如何從下載文件數(shù)據(jù)丟失來分析BufferedOutputStream源碼

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

創(chuàng)新互聯(lián)服務(wù)項(xiàng)目包括康樂網(wǎng)站建設(shè)、康樂網(wǎng)站制作、康樂網(wǎng)頁制作以及康樂網(wǎng)絡(luò)營銷策劃等。多年來,我們專注于互聯(lián)網(wǎng)行業(yè),利用自身積累的技術(shù)優(yōu)勢、行業(yè)經(jīng)驗(yàn)、深度合作伙伴關(guān)系等,向廣大中小型企業(yè)、政府機(jī)構(gòu)等提供互聯(lián)網(wǎng)行業(yè)的解決方案,康樂網(wǎng)站推廣取得了明顯的社會效益與經(jīng)濟(jì)效益。目前,我們服務(wù)的客戶以成都為中心已經(jīng)輻射到康樂省份的部分城市,未來相信會繼續(xù)擴(kuò)大服務(wù)區(qū)域并繼續(xù)獲得客戶的支持與信任!

今天突然遇到一個問題,通過下載文件的接口下載的文件比實(shí)際文件小了2kb,而且文件中的內(nèi)容比實(shí)際內(nèi)容少了很多,帶著這個問題,我跟蹤代碼執(zhí)行流程,我們來看一下核心代碼:
        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);
        }

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

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

該語句是循環(huán)讀取所有讀緩沖區(qū)的內(nèi)容,因此,該語句出現(xiàn)問題的幾率不是很大,很大可能是因?yàn)閷懢彌_區(qū)的問題,下面我通過分析BufferedOutputStream的源碼來看看能不能找出問題的原因:

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

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

從上面的源碼中可以發(fā)現(xiàn):觸發(fā)緩沖區(qū)刷新的時機(jī)是當(dāng)寫入數(shù)據(jù)大小大于緩沖區(qū)的可用大小。

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

關(guān)于如何從下載文件數(shù)據(jù)丟失來分析BufferedOutputStream源碼問題的解答就分享到這里了,希望以上內(nèi)容可以對大家有一定的幫助,如果你還有很多疑惑沒有解開,可以關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道了解更多相關(guān)知識。

網(wǎng)站標(biāo)題:如何從下載文件數(shù)據(jù)丟失來分析BufferedOutputStream源碼
文章起源:http://www.muchs.cn/article26/ghjpcg.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供搜索引擎優(yōu)化、定制開發(fā)ChatGPT、建站公司網(wǎng)站設(shè)計(jì)公司、商城網(wǎng)站

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)

成都定制網(wǎng)站網(wǎng)頁設(shè)計(jì)