我有一个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;
因为它在压缩前给出尺寸。
答案 0 :(得分:2)
您可以使用Apache commons IO库中的CountingOutputStream。
将它放在GZIPOutputStream和文件Outputstream(hdfs.create(..))之间。
将内容写入文件后,您可以从CountingOutputStream实例中读取写入的字节数。
答案 1 :(得分:2)
如果现在还不太晚,并且您使用的是1.7+并且您不想使用Guava或Commons-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();
}
}