如果我理解正確,方法是創建一個裝飾器inputstream並重寫一些方法,將chante輸入流狀態,如讀取方法或跳過method.And,然後使用觀察者模式通知moinotr閱讀的百分比。請參閱下面的代碼:
public static class ProcessInputStream extends InputStream{
private InputStream in;
private int length,sumRead;
private java.util.List<Listener> listeners;
private double percent;
public ProcessInputStream(InputStream inputStream,int length) throws IOException{
this.in=inputStream;
listeners=new ArrayList<>();
sumRead=0;
this.length=length;
}
@Override
public int read(byte[] b) throws IOException {
int readCount = in.read(b);
evaluatePercent(readCount);
return readCount;
}
@Override
public int read(byte[] b, int off, int len) throws IOException {
int readCount = in.read(b, off, len);
evaluatePercent(readCount);
return readCount;
}
@Override
public long skip(long n) throws IOException {
long skip = in.skip(n);
evaluatePercent(skip);
return skip;
}
@Override
public int read() throws IOException {
int read = in.read();
if(read!=-1){
evaluatePercent(1);
}
return read;
}
public ProcessInputStream addListener(Listener listener){
this.listeners.add(listener);
return this;
}
private void evaluatePercent(long readCount){
if(readCount!=-1){
sumRead+=readCount;
percent=sumRead*1.0/length;
}
notifyListener();
}
private void notifyListener(){
for (Listener listener : listeners) {
listener.process(percent);
}
}
}
監聽器類是當有人改變InputStream的索引像讀取的字節或跳過字節將被調用的回調。
public interface Listener{
void process(double percent);
}
測試用例代碼:
UserInfo userInfo=new UserInfo();
userInfo.setName("zyr");
userInfo.setPassword("123");
userInfo.setTestString(new ArrayList<>());
System.out.println(userInfo);
ByteArrayOutputStream bos = new ByteArrayOutputStream();
ObjectOutputStream oos=new ObjectOutputStream(bos);
oos.writeObject(userInfo);
byte[] objectBytes = bos.toByteArray();
oos.close();
bos.close();
ProcessInputStream processInputStream = new ProcessInputStream(new ByteArrayInputStream(objectBytes),objectBytes.length);
processInputStream.addListener(percent -> System.out.println(percent));
ObjectInputStream ois=new ObjectInputStream(processInputStream);
UserInfo target = (UserInfo) ois.readObject();
System.out.println(target);
在上面的代碼,我只是打印的讀取的字節%,而你的要求,你應該改變進程欄的位置。
這是輸出的一部分;
UserInfo{id=0, name='zyr', password='123', testString=[]}
0.008658008658008658
0.017316017316017316
0.021645021645021644
......
......
0.9523809523809523
0.9696969696969697
0.974025974025974
0.9783549783549783
0.9956709956709957
1.0
UserInfo{id=0, name='zyr', password='123', testString=[]}
我可以得到尺寸查詢Uri。他們只會通過本地存儲而不是通過HTTP訪問 –