不灭的火

革命尚未成功,同志仍须努力下载JDK17

作者:AlbertWen  添加时间:2022-08-24 18:27:25  修改时间:2025-05-22 17:33:06  分类:08.Java基础  编辑

最近自学韩顺平的java视频,讲到io流的时候碰到了这样一段无法理解的代码,在CSDN上找了好多贴子来看,最终搞懂了!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
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();
            }
        }
    }
}

最疑惑这一小段:

1
2
3
4
5
6
7
8
9
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个字节。

合理的解释:

引用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