public void readArr() { // 明确文件 File file = new File("D:/net.txt"); // 构建流的对象 InputStream inputStream = null; try { inputStream = new FileInputStream(file); // 声名缓冲数组 int i; byte[] bytes = new byte[5]; while ((i = inputStream.read(bytes)) != -1) { for (int j = 0; j < i; j++) { System.out.print((char)bytes[j]); } } } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } finally { try { if (inputStream != null) { inputStream.close(); } } catch (IOException e) { e.printStackTrace(); } } }
在使用InputStream读取文件时,发现在使用while循环读取文件时,它会自动的按顺序读取文件的内容,这是为什么呢?首先我们看看官方的API文档解释:
/** * Reads the next byte of data from the input stream. The value byte is * returned as an <code>int</code> in the range <code>0</code> to * <code>255</code>. If no byte is available because the end of the stream * has been reached, the value <code>-1</code> is returned. This method * blocks until input data is available, the end of the stream is detected, * or an exception is thrown. * * <p> A subclass must provide an implementation of this method. * * @return the next byte of data, or <code>-1</code> if the end of the * stream is reached. * @exception IOException if an I/O error occurs. */ public abstract int read() throws IOException
大概意思就是,每次调用InputStream.read()方法,就从输入流中读取一个字节的数据,并返回这个字节。如果读取内容到达文件末尾,那么就返回-1。
文件流FileInputStream的读取是单向的,也就是说读取顺序是按照文件中的数据存储书序来的。另外,通过.read()方法读出来的数据是个临时变量,java会自动在堆中为其分配一个内存空间,但是当.read()方法执行结束,垃圾回收器会立刻将其删除,因此在程序中.read(byte[] bytes)方法中的bytes参数才是实际上是用来存储读取出来数据的参数。如果文件保存了10个字节的数据,而bytes长度为8,那么inputStream会按照每8个字节读一次文件,在此例中会读取两次,并且最终输出结果会有问题。这是因为第二次读取出来的两个字节会按照读取顺序依次填充在bytes数组的前两位,而后面6位元素并不会改变。
public void readStr() { // 写文件 OutputStream outputStream = null; // 读文件 InputStream inputStream = null; try { outputStream = new FileOutputStream(file); inputStream = new FileInputStream(file); createFile(); String str = "helloWorld"; outputStream.write(str.getBytes()); outputStream.flush(); byte[] bytes = new byte[8]; // read()按内容存储顺序进行读取,从第一个字节到最后,读取出来的内容保存在bytes数组中,如果数组的长度不够,则接下来读取出来的内容会被依次覆盖 while (inputStream.read(bytes) != -1) { System.out.println("我在循环!"); for (byte b:bytes) { System.out.print((char)b); } System.out.println(); } } catch (IOException e) { e.printStackTrace(); } finally { try { outputStream.close(); inputStream.close(); } catch (IOException e) { e.printStackTrace(); } } }
输出结果:我在循环!
helloWor
我在循环!
ldlloWor