溫馨提示×

溫馨提示×

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

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

基于bufferedreader的read()與readline()讀取出錯怎么解決

發(fā)布時間:2021-12-09 15:09:31 來源:億速云 閱讀:167 作者:iii 欄目:開發(fā)技術

本篇內容主要講解“基于bufferedreader的read()與readline()讀取出錯怎么解決”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實用性強。下面就讓小編來帶大家學習“基于bufferedreader的read()與readline()讀取出錯怎么解決”吧!

bufferedreader的read()與readline()讀取出錯

以前學習java的時候也沒有太在意,直到最近做項目時使用了才發(fā)現這個問題,總是第一個字符輸不出來

bufferedreader這個類借用別人的話來說,就是一個包裝類

它可以包裝字符流,將字符流放入緩存里,先把字符讀到緩存里,到緩存滿了或者你flush的時候,再讀入內存,就是為了提高讀的效率而設計的。

讀取一個txt文件,方法很多種而我使用的是字符流來讀取

int c; 
FileReader file = new FileReader("D:\\emDemo.java");
   BufferedReader br = new BufferedReader(file);
   while((c=br.read())!=-1){undefined
    System.out.println(br.readLine());
   }

發(fā)現每行的第一個字符都沒有顯示出來,后來發(fā)現 c=br.read())!=-1 每次都會先讀取一個字節(jié)出來,所以后面的br.readLine());

讀取的就是每行少一個字節(jié)

所以,應該使用

String input = null;
   while ((input=br.readLine())!=null){undefined
    System.out.println(input);
   }

這樣就能解決了~

bufferedReader中的readLine()源碼解析

String readLine(boolean ignoreLF) throws IOException {
		//行(hang)數據的緩沖s
		StringBuffer s = null;
		int startChar;
 
	        synchronized (lock) {
	       /*確保被bufferedReader包裝的輸入流沒有關閉*/
	            ensureOpen();
	            
	          /* 如果 讀到'\r',skipLF置為true,
	           * 這是skip()方法里面的部分代碼,它展示了通過skipLF來忽略'\n'
	           * if (skipLF) {
		        skipLF = false;
		        if (cb[nextChar] == '\n') {
			   	 	nextChar++;
		          }
		       }
	           *ignoreLF一直就是false
	           **/
		    boolean omitLF = ignoreLF || skipLF;
 
		 /* bufferLoop主要是不斷地遍歷底層的數組cb,并取兩個換行符之間的數據付給行緩沖s。當底層數組遍歷完要用fill()把數據從流中填充到cb,直到流的末尾
		  *charloop,主要是遍歷緩沖數組cb,以確定'\n','\r'的位置
		    nextChar:下次讀取緩沖字符數組cb的位置,
		  	nChars:緩沖字符數組cb的length
		  	
		  */	
		    bufferLoop:
		    for (;;) {
		    	
		    	//1、如果緩沖數組的數據不足,或者已經讀到了數組的末尾時:
		    	//1.1如果下次讀取的位置已經到了or超過數組的長度,從流中讀數據到緩沖數組cb中
			if (nextChar >= nChars)
			    fill();
			/*1.2如果從流中讀數據到數組cb之后, nextChar,nChars的大小關系沒有改變.
			說明到了文件的末尾,END OF FILE.返回s
			*/
			if (nextChar >= nChars) { /* EOF */
			    if (s != null && s.length() > 0)
				return s.toString();
			    else
				return null;
			}
			
			
			//2 緩沖數組中有足夠的數據時:
			/*從本個換行符所在的索引位置開始,遍歷char [] cb ,直到找到\n \r,把兩個換行符之間的字符序列填充進s
			 *eol:END OF LINE
			 *類屬性char [] cb ,也就是bufferReader類的緩沖數組。length由構造器指定,若不指定默認為8 * 1024 = 8192,與內存頁大小密切相關
			 * */
			boolean eol = false;
			char c = 0;
			int i;
 
			if (omitLF && (cb[nextChar] == '\n')) 
	                    nextChar++;
			skipLF = false;
			omitLF = false;
 
		    charLoop:
			for (i = nextChar; i < nChars; i++) {
			    c = cb[i];
			    if ((c == '\n') || (c == '\r')) {
				eol = true;
				break charLoop;
			    }
			}
			
			/*2.1找到換行符后,從上個換行符到本換行符之間的序列,填充給s*/
			startChar = nextChar;
			nextChar = i;
			if (eol) {
			    String str;
			    /*2.1.1如果是第一次遍歷到換行符,*/
			    if (s == null)
			    {
				str = new String(cb, startChar, i - startChar);
			    } 
			    /*2.1.2至少遍歷到一次換行符時*/
			    else
			    {
				s.append(cb, startChar, i - startChar);
				str = s.toString();
			    }
			  //更新下次讀取的位置
			    nextChar++;
			    if (c == '\r') {
				skipLF = true;
			    }
			    return str;
			}
			//2.2如果沒有換行符
			if (s == null) 
				//類屬性int defaultExpectedLineLength = 80
			    s = new StringBuffer(defaultExpectedLineLength);
			//填充s,從上個換行符到最后
			s.append(cb, startChar, i - startChar);
		    }
	        }
	    }

到此,相信大家對“基于bufferedreader的read()與readline()讀取出錯怎么解決”有了更深的了解,不妨來實際操作一番吧!這里是億速云網站,更多相關內容可以進入相關頻道進行查詢,關注我們,繼續(xù)學習!

向AI問一下細節(jié)

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

AI