|
最近自學韓順平的java視頻,講到io流的時候碰到了這樣一段無法理解的代碼,在CSDN上找了好多貼子來看,最終搞懂了!
- public class demo {
- public static void main(String[] args) {
- //先把图片读入到内存--然后写到 文件
- FileInputStream fis=null;
- File q=new File("e:/123.txt");
- //因为File没有读写的能力,所以需要使用InputStream;
- try {
- fis=new FileInputStream(q);
- //定义一个字节数组,相当于缓存
- byte[] bytes=new byte[1024];
- int n=0;//得到实际读取到的字节数 读到最后返回-1
- //循环读取
- while((n=fis.read(bytes))!=-1)//把fis里的东西读到bytes数组里去
- {
- //把字节转成String 从0到N变成String
- String w=new String(bytes,0,n);
- System.out.println(w);
- }
- } catch (Exception e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- finally{
- //一定要关闭文件流。并且关闭文件流必须放在finally里面
- try {
- fis.close();
- } catch (IOException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- }
- }
- }
複製代碼
最疑惑這一小段:
- byte[] bytes=new byte[1024];
- int n=0;//得到实际读取到的字节数 读到最后返回-1
- //循环读取
- while((n=fis.read(bytes))!=-1)//把fis里的东西读到bytes数组里去
- {
- //把字节转成String 从0到N变成String
- String w=new String(bytes,0,n);
- System.out.println(w);
- }
複製代碼
我的最初想法:
1,fis每讀一個字節,都要給n賦值,不到文檔末尾n不會是-1,所以每次都要輸出一個越來越長的String,直到該文件內容全部輸出。
2,如果文件字節數大於1024,那麼n=1024時bytes就被填滿了,所以有可能只能輸出文件的前1024個字節。
測試結果說明上面兩個想法都是錯誤的,控制台輸出的是整個文件的內容,並不是“越來越長”的部分內容。在文件字節大於1024時,依然能正常輸出。
合理的解釋:
引用API文檔:“public int read(byte[] b) throws IOException:從此輸入流中將最多b.length個字節的數據讀入一個byte數組中。在某些輸入可用之前,此方法將阻塞。 ”
注意“ 阻塞 ”二字,fis執行read時,不會每讀一個字節就對n賦值,所以while循環就被一直堵在判斷語句中,直到bytes被賦滿出現異常,讀取的阻塞釋放,n終於被賦了一個值1024,接下來就執行循環體的打印。
bytes第一次塞滿時,文件被讀到的地方會有一個記錄,所以當循環體執行完後,fis從上次循環結束的記錄向下讀文件,又把while循環阻塞在判斷語句,直到讀完最後一個字節,讀取阻塞再次被釋放,這次n被賦值,該值為這次fis讀到的字節數。然後,執行循環體打印。
然後,fis再次嘗試讀取文件,這時候已經沒有字節可讀,故返回-1賦給n,循環體不再執行,循環結束。
文章出處:https://blog.csdn.net/zzuwlan_high/article/details/78553193
|
|