1. 程式人生 > >利用管道化連線下載網頁 Java

利用管道化連線下載網頁 Java

HTTP連線的建立需要時間。如果我們要從一臺伺服器上獲取4個檔案,獲取每個檔案都要重新建立連線來獲取資料,這勢必會降低檔案下載效率,因為有一部分時間花費在建立連線上了,而不是真正在傳輸有用資料,如圖a所示:
這裡寫圖片描述

如果我們能建立一個連線,傳輸完所有四個檔案,再關閉連線,必然會增加檔案下載效率,因為節省了多次建立連線的開銷,持久連線就是這樣的連線,它的工作方式如圖b所示:
這裡寫圖片描述
簡單的持久連線有個問題,就是每次都要等到我們獲得了上一次請求的響應之後,才能發起下一次連線,這導致請求的時候,輸入流是完全閒置的,獲取響應的時候,輸出流是完全閒置的。如果我們能一邊傳送請求,一邊接收響應,這必然能更加充分的利用這個連線,可以被這樣使用的持久連線叫做管道化連線,它的工作方式如圖c所示:
這裡寫圖片描述

下面給出的Java程式碼是通過一個管道化連線從伺服器上獲取多個檔案的示例:

package socket;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.Socket;
import java.net.UnknownHostException;
import java.nio.file.Files;
import
java.nio.file.Path; import java.nio.file.Paths; import java.nio.file.StandardOpenOption; public class ReuseSocket { public static void main(String[] args) throws UnknownHostException, IOException { String host = "www.cnblogs.com"; int port = 80; String path = "/chenying99/p/3735282.html"
; String path2 = "/everSeeker/p/5462853.html"; String result = getByPipePipelinedConnection(host, port, path, path2); writeFile(result, "d:/test/pipelined.html", "utf-8"); } /** * 通過一個管道化連接獲取host指定的主機上paths指定的所有檔案 * @param host 主機名 * @param port 埠 * @param paths host指定的主機上的檔案路徑集合 * @return 伺服器返回的結果 * @throws UnknownHostException * @throws IOException */ public static String getByPipePipelinedConnection(String host, int port, String...paths) throws UnknownHostException, IOException { StringBuilder lines = new StringBuilder(); try(Socket socket = new Socket(host, port); // 輸出流 PrintWriter printWriter = new PrintWriter((new OutputStreamWriter( socket.getOutputStream(), "utf-8"))); // 輸入流 BufferedReader bufferedReader = new BufferedReader(new InputStreamReader( socket.getInputStream(), "utf-8")); ) { for (String path : paths) { String requestHead = generateRequestHead(host, path); printWriter.println(requestHead); printWriter.flush(); } String line = null; while ((line = bufferedReader.readLine()) != null) { lines.append(line); lines.append(System.lineSeparator()); } } return lines.toString(); } /** * * @param host 主機名 * @param path 主機上某個檔案的路徑 * @return 獲得host指定主機上的path指定的檔案的請求頭 */ private static String generateRequestHead(String host, String path) { StringBuffer requestHeader = new StringBuffer(); requestHeader .append("GET " + path + " HTTP/1.1\n") .append("Accept: text/html, application/xhtml+xml, */*\n") .append("Accept-Language:zh-CN,zh;q=0.8\n") .append("User-Agent: Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.2; WOW64; Trident/6.0)\n") .append("HOST:" + host + "\n") .append("\n"); return requestHeader.toString(); } /** * 把字串寫進檔案,檔案已經存在會覆蓋原檔案 * @param content 字串 * @param pathName 檔案路徑名 * @param charsetName 字符集 */ private static void writeFile(String content, String pathName, String charsetName) { Path path = Paths.get(pathName); try { Files.write(path, content.getBytes(charsetName), StandardOpenOption.CREATE); } catch (IOException e) { e.printStackTrace(); } } }

想更細緻的瞭解管道化連線,可以閱讀《HTTP權威指南》4.6節,本文的圖也來自這本書。

相關推薦

利用管道連線下載網頁 Java

HTTP連線的建立需要時間。如果我們要從一臺伺服器上獲取4個檔案,獲取每個檔案都要重新建立連線來獲取資料,這勢必會降低檔案下載效率,因為有一部分時間花費在建立連線上了,而不是真正在傳輸有用資料,如圖a所示: 如果我們能建立一個連線,傳輸完所有四個檔案,再關

Java如何讀取和下載網頁

port 一個 oid except 網頁 如何使用 mon exceptio -i 在Java編程中,如何讀取和下載網頁? 以下示例顯示如何使用net.URL類的URL()構造函數來讀取和下載網頁。 package com.yiibai; import java.io.

Java 利用圖形介面做出驗證IP地址的程式

package com.gogogo import java.awt.EventQueue; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import javax.swing.JButton

【MongoDb學習之路】Java利用MongoClient類連線MongoDB資料庫

專案需要 mongo-java-driver-3.0.2 .jar  【重點看加粗字型,方法體中註釋的都是系統連線引數】 package cn.com.mongodb; import com.mongodb.DB; import com.mongodb.DBColl

JAVA中新增openlayer3的js包製作地圖,使用geoserver釋出地圖,將釋出的地圖連線網頁

1 首先下載OpenLayers 3所需資料 OpenLayers 3的官網是http://openlayers.org/,若記不住,請儲存到收藏夾。在官網首頁上,即可看到相關的介紹,文件,API,以及Examples連結,這些資料都跟隨最新的版本實時更新。 向工程中新增 新

實現Java讀取網頁內容並下載網頁中出現的圖片

import java.io.BufferedInputStream; import java.io.BufferedReader; import java.io.File; import java.io.FileNotFoundException; impor

java利用正則,過濾網頁標籤.......

在開發中有時候會遇到在一大串字串中替換或者去除某個特定的字串,一下例子是過濾html頁面字串的例項,說明正則在其中的作用: package com.project.admin.common.util; import java.util.ArrayList; import

使用Java下載網頁下載連結的內容

專案需要大量的excel檔案作為資料來源,然後寫了一個java小程式用來直接下載網頁下載連結的內容。這樣使用Java程式設計可以進行指定任務的下載 匯入相應的包 import java.io.Fil

Java PhantomJs下載網頁

1 下載PhantomJS 國外的網站下載比較慢,推薦使用淘寶映象下載,地址: 2  下載PhantomJSDriver 這裡使用maven來直接依賴:             <dependency>                 <groupI

利用scrapy爬取文件後並基於管道的持久化存儲

val set field wid 參數 err spi http res 我們在pycharm上爬取 首先我們可以在本文件打開命令框或在Terminal下創建 scrapy startproject xiaohuaPro ------------創建文件 s

如何用 LaunchBar 一鍵下載網頁上的所有文件?

nbsp spl class https 好的 idt 標簽 set 每天 本文標簽: Mac效率工具 Mac小工具 MacOS LaunchBar 一鍵下載網頁文件 有時候我們會遇到這種問題,一個頁面上掛了好多文檔需要下載: 依次點開再按 ? S 或是逐個右擊再選擇下載

對象逆序列報錯:java.lang.ClassNotFoundException

http 上網 security ref targe lin 存在 lan dcl 簡單的想從保存的對象中又一次解析出對象。用了逆序列化,但是報錯: java.lang.ClassNotFoundException: xxxxxxxxxxxx at java.net.U

2.3 利用FTP服務器下載和上傳文件

true () cal 信息 color imp exists binary logs 二.利用FTP服務器的下載文件 from ftplib import FTP from os.path import exists def getfile(file,site,dir

2.4 利用FTP服務器下載和上傳目錄

logs conn lean 連接 int edi dir ack ftp服務器 利用FTP服務器下載目錄 import os,sys from ftplib import FTP from mimetypes import guess_type nonpassive

Linux 利用管道父子進程間傳遞數據

csdn ans 函數 fault 判斷 ini popu ges def [原文] fork()函數:用於創建子進程,子進程完全復制父進程的資源,相當於父進程的拷貝。具體理解,運用父進程的同一套代碼,通過判斷進程ID來執行不同進程的不同任務。返回值正常為子進程ID,出錯返

python多線程下載網頁圖片並保存至特定目錄

loading eat start file ext thread end tex _for #!python3 #multidownloadXkcd.py - Download XKCD comics using multiple threads. import r

python 批量下載網頁裏的圖片

www file header range .html filename 表達 則表達式 進行 python 3.* import requestsimport sys,re#設置提取圖片url 的正則表達式imgre = re.compile(r"<img

Python3網絡爬蟲(一):利用urllib進行簡單的網頁抓取

robot 資源 urlopen 解碼 支付寶 編碼方式 只需要 服務器 net 一、預備知識 1.Python3.x基礎知識學習: 可以在通過如下方式進行學習: (1)廖雪峰Python3教程(文檔): URL:http://www.liaoxue

下載網頁音頻

老年人 大鼓書 評書 戲曲 下載 老年人戲曲,評書,大鼓書下載本人長期給我媳婦的爺爺下載各種戲曲評書,他老人家要求比較高,一直苦於下不到,知道發現這個方法,之後下載如行雲流水暢通無阻。本例子使用Google瀏覽器。首先我們要找到一個能在線播放的音頻網站,然後打開它播放音頻,這時候按F12,

利用管道實現進程間通信

Linux 進程 管道 通信 管道通信 匿名管道 創建匿名管道 int pipe(int pipefd[2]);pipefd[0] : 表示讀管道pipefd[1] : 表示寫管道返回 0表示成功,非零表示創建失敗。 代碼事例: //匿名管道