Path file = Paths.get("c:/large.log");
AsynchronousFileChannel channel = AsynchronousFileChannel.open(file);
final ByteBuffer buffer = ByteBuffer.allocate(1000);
channel.read(buffer, 0, buffer,
new CompletionHandler<Integer, ByteBuffer>() {
public void completed(Integer result, ByteBuffer attachment) {
System.out.println(new String(buffer.array()));
}
});
Run Code Online (Sandbox Code Playgroud)
这样,我就可以从large.log中读取前1000字节。如果我不想分配更大的字节数组,如 ByteBuffer.allocate(1000*1000),我如何读取以下日志。因为我认为这会导致OutOfMemory。
有人可以给我示例代码吗? 谢谢。
ps:我可以用JIO循环读取大文件,因为我可以检查java.io.BufferedReader.read()的返回值。但我不知道NIO2怎么办。
这是一个有效的技巧。
您需要注意以下几点:
buffer.array()输出。我必须使用 buffer.clear() 重置位置,以便异步读取会看到有 1000 个备用字节,但这并不能清除数组中的现有数据。因此,当您到达文件末尾时,如果您读取的内容少于 1000 个字节,它将打印整个缓冲区:无论您刚刚读取了多少内容,加上缓冲区末尾最后的内容的剩余 1000 个字节。在现实生活中,您可能想要对此做一些事情(可能是结果或缓冲区的位置。buffer哪个是类变量在completed方法中是好的,但channel哪个也是类变量是空的。我还没弄清楚为什么会这样。所以我更改了它,使其channel作为附件而不是缓冲区传递。对我来说仍然没有意义。read在 main 方法的末尾添加了 a 。按Enter退出。pos维护您正在读取的文件中的位置。complete。这就是为什么我放弃了匿名类并实现了接口本身。玩得开心。
import java.nio.*;
import java.nio.channels.*;
import java.nio.file.*;
import java.io.IOException;
public class TryNio implements CompletionHandler<Integer, AsynchronousFileChannel> {
// need to keep track of the next position.
int pos = 0;
AsynchronousFileChannel channel = null;
ByteBuffer buffer = null;
public void completed(Integer result, AsynchronousFileChannel attachment) {
// if result is -1 means nothing was read.
if (result != -1) {
pos += result; // don't read the same text again.
// your output command.
System.out.println(new String(buffer.array()));
buffer.clear(); // reset the buffer so you can read more.
}
// initiate another asynchronous read, with this.
attachment.read(buffer, pos , attachment, this );
}
public void failed(Throwable exc,
AsynchronousFileChannel attachment) {
System.err.println ("Error!");
exc.printStackTrace();
}
public void doit() {
Path file = Paths.get("/var/log/syslog");
AsynchronousFileChannel channel = null;
try {
channel = AsynchronousFileChannel.open(file);
} catch (IOException e) {
System.err.println ("Could not open file: " + file.toString());
System.exit(1); // yeah. heh.
}
buffer = ByteBuffer.allocate(1000);
// start off the asynch read.
channel.read(buffer, pos , channel, this );
// this method now exits, thread returns to main and waits for user input.
}
public static void main (String [] args) {
TryNio tn = new TryNio();
tn.doit();
// wait fur user to press a key otherwise java exits because the
// asynch thread isn't important enough to keep it running.
try { System.in.read(); } catch (IOException e) { }
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
6696 次 |
| 最近记录: |