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