Java SeekableByteChannel.read()始终返回0,InputStream正常
我们有一个需要生成CRC的数据文件。作为占位符,我使用CRC32,而其他人则知道他们实际需要什么样的CRC多项式。这段代码似乎应该起作用: 破碎的: System.err和loops的内容只是为了调试;实际上,我们并不在乎需要多少次。输出为: 字节通道是C:\working\tmp\ls2kst83543216xuxxy8136.tmp中的sun.nio.ch.FileChannelImpl,大小为7196,isopen=true 通过循环0次后完成 没有办法在调试器中运行真正的代码来逐步完成它,但是从查看源代码到sun.nio.ch.FileChannelImpl.read,如果在准备内部数据结构时文件神奇地关闭,则返回0;下面的代码是从Java 7参考实现中复制的,我添加了注释:Java SeekableByteChannel.read()始终返回0,InputStream正常,java,nio,Java,Nio,我们有一个需要生成CRC的数据文件。作为占位符,我使用CRC32,而其他人则知道他们实际需要什么样的CRC多项式。这段代码似乎应该起作用: 破碎的: System.err和loops的内容只是为了调试;实际上,我们并不在乎需要多少次。输出为: 字节通道是C:\working\tmp\ls2kst83543216xuxxy8136.tmp中的sun.nio.ch.FileChannelImpl,大小为7196,isopen=true 通过循环0次后完成 没有办法在调试器中运行真正的代码来逐步完成它
// sun.nio.ch.FileChannelImpl.java
public int read(ByteBuffer dst) throws IOException {
ensureOpen(); // this throws if file is closed...
if (!readable)
throw new NonReadableChannelException();
synchronized (positionLock) {
int n = 0;
int ti = -1;
Object traceContext = IoTrace.fileReadBegin(path);
try {
begin();
ti = threads.add();
if (!isOpen())
return 0; // ...argh
do {
n = IOUtil.read(fd, dst, -1, nd);
} while (......)
.......
但是调试代码测试了isOpen并得到了实现。所以我不知道出了什么问题
由于当前的测试数据文件很小,我将其放在适当的位置,只是为了让某些东西工作:
目前的工作:
我不想为了真正的代码而将整个文件拖到内存中,因为其中一些文件可能很大。我注意到readAllBytes在其引用实现中使用了InputStream,它在读取SeekableByteChannel未能读取的相同文件时没有问题。所以我可能会重写代码,只使用输入流而不是字节通道。我仍然想找出哪里出了问题,以防将来出现需要使用字节通道的情况。SeekableByteChannel缺少什么?检查“合理的缓冲区大小”是否为零。它当前已硬编码为32K。我不相信他们有任何计划在运行时调整缓冲区大小;它只是其中一个获取名称而不是文本整数的常量。您确定调用read时它不是零吗?它可以返回零的唯一方法是提供一个长度为零的缓冲区或一个已满的缓冲区,或者在非阻塞模式下返回零,这在本例中不适用。final int reasonal_buffer_size=32*1024;似乎不是零。:-但我明白你的意思;当我回到实验室时,我会尽量减少到一个非常小的缓冲区,看看会发生什么。当allocate返回时,缓冲区应该是空的,我记得添加一个抢占式调用来清除任何东西都没有效果。正如本德所说,蚂蚁代码生成者密谋咬我们闪亮的金属屁股。在源文件中输入的内容不一定与在类文件中输出的内容相似。。。
// sun.nio.ch.FileChannelImpl.java
public int read(ByteBuffer dst) throws IOException {
ensureOpen(); // this throws if file is closed...
if (!readable)
throw new NonReadableChannelException();
synchronized (positionLock) {
int n = 0;
int ti = -1;
Object traceContext = IoTrace.fileReadBegin(path);
try {
begin();
ti = threads.add();
if (!isOpen())
return 0; // ...argh
do {
n = IOUtil.read(fd, dst, -1, nd);
} while (......)
.......
try {
byte[] scratch = Files.readAllBytes(in);
java.util.zip.CRC32 placeholder = new java.util.zip.CRC32();
placeholder.update(scratch);
// do stuff with placeholder.getValue()
}