gpt4 book ai didi

java - 用于进度报告的 InputStream 或 Reader 包装器

转载 作者:搜寻专家 更新时间:2023-10-30 21:44:17 25 4
gpt4 key购买 nike

因此,我正在将文件数据提供给采用 Reader 的 API,并且我想要一种报告进度的方法。

编写一个包装 FileInputStreamFilterInputStream 实现似乎应该很简单,跟踪读取的字节数与总文件大小,并且触发一些事件(或者调用一些 update() 方法)来报告部分进度。

(或者,它可以报告读取的绝对字节数,而其他人可以进行数学计算——在其他流式传输情况下可能更有用。)

我知道我以前见过这个,我什至可能以前做过,但我找不到代码而且我很懒。有没有人把它放在身边?或者有人可以建议更好的方法吗?


一年(和一点)之后......

我根据以下 Adamski 的回答实现了一个解决方案,它有效,但在使用几个月后我不推荐它。当您有很多更新时,触发/处理不必要的进度事件会变成巨大的成本。基本的计数机制很好,但最好让关心进度的人为其投票,而不是将其推送给他们。

(如果您知道总大小,您可以尝试仅在每超过 1% 的变化或其他任何情况下触发一个事件,但这并不值得麻烦。而且通常情况下,您不这样做。)

最佳答案

这是一个相当基本的实现,它在读取额外字节时触发 PropertyChangeEvent。一些注意事项:

  • 该类不支持markreset 操作,尽管这些操作很容易添加。
  • 该类不会检查读取的总字节数是否超过预期的最大字节数,尽管在显示进度时客户端代码始终可以处理这一点。
  • 我还没有测试代码。

代码:

public class ProgressInputStream extends FilterInputStream {
private final PropertyChangeSupport propertyChangeSupport;
private final long maxNumBytes;
private volatile long totalNumBytesRead;

public ProgressInputStream(InputStream in, long maxNumBytes) {
super(in);
this.propertyChangeSupport = new PropertyChangeSupport(this);
this.maxNumBytes = maxNumBytes;
}

public long getMaxNumBytes() {
return maxNumBytes;
}

public long getTotalNumBytesRead() {
return totalNumBytesRead;
}

public void addPropertyChangeListener(PropertyChangeListener l) {
propertyChangeSupport.addPropertyChangeListener(l);
}

public void removePropertyChangeListener(PropertyChangeListener l) {
propertyChangeSupport.removePropertyChangeListener(l);
}

@Override
public int read() throws IOException {
int b = super.read();
updateProgress(1);
return b;
}

@Override
public int read(byte[] b) throws IOException {
return (int)updateProgress(super.read(b));
}

@Override
public int read(byte[] b, int off, int len) throws IOException {
return (int)updateProgress(super.read(b, off, len));
}

@Override
public long skip(long n) throws IOException {
return updateProgress(super.skip(n));
}

@Override
public void mark(int readlimit) {
throw new UnsupportedOperationException();
}

@Override
public void reset() throws IOException {
throw new UnsupportedOperationException();
}

@Override
public boolean markSupported() {
return false;
}

private long updateProgress(long numBytesRead) {
if (numBytesRead > 0) {
long oldTotalNumBytesRead = this.totalNumBytesRead;
this.totalNumBytesRead += numBytesRead;
propertyChangeSupport.firePropertyChange("totalNumBytesRead", oldTotalNumBytesRead, this.totalNumBytesRead);
}

return numBytesRead;
}
}

关于java - 用于进度报告的 InputStream 或 Reader 包装器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1339437/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com