[英]SeekableByteChannel.read() always returns 0, InputStream is fine
We have a data file for which we need to generate a CRC. 我们有一个需要为其生成CRC的数据文件。 (As a placeholder, I'm using CRC32 while the others figure out what CRC polynomial they actually want.) This code seems like it ought to work: (作为一个占位符,我使用的是CRC32,其他人则弄清楚了他们实际想要的是CRC多项式。)这段代码似乎应该起作用:
broken: 破碎:
Path in = ......;
try (SeekableByteChannel reading =
Files.newByteChannel (in, StandardOpenOption.READ))
{
System.err.println("byte channel is a " + reading.getClass().getName() +
" from " + in + " of size " + reading.size() + " and isopen=" + reading.isOpen());
java.util.zip.CRC32 placeholder = new java.util.zip.CRC32();
ByteBuffer buffer = ByteBuffer.allocate (reasonable_buffer_size);
int bytesread = 0;
int loops = 0;
while ((bytesread = reading.read(buffer)) > 0) {
byte[] raw = buffer.array();
System.err.println("Claims to have read " + bytesread + " bytes, have buffer of size " + raw.length + ", updating CRC");
placeholder.update(raw);
loops++;
buffer.clear();
}
// do stuff with placeholder.getValue()
}
catch (all the things that go wrong with opening files) {
and handle them;
}
The System.err
and loops
stuff is just for debugging; System.err
和loops
内容仅用于调试; we don't actually care how many times it takes. 我们实际上并不关心需要花费多少时间。 The output is: 输出为:
byte channel is a sun.nio.ch.FileChannelImpl from C:\\working\\tmp\\ls2kst83543216xuxxy8136.tmp of size 7196 and isopen=true finished after 0 time(s) through the loop
There's no way to run the real code inside a debugger to step through it, but from looking at the source to sun.nio.ch.FileChannelImpl.read()
it looks like a 0 is returned if the file magically becomes closed while internal data structures are prepared; 没有办法在调试器中运行真实的代码来逐步调试它,但是从查看源代码到sun.nio.ch.FileChannelImpl.read()
,如果文件在内部数据中神奇地关闭,则看起来像返回了0。准备结构; the code below is copied from the Java 7 reference implementation, comments added by me: 下面的代码是从Java 7参考实现中复制的,我添加了注释:
// 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 (......)
.......
But the debugging code tests isOpen()
and gets true. 但是调试代码会测试isOpen()
并得到true。 So I don't know what's going wrong. 所以我不知道出了什么问题。
As the current test data files are tiny, I dropped this in place just to have something working: 由于当前的测试数据文件很小,因此我将其放置在适当的位置只是为了使某些功能正常工作:
works for now: 现在可以使用:
try {
byte[] scratch = Files.readAllBytes(in);
java.util.zip.CRC32 placeholder = new java.util.zip.CRC32();
placeholder.update(scratch);
// do stuff with placeholder.getValue()
}
I don't want to slurp the entire file into memory for the Real Code, because some of those files can be large . 我不想将整个文件插入到Real Code的内存中,因为其中一些文件可能很大 。 I do note that readAllBytes
uses an InputStream in its reference implementation, which has no trouble reading the same file that SeekableByteChannel failed to. 我确实注意到readAllBytes
在其参考实现中使用了InputStream,它可以readAllBytes
读取SeekableByteChannel失败的相同文件。 So I'll probably rewrite the code to just use input streams instead of byte channels. 因此,我可能会重写代码以仅使用输入流而不是字节通道。 I'd still like to figure out what's gone wrong in case a future scenario comes up where we need to use byte channels. 我仍然想弄清楚出了什么问题,以防将来出现需要使用字节通道的情况。 What am I missing with SeekableByteChannel
? SeekableByteChannel
我缺少什么?
检查“ reasonable_buffer_size”是否不为零。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.