【问题标题】:Java BufferedInputStream behaviorJava BufferedInputStream 行为
【发布时间】:2023-04-09 23:56:01
【问题描述】:

如果文件大小 > 8k,为什么读取的 LAST Byte = 0?

private static final int GAP_SIZE = 8 * 1024;

public static void main(String[] args) throws Exception{
    File tmp = File.createTempFile("gap", ".txt");
    FileOutputStream out = new FileOutputStream(tmp);
    out.write(1);
    out.write(new byte[GAP_SIZE]);
    out.write(2);
    out.close();
    BufferedInputStream in = new BufferedInputStream(new FileInputStream(tmp));
    int first = in.read();
    in.skip(GAP_SIZE);
    int last = in.read();
    System.out.println(first);
    System.out.println(last);
}

【问题讨论】:

  • 不保证实际跳过的字节数。你必须检查一下。似乎它不想跳过本机文件系统块大小。

标签: java inputstream behavior bufferedinputstream


【解决方案1】:

InputStream API 表示,由于各种原因,skip 方法最终可能会跳过一些较小的字节数。试试这个

...
long n = in.skip(GAP_SIZE);
System.out.println(n);
...

它打印 8191 而不是预期的 8192。这与 BufferedInputStream 实现细节有关,如果你删除它(在这种具体情况下它不会提高性能)你会得到预期的结果

...
InputStream in = new FileInputStream(tmp);
...

输出

1
2

【讨论】:

  • 我很困惑...如果原因是 FileInputStream 中的跳过方法,为什么删除 BufferedInputStream 可以解决问题?
  • 实际原因是BufferedInputStream实现细节,FileInputStream没问题
  • 嗯,你是对的,但我仍然感到困惑,正如 FileInputStream Skip 所说:“由于各种原因,skip 方法最终可能会跳过一些较小的字节数”。
  • 对,在实际应用中,我们应该在循环中使用skip,直到我们跳过我们需要的数字
  • 我找到了原因:BufferedInputStream有一个defaultBufferSize = 8192
【解决方案2】:

正如 Perception 所说,您需要检查 skip 的返回。如果我添加支票并进行补偿,它可以解决问题:

long skipped = in.skip(GAP_SIZE);
System.out.println( "GAP: " + GAP_SIZE + " skipped: " + skipped ) ;
if( skipped < GAP_SIZE)
{
   skipped = in.skip(GAP_SIZE-skipped);
}

skip 部分所述FileInputStream

由于各种原因,skip 方法最终可能会跳过一些较小的字节数,可能是 0

【讨论】:

    猜你喜欢
    • 2012-06-18
    • 1970-01-01
    • 2021-12-13
    • 2018-09-15
    • 1970-01-01
    • 2019-05-27
    • 2013-08-19
    • 2012-04-06
    • 1970-01-01
    相关资源
    最近更新 更多