2

我有一个BufferedWriter如下图:

BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(
        new GZIPOutputStream( hdfs.create(filepath, true ))));

String line = "text";
writer.write(line);

我想找出写入文件的字节而不像查询文件一样

hdfs = FileSystem.get( new URI( "hdfs://localhost:8020" ), configuration );

filepath = new Path("path");
hdfs.getFileStatus(filepath).getLen();

因为它会增加开销,我不希望这样。

我也不能这样做:

line.getBytes().length;

因为它在压缩前给出大小。

4

4 回答 4

3

您可以使用 Apache commons IO 库中的CountingOutputStream

将它放在 GZIPOutputStream 和文件 Outputstream (hdfs.create(..)) 之间。

将内容写入文件后,您可以从 CountingOutputStream 实例中读取写入的字节数。

于 2014-08-29T15:21:33.153 回答
2

如果这还不算太晚并且您使用的是 1.7+ 并且您不想引入像GuavaCommons-IO这样的整个库,您可以扩展GZIPOutputStream并像这样从相关的Deflater获取数据:

public class MyGZIPOutputStream extends GZIPOutputStream {

  public MyGZIPOutputStream(OutputStream out) throws IOException {
      super(out);
  }

  public long getBytesRead() {
      return def.getBytesRead();
  }

  public long getBytesWritten() {
      return def.getBytesWritten();
  }

  public void setLevel(int level) {
      def.setLevel(level);
  }
}
于 2017-09-08T05:24:01.460 回答
0

你可以让你自己的后代OutputStream并计算调用了多少时间write方法

于 2014-08-29T15:07:33.180 回答
0

这与 Olaseni 的响应类似,但我将计数移至BufferedOutputStream而不是GZIPOutputStream,这更加稳健,因为def.getBytesRead()在流关闭后 Olaseni 的答案不可用。

通过下面的实现,您可以AtomicLong向构造函数提供您自己的,以便您可以CountingBufferedOutputStream在 try-with-resources 块中分配 ,但在块退出后(即文件关闭后)仍然检索计数。

public static class CountingBufferedOutputStream extends BufferedOutputStream {
    private final AtomicLong bytesWritten;

    public CountingBufferedOutputStream(OutputStream out) throws IOException {
        super(out);
        this.bytesWritten = new AtomicLong();
    }

    public CountingBufferedOutputStream(OutputStream out, int bufSize) throws IOException {
        super(out, bufSize);
        this.bytesWritten = new AtomicLong();
    }

    public CountingBufferedOutputStream(OutputStream out, int bufSize, AtomicLong bytesWritten)
            throws IOException {
        super(out, bufSize);
        this.bytesWritten = bytesWritten;
    }

    @Override
    public void write(byte[] b) throws IOException {
        super.write(b);
        bytesWritten.addAndGet(b.length);
    }

    @Override
    public void write(byte[] b, int off, int len) throws IOException {
        super.write(b, off, len);
        bytesWritten.addAndGet(len);
    }

    @Override
    public synchronized void write(int b) throws IOException {
        super.write(b);
        bytesWritten.incrementAndGet();
    }

    public long getBytesWritten() {
        return bytesWritten.get();
    }
}
于 2019-10-26T01:17:07.100 回答