91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

如何從下載文件數據丟失來分析BufferedOutputStream源碼

發布時間:2021-09-10 13:51:18 來源:億速云 閱讀:169 作者:柒染 欄目:大數據

如何從下載文件數據丟失來分析BufferedOutputStream源碼,針對這個問題,這篇文章詳細介紹了相對應的分析和解答,希望可以幫助更多想解決這個問題的小伙伴找到更簡單易行的方法。

今天突然遇到一個問題,通過下載文件的接口下載的文件比實際文件小了2kb,而且文件中的內容比實際內容少了很多,帶著這個問題,我跟蹤代碼執行流程,我們來看一下核心代碼:
        bis = new BufferedInputStream(new FileInputStream(targetFilePath));
        bos = new BufferedOutputStream(response.getOutputStream());
        byte[] buff = new byte[2048];
        int bytesRead;
        while (-1 != (bytesRead = bis.read(buff, 0, buff.length))) {
            bos.write(buff, 0, bytesRead);
        }

核心代碼非常簡單,就是根據目標文件,通過FileInputStream流來讀取目標文件流,寫入到response的輸出流中。中間通過BufferedInputStream和BufferedOutputStream緩沖流來提高性能。 根據上述代碼,我大膽猜測可能出現問題的原因是BufferedInputStream或者BufferedOutputStream。進一步分析:

		 while (-1 != (bytesRead = bis.read(buff, 0, buff.length))) 		

該語句是循環讀取所有讀緩沖區的內容,因此,該語句出現問題的幾率不是很大,很大可能是因為寫緩沖區的問題,下面我通過分析BufferedOutputStream的源碼來看看能不能找出問題的原因:

	BufferedOutputStream位于 java.io包下
	
	/**
	* 繼承自FilterOutputStream(FilterOutputStream有一個			OutputStream的屬性,就是目標輸出out對象流)
	*/
	public class BufferedOutputStream extends FilterOutputStream {
	    /**
		 * 用來存儲數據的緩沖區(默認8912個字節)
		 */
		protected byte buf[];

		/**
		 * 當前已存儲數據的字節數(個人理解為指向已存儲數據末尾的一個指針)
		 */
		protected int count;
		
		/**
		* 構造方法1: 用設置目標輸出流對象,同時默認buff緩沖區大小8912個字節
		*/
		 public BufferedOutputStream(OutputStream out) {
			this(out, 8192);
		}
		
		/**
		* 構造方法2:設置輸出流對象,自定義緩沖區的大小,
		*/
		 public BufferedOutputStream(OutputStream out, int size) {
			super(out);
			if (size <= 0) {
				throw new IllegalArgumentException("Buffer size <= 0");
				}
			buf = new byte[size];
		}
		
		
			/**
			* 刷新緩沖區(將緩沖區內容寫入到目標流對象中,同同時將count置為0)
			**/
		   private void flushBuffer() throws IOException {
   			 if (count > 0) {
        			out.write(buf, 0, count);
        			count = 0;
    			}
		}
		
		/**
		* 向緩沖區寫一個字節數據
		**/
		public synchronized void write(int b) throws IOException {
			//先判斷緩沖區是否已滿,如果已滿,清空緩沖區
			if (count >= buf.length) {
       			 	flushBuffer();
    			}
    			buf[count++] = (byte)b;
		}
		
		
		/**
		* 向緩沖區寫入指定長度的數據
		**/
		    public synchronized void write(byte b[], int off, int len) throws IOException {
			//判斷寫入數據的長度是否超過緩沖區大小,如果超過,直接寫入目標對象out流中,清空緩沖區
			if (len >= buf.length) {
				flushBuffer();
				out.write(b, off, len);
				return;
			}
			//如果長度大于緩沖區剩余空間,將緩沖區清空,寫入數據
			if (len > buf.length - count) {
				flushBuffer();
			}
			System.arraycopy(b, off, buf, count, len);
			count += len;
		}
		
		/**
		*刷新緩沖區
		**/
		public synchronized void flush() throws IOException {
			flushBuffer();
			out.flush();
		}
	}

從上面的源碼中可以發現:觸發緩沖區刷新的時機是當寫入數據大小大于緩沖區的可用大小。

為了解決該問題,將核心操作放到try-catche-finally中,在finally中手動關閉BufferedInputStream和BufferedOutputStream流(BufferedOutputStream并沒有close方法,調用父類FilterOutputStream的close方法),在關閉前會強制刷新緩沖區的數據到out寫對象流中。該問題得到解決。

關于如何從下載文件數據丟失來分析BufferedOutputStream源碼問題的解答就分享到這里了,希望以上內容可以對大家有一定的幫助,如果你還有很多疑惑沒有解開,可以關注億速云行業資訊頻道了解更多相關知識。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

久治县| 措美县| 南京市| 余庆县| 武定县| 阳信县| 平阴县| 乌鲁木齐县| 松潘县| 富裕县| 潼关县| 双辽市| 佛冈县| 微博| 宜兴市| 通山县| 台东市| 鸡东县| 德州市| 尉氏县| 阳西县| 什邡市| 古蔺县| 威海市| 乐陵市| 交城县| 藁城市| 彩票| 镇远县| 钟祥市| 松溪县| 深州市| 且末县| 通海县| 公主岭市| 佛山市| 连云港市| 新昌县| 那坡县| 五常市| 唐河县|