如何发布使用 GSON 解析大型 json 文件的进度
Posted
技术标签:
【中文标题】如何发布使用 GSON 解析大型 json 文件的进度【英文标题】:How to publish progress for large json file parsing with GSON 【发布时间】:2015-03-09 12:41:12 【问题描述】:亲爱的 ***ers,
我目前正在从我的原始资源中解析一个大型 json 文件。我不得不将阅读逐行更改为将 Reader 对象与 gson 结合使用,以逃避内存不足异常。到目前为止,一切顺利。
现在这一切都发生在异步任务中,我希望通过使用publishProgress()
在某种加载屏幕中通知用户进度。
InputStream raw = getResources().openRawResource(R.raw.json);
Reader rd = new BufferedReader(new InputStreamReader(raw));
Gson gson = new Gson();
mReadObjects = gson.fromJson(rd, ReadObjectList.class);
这是我目前读取文件的方式,但我不知道是否(以及如何)可以从 GSON 或 Reader 对象获取任何类型的进度更新。
非常感谢任何帮助!
【问题讨论】:
【参考方案1】:您必须围绕InputStream
(或Reader
)编写一个包装器。
这样的事情应该可以工作:
public class ProgressInputStream extends FilterInputStream
private final int size;
private long bytesRead;
private int percent;
private List<Listener> listeners = new ArrayList<>();
public ProgressInputStream(InputStream in)
super(in);
try
size = available();
if (size == 0) throw new IOException();
catch (IOException e)
throw new RuntimeException("This reader can only be used on InputStreams with a known size", e);
bytesRead = 0;
percent = 0;
public void addListener(Listener listener)
listeners.add(listener);
public void removeListener(Listener listener)
listeners.remove(listener);
@Override
public int read() throws IOException
int b = super.read();
updateProgress(1);
return b;
@Override
public int read(@NonNull byte[] b) throws IOException
return updateProgress(super.read(b));
@Override
public int read(@NonNull byte[] b, int off, int len) throws IOException
return 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 <T extends Number> T updateProgress(T numBytesRead)
if (numBytesRead.longValue() > 0)
bytesRead += numBytesRead.longValue();
if (bytesRead * 100 / size > percent)
percent = (int) (bytesRead * 100 / size);
for (Listener listener : listeners)
listener.onProgressChanged(percent);
return numBytesRead;
public interface Listener
void onProgressChanged(int percentage);
使用方法:
ProgressInputStream raw = new ProgressInputStream(getResources().openRawResource(R.raw.json));
raw.addListener(new ProgressInputStream.Listener()
@Override
public void onProgressChanged(int percentage)
publishProgress(percentage);
);
Reader rd = new BufferedReader(new InputStreamReader(raw));
【讨论】:
我不知道为什么这只有一票并且没有被标记为正确。这对我帮助很大,谢谢。以上是关于如何发布使用 GSON 解析大型 json 文件的进度的主要内容,如果未能解决你的问题,请参考以下文章
基于流式输入输出 使用Java借助GSON库 实现对大型asc文件的读入解析 并输出为JSON文件