【问题标题】:Java: how to define the size of buffer to read all data from FileChannelJava:如何定义缓冲区的大小以从 FileChannel 读取所有数据
【发布时间】:2017-02-04 12:47:26
【问题描述】:

我有一个管道,我需要从中读取数据。但是,正如我在阅读之前所了解的那样,我必须创建一些大小的缓冲区。问题是如何定义缓冲区的大小以从管道中读取all 数据?

这是我的代码:

RandomAccessFile aFile     = new RandomAccessFile(PIPE_FILE, "r");
FileChannel  inChannel = aFile.getChannel();
ByteBuffer buf = ByteBuffer.allocate(4);//temp 4
while(true){
    System.out.println("Size:"+inChannel.size());//returns 0
    int bytesRead = inChannel.read(buf);
    byte [] bytes=buf.array();
    ...
    buf.clear();
}

【问题讨论】:

  • 选择这种大小的缓冲区是在读取时间和内存之间进行权衡。如果您采用较小的尺寸,则将花费更多时间,因为使用的循环次数越多,如果尺寸越大,则使用的内存越多。我已经看到 1024 作为要选择的命令值。
  • 你不能使用Files.readAllBytes 有什么具体原因吗?
  • @BackSlash 说实话我不知道。在我在互联网上看到的许多示例中,人们建议使用 RandomAccessFile 从命名管道中读取数据。

标签: java


【解决方案1】:

与文件不同,管道没有固定大小:据我们所知,管道另一端的写入器可以将通过算法创建的数据推送给您,因此管道流可能是无限的。

您需要创建一个一定大小的缓冲区,通常为数百到数千字节,循环从管道中读取,并在执行过程中处理数据流,或者将其保存在循环中动态分配的缓冲区中.

【讨论】:

    【解决方案2】:

    我还不能发cmet,所以我会根据我的理解来回答:

    我将重点说明这是一个 RandomAccessFile。

    正如另一个答案中所建议的,无论缓冲区大小如何,您都可以循环读取它直到结束:

    while(inChannel.read(buf) >= 0)
    {
    }
    

    除此之外,为了准确回答您最初的问题,即使您的文件/管道很可能会在给定时间不断增长,但它具有一定的大小,因此您可以将其用于缓冲区,但如果介于文件之间被修改然后这可能导致不完整的读取甚至错误(例如,如果管道将被清除或类似的东西):

    ByteBuffer buf = ByteBuffer.allocate(inChannel.size());
    

    【讨论】:

    • 注意:你要使用>= 0,而不是> 0。 -1 表示流结束; 0 只是表示这次没有读取任何字节,但下次可能会有一些字节。
    • 很好的区别,将编辑我的帖子,谢谢。小细节是关键:)。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多