【问题标题】:What is the most efficient way to read a variable data length from binary input stream从二进制输入流中读取可变数据长度的最有效方法是什么
【发布时间】:2015-06-23 14:19:05
【问题描述】:

我正在使用 BufferedInputStream 并从二进制文件中读取一些数据字段。 我有一个标题,其中包含我必须读取的字段以确定下一条消息需要读取的字节数。所以我需要读取的数据量总是可变的。我尝试一次读取消息的全部字节数,但这有时无法读取消息的全部大小。

所以现在我只是循环并一次读取 1 个字节,直到获得完整的数据消息。这似乎可行,但似乎是读取大数据文件(50 meg 文件)的最有效方式。

从流式二进制文件中读取可变数量数据的最佳方法是什么?

谢谢!!

              int numRead= 0;
              int total =0;
              int readSize =56;  // actually read from header
              while(numRead>=0  && total < readSize){
                  // reading one byte at a time
                  //is there any way to read bigger chunks reliably
                  // since file is large
                  numRead= this.in.read(inBytes,total ,1); 
                  if(numRead>0){
                      total += numRead;
                  }
              }

【问题讨论】:

  • 您是从文件中创建BufferedInputStream 吗?
  • 是的,我正在创建和使用 BufferedInputStream
  • BufferedInputStream buffStream = new BufferedInputStream( new FileInputStream(...
  • 我不确定你在问什么。您是在问如何读取整个文件或如何检查此标头然后更改之后读取的数据量?
  • 你的 sn-p 中的 this 是什么?

标签: java


【解决方案1】:

您应该能够使用 read(byte[], int, int) 方法来填充字节数组。

int numRead= 0;
int total =0;
int readSize =56;
while(numRead >= 0 && total < readSize) {
    numRead = this.in.read(inBytes, total, readSize - total); 
    if(numRead > 0) {
       total += numRead;
    }
}

这与您所拥有的类似,但一次不限于 1 个字节。

【讨论】:

    【解决方案2】:

    我认为最好的解决方案是将您的输入流与DataInputStream 结合起来,然后使用readByte() 方法。

    DataInputStream dis = new DataInputStream(new BufferedInputStream( new FileInputStream(...
    

    【讨论】:

    • 你能解释一下你为什么认为这是最好的解决方案吗?
    • 因为据我了解,他需要读取原始类型... 数据输入流让应用程序读取原始Java数据类型
    • 不要写给我,把它添加到你的答案中。既然你说这可能是最好的解决方案,你应该在那里解释。这使您的答案更加完整。
    【解决方案3】:

    已在此处发布答案:java-inputstream-size Java InputStream size

    例如:

    int numRead= 0;
    int total =0;
    int readSize = 1000; //you can put an bigger value here
    while(numRead>0){
        numRead= this.in.read(inBytes,0,readSize); 
        total += numRead;
    }
    

    }

    使用此方法,可以通过 readSize 个字节块读取 inputStream。

    注意:此方法只能读取大小。字节数组将仅包含上次迭代期间获得的字节,因为我们每次将偏移量设置为 0 时都会覆盖它。另一点是您必须创建一个大小为(至少)readSize

    最后,有一些 API 可以完成将所有字节从 inputStream 获取到像 commons-io 这样的字节数组的过程。见this answer

    【讨论】:

      【解决方案4】:

      如果你只是想高效地读取文件

          final int BUFFER_SIZE = 1 << 10;
          try {
              BufferedInputStream in = new BufferedInputStream(new FileInputStream(fileName),BUFFER_SIZE);
              int bytesRead = 0;
              int bytesToRead = 1;
              byte[] bytes = new byte[BUFFER_SIZE];
              while((bytesRead = in.read(bytes)) != -1){
                  doSomethingWithContent(bytes,bytesRead);
              }
          } catch (IOException e) {
              e.printStackTrace();
          }
      

      这会在每次读取时将 BUFFER_SIZE 字节读入 byte[]。这将使读取次数显着减少,这就是它快得多的原因。

      【讨论】:

        猜你喜欢
        • 2014-11-03
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-11-24
        相关资源
        最近更新 更多