通过GZIPOutputStream形成的BufferedWriter计算写入文件的字节数

时间:2014-08-29 15:04:00

标签: java outputstream bufferedwriter gzipoutputstream

我有一个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 个答案:

答案 0 :(得分:2)

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

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

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

答案 1 :(得分:2)

如果现在还不太晚,并且您使用的是1.7+并且您不想使用GuavaCommons-IO这样的整个库,则可以扩展{{ 3}}并从关联的GZIPOutputStream获取数据,如下所示:

public class MyGZIPOutputStream extends GZIPOutputStream {

  public GZIPOutputStream(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);
  }
}

答案 2 :(得分:0)

您可以让自己拥有OutputStream的后代并计算调用了多少次write方法

答案 3 :(得分:0)

这类似于Olaseni的回答,但我将计数移到了BufferedOutputStream而不是GZIPOutputStream中,这更可靠了,因为Olaseni回答中的def.getBytesRead()不是流关闭后可用。

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

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();
    }
}