当我执行以下课程
时import java.io.*;
import java.nio.*;
import java.nio.file.*;
import java.nio.channels.*;
public class FileChannelTest {
public static void main(final String... args) throws IOException {
final File file = File.createTempFile("temp", null);
file.deleteOnExit();
// write some
try(OutputStream output = new FileOutputStream(file)) {
output.write(new byte[128]);
output.flush();
}
System.out.println("length: " + file.length());
// read to end
try(FileChannel channel
= FileChannel.open(file.toPath(), StandardOpenOption.READ)) {
final ByteBuffer buffer = ByteBuffer.allocate(128);
for(int read; (read = channel.read(buffer)) != -1; ) {
System.out.println("read: " + read);
}
}
}
}
阅读循环永远不会结束。
$ java -version
java version "1.8.0_65"
Java(TM) SE Runtime Environment (build 1.8.0_65-b17)
Java HotSpot(TM) 64-Bit Server VM (build 25.65-b01, mixed mode)
$ java FileChannelTest.java
$ java FileChannelTest
length: 128
read: 128
read: 0
read: 0
read: 0
...
...
...
FileChannel.read(ByteBuffer)说,
从该通道读取一个字节序列到给定的缓冲区。 从该通道的当前文件位置开始读取字节,然后使用实际读取的字节数更新文件位置。 否则此方法的行为与
ReadableByteChannel
界面中指定的完全相同。
其他是什么意思?
答案 0 :(得分:3)
当您读入ByteBuffer时,它只能读取缓冲区中可用的字节数,即byteBuffer.remaining()
这意味着一旦缓冲区已满,当您执行读取操作时,它将返回0
。
如果您已经消耗了所有读取的数据,我建议您使用clear()
;如果您只消耗了部分数据,我建议使用compact()
。
for(int read; (read = channel.read(buffer)) != -1; ) {
System.out.println("read: " + read);
buffer.clear(); // so we can read more data
}
答案 1 :(得分:0)
以上@Peter Lawrey的回答为你的无限循环提供了解决方案。除此之外,根据我的理解,在FileChannel
课程的文档中回答您关于否则的含义的问题:
来自Java docs:
从该通道读取一个字节序列到给定的缓冲区。 从该通道的当前文件位置开始读取字节,并且 然后用实际的字节数更新文件位置 读取。
此方法的行为与阻塞和非阻塞I / O模式下的ReadableByteChannel.read
方法以及线程安全要求完全相同。它执行的唯一的附加操作(读取OOP术语中的专门化)是FileChannel.read
实现也将使用从通道实际读取的字节数增加文件位置。
希望这有帮助