【发布时间】:2016-01-16 20:04:17
【问题描述】:
所以你知道你可以使用 AsynchronousFileChannel 将整个文件读入一个字符串:
AsynchronousFileChannel fileChannel = AsynchronousFileChannel.open(filePath, StandardOpenOption.READ);
long len = fileChannel.size();
ReadAttachment readAttachment = new ReadAttachment();
readAttachment.byteBuffer = ByteBuffer.allocate((int) len);
readAttachment.asynchronousChannel = fileChannel;
CompletionHandler<Integer, ReadAttachment> completionHandler = new CompletionHandler<Integer, ReadAttachment>() {
@Override
public void completed(Integer result, ReadAttachment attachment) {
String content = new String(attachment.byteBuffer.array());
try {
attachment.asynchronousChannel.close();
} catch (IOException e) {
e.printStackTrace();
}
completeCallback.accept(content);
}
@Override
public void failed(Throwable exc, ReadAttachment attachment) {
exc.printStackTrace();
exceptionError(errorCallback, completeCallback, String.format("error while reading file [%s]: %s", path, exc.getMessage()));
}
};
fileChannel.read(
readAttachment.byteBuffer,
0,
readAttachment,
completionHandler);
假设现在,我不想分配整个ByteBuffer,而是逐行读取。我可以使用固定宽度的ByteBuffer 并多次调用read,总是复制并附加到 StringBuffer 直到我没有进入新行...我唯一担心的是:因为文件的编码我正在阅读的可能是每个字符多字节(UTF 的东西),可能会发生读取的字节以不完整的字符结尾。如何确保将正确的字节转换为字符串而不弄乱编码?
更新:答案在所选答案的评论中,但基本指向CharsetDecoder。
【问题讨论】:
-
不要使用异步 I/O 读取行。只是不合适。
BufferedReader.readLine().每秒可以读取数百万行 -
我需要非阻塞操作!
-
那你为什么要使用异步 I/O?这不是非阻塞的。它是继阻塞和非阻塞之后的第三种范式。但是为什么你认为你不能首先使用阻塞 I/O?
-
如果我使用 Handler 它应该是非阻塞的,不是吗?您还建议什么其他范式?