0

首先在应用程序中下载文件,并保留名称为try.pdf

这里的代码:

try {

URL url = new URL(aurl[0]);
    URLConnection conexion = url.openConnection();
    conexion.connect();

    int lenghtOfFile = conexion.getContentLength();
    Log.d("ANDRO_ASYNC", "Lenght of file: " + lenghtOfFile);

    InputStream input = new BufferedInputStream(url.openStream());
    FileOutputStream fos = openFileOutput("try.pdf", Context.MODE_PRIVATE);

    byte data[] = new byte[1024];

    long total = 0;

        while ((count = input.read(data)) != -1) {
            total += count;
            publishProgress(""+(int)((total*100)/lenghtOfFile));
            fos.write(data, 0, count);
        }

        fos.flush();
        fos.close();
        input.close();
} catch (Exception e) {}
return null;

}

现在,当我想使用以下代码打开它时,问题就来了:

   try {
    FileInputStream in = openFileInput("try.pdf"); 
    InputStreamReader inputStreamReader = new InputStreamReader(in); 
    BufferedReader bufferedReader = new BufferedReader(inputStreamReader); 
    StringBuilder sb = new StringBuilder(); 
    String line; 
    try {
        while ((line = bufferedReader.readLine()) != null){ 
            sb.append(line); 
        }
    } catch (IOException e) {
        e.printStackTrace();
    }
} catch (FileNotFoundException e) {
    e.printStackTrace();
}

当尝试使用 FileInputStream 读取文件“try.pdf”的文件时,我有错误 outOfMemory,有什么解决方案吗?

谢谢

4

2 回答 2

0

我怀疑的问题在于你的编码风格,C'ish DOS 单线程。

while ((count = input.read(data)) != -1) {
        total += count;
        publishProgress(""+(int)((total*100)/lenghtOfFile));
        fos.write(data, 0, count);
    }

再次使用相同的 C'ish DOC 单线程样式

while ((line = bufferedReader.readLine()) != null){ 
        sb.append(line); 

您需要在 2 个不同的线程(显然非 UI)上阅读和发布进度(readLine 和追加)。当一个线程添加到等待数据队列中时,另一个线程从中提取。通过这种方式,您可以让 CPU 时间稍微放松一下。

确保在 2 个线程共享队列之间为此使用 LinkedList 和 ArrayList。

于 2012-06-27T08:50:40.333 回答
0

似乎最可能的原因是文件太大而无法保存在内存中(并且您似乎正在尝试将整个文件加载到内存中) - 尽管在分配失败发生时看到错误本身会确定.

此外,如果它真的是一个 pdf 文件而不是纯文本文件,我认为 BufferedReader 将无法正确读取它(并且可能不会正确换行,因为这需要可能不在的 CRLF pdf二进制文件)。

如果它太大,那么您需要(取决于您正在使用它做什么)控制显示在屏幕上的内容并仅加载该数据,或者如果您正在处理,则以较小的块而不是一个块来处理它而不是显示它。

于 2012-06-27T08:40:34.733 回答