通过 ReadableByteChannel 的 InputStream 没有读到结束
InputStream via ReadableByteChannel does not read to end
我在使用 InputStreams 时遇到了一个问题,我想提高从该频道读取数据的性能。因此我阅读 ReadableByteChannel
.
因此,使用此代码读取速度更快:
public static String readAll(InputStream is, String charset, int size) throws IOException{
try(ByteArrayOutputStream bos = new ByteArrayOutputStream()){
java.nio.ByteBuffer buffer = java.nio.ByteBuffer.allocate(size);
try(ReadableByteChannel channel = Channels.newChannel(is)){
int bytesRead = 0;
do{
bytesRead = channel.read(buffer);
bos.write(buffer.array(), 0, bytesRead);
buffer.clear();
}
while(bytesRead >= size);
}
catch(Exception ex){
ex.printStackTrace();
}
String ans = bos.toString(charset);
return ans;
}
}
问题是:它每次都没有读到最后!如果我尝试读取一个文件,它工作得很好。如果我从网络套接字读取(例如手动请求网页),它有时会在两者之间停止。
怎样才能读完?
我不想使用这样的东西:
StringBuilder result = new StringBuilder();
while(true){
int ans = is.read();
if(ans == -1) break;
result.append((char)ans);
}
return result.toString();
因为这个实现很慢。
希望你能帮我解决我的问题。也许我的代码有一些错误。
这会导致问题:
... } while (bytesRead >= size);
从套接字读取可能 return 当至少读取一个字节时(或者即使在非阻塞的情况下没有字节)。因此,如果 OS 套接字缓冲区中没有足够的字节,尽管显然没有读取完整内容,但该条件将中断循环。如果 size
确定要接收的预期长度,则执行 total += bytesRead
并在 total
达到 size
时中断循环。或者,如果您当然到达文件末尾...
你的复制循环是完全错误的。没有理由 bytesRead
应该 曾经 是 >= size
,并且它在流的末尾行为不端。它应该是这样的:
while ((bytesRead = channel.read(buffer)) > 0)
{
bos.write(buffer.array(), 0, bytesRead);
buffer.clear();
}
适当调整以将传输限制为 size
字节,这是非常重要的。
但是将所有这些叠加在现有的 InputStream
上不可能 'much faster' 直接使用 InputStream
,除非因为提前终止。除非您发布了使用 InputStream
的想法,否则速度非常慢。尝试使用 'BufferedInputStream
.
我在使用 InputStreams 时遇到了一个问题,我想提高从该频道读取数据的性能。因此我阅读 ReadableByteChannel
.
因此,使用此代码读取速度更快:
public static String readAll(InputStream is, String charset, int size) throws IOException{
try(ByteArrayOutputStream bos = new ByteArrayOutputStream()){
java.nio.ByteBuffer buffer = java.nio.ByteBuffer.allocate(size);
try(ReadableByteChannel channel = Channels.newChannel(is)){
int bytesRead = 0;
do{
bytesRead = channel.read(buffer);
bos.write(buffer.array(), 0, bytesRead);
buffer.clear();
}
while(bytesRead >= size);
}
catch(Exception ex){
ex.printStackTrace();
}
String ans = bos.toString(charset);
return ans;
}
}
问题是:它每次都没有读到最后!如果我尝试读取一个文件,它工作得很好。如果我从网络套接字读取(例如手动请求网页),它有时会在两者之间停止。
怎样才能读完?
我不想使用这样的东西:
StringBuilder result = new StringBuilder();
while(true){
int ans = is.read();
if(ans == -1) break;
result.append((char)ans);
}
return result.toString();
因为这个实现很慢。
希望你能帮我解决我的问题。也许我的代码有一些错误。
这会导致问题:
... } while (bytesRead >= size);
从套接字读取可能 return 当至少读取一个字节时(或者即使在非阻塞的情况下没有字节)。因此,如果 OS 套接字缓冲区中没有足够的字节,尽管显然没有读取完整内容,但该条件将中断循环。如果 size
确定要接收的预期长度,则执行 total += bytesRead
并在 total
达到 size
时中断循环。或者,如果您当然到达文件末尾...
你的复制循环是完全错误的。没有理由 bytesRead
应该 曾经 是 >= size
,并且它在流的末尾行为不端。它应该是这样的:
while ((bytesRead = channel.read(buffer)) > 0)
{
bos.write(buffer.array(), 0, bytesRead);
buffer.clear();
}
适当调整以将传输限制为 size
字节,这是非常重要的。
但是将所有这些叠加在现有的 InputStream
上不可能 'much faster' 直接使用 InputStream
,除非因为提前终止。除非您发布了使用 InputStream
的想法,否则速度非常慢。尝试使用 'BufferedInputStream
.