1. 程式人生 > >Java使用URL類下載的圖片不完整

Java使用URL類下載的圖片不完整

aid 下載圖片 pri 相同 pre open set [] 接收數據

問題

  今天在使用URL類來下載網站中的圖片的時候,出現了一個問題:下載的圖片不完整,並且每次下載的圖片大小也不是都相同,反正就是不完整。

  問題代碼如下:

package cn.ganlixin.test;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URL;
import java.net.URLConnection;

public class Test {
	
	public static void main(String[] args) throws IOException  {
		URL url = new URL("http://www.baidu.com/favicon.ico");
		URLConnection conn = url.openConnection();

		// 設置user-agent,預防403
		conn.setRequestProperty("user-agent", "Chrome/73.0.3683.86");

		InputStream _is = conn.getInputStream();
		
		byte[] data = new byte[1024*1024];  // 1M
		
		// 一次性下載
		int length = _is.read(data);
		
		OutputStream _os = new FileOutputStream(new File("favicon.ico"));
		_os.write(data, 0, length);
		_os.flush();
		
		System.out.println("下載 " + url + " 共" + length + "字節內容");
	}

}

  運行多次,輸出如下:

下載 http://www.baidu.com/favicon.ico 共5440字節內容
下載 http://www.baidu.com/favicon.ico 共16495字節內容
下載 http://www.baidu.com/favicon.ico 共13455字節內容

  上面要下載圖片的完整大小應該是16.6KB,但是上面測試多次都沒有下載完整。

  剛開始還以為是接收數據的byte數組長度不夠,但是當我設置為1M的時候,依舊下載不完整,這就有點不解了。

  網上查了一些資料說是輸出的時候沒有flush,但是計算的下載的數據長度呀,這和輸出是否進行了flush是沒有關系的。。

  

解決方式

  後來我該用了多次read,而不是向上面的代碼中一次read,計算總和,這個時候就沒有出現數據不完整的情況了。

package cn.ganlixin.test;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URL;
import java.net.URLConnection;

public class Test {
	public static void main(String[] args) throws IOException  {
		URL url  = new URL("http://www.baidu.com/favicon.ico");
		URLConnection conn = url.openConnection();

		conn.setRequestProperty("user-agent", "Chrome/73.0.3683.86");

		InputStream _is = conn.getInputStream();
		byte[] data = new byte[1024*100];  // 100KB
		
		int tot = 0;
		int length = 0;
		
		OutputStream _os = new FileOutputStream(new File("demo.png"));
		
		// 采用多次read的方式
		while ((length = _is.read(data)) != -1) {
			tot += length;
			_os.write(data, 0, length);
		}		
		_os.flush();
		
		System.out.println("下載 " + url + " 共" + tot + "字節內容");
	}
}

  運行多次,結果如下:

下載 http://www.baidu.com/favicon.ico 共16958字節內容
下載 http://www.baidu.com/favicon.ico 共16958字節內容
下載 http://www.baidu.com/favicon.ico 共16958字節內容

  數據完整了,但是我還是沒有明白上面的那個問題出在哪裏。

Java使用URL類下載的圖片不完整