2

我正在尝试将一个大型 pdf 文件(3.7 mb)从我的原始文件夹复制到外部缓存目录。

我使用以下代码:

int i = 0;
        if (Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())) 
        {           
            InputStream input = getResources().openRawResource(pdfs[i]);
            File file = new File(Environment.getExternalStorageDirectory(), "/Android/data/eu.app/cache/" + pdfNames[i]);

            if(!file.exists())
            {
                try
                {
                    new File(Environment.getExternalStorageDirectory().getAbsolutePath() + "/Android/data/eu.app/cache").mkdirs();
                    FileOutputStream fos = new FileOutputStream(file.toURI().getPath(), false);

                    OutputStream os = new BufferedOutputStream(fos);



                    byte[] buffer = new byte[1024];
                    int byteRead = 0;


                    while ((byteRead = input.read(buffer)) != -1) {

                            os.write(buffer, 0, byteRead);
                    }

                    fos.close();

                }
                catch(Exception ex)
                {
                    Log.d("storage", ex.getMessage()); 

                }
            }               
        }
        else
        {

        }

我没有收到任何错误,但输出文件比原始文件小几个字节,无法打开。我需要做什么来解决这个问题?

4

2 回答 2

2

我认为主要问题是你关闭 fos 而你应该关闭 os. 您还需要将关闭操作放在 finally 块中。

更新(现在使用全键盘;)):在刷新缓冲流之前关闭文件流(fos)。您应该做的是关闭缓冲流(os),然后刷新其缓冲区并写入丢失的字节,然后它会自动关闭底层文件流。要修复它,请更改fos.close()os.close().

此外,为了确保您始终关闭流,您应该将关闭操作放在 finally 块中。一个典型的模式如下:

BufferedInputStream in = null;
try {
    in = new BufferedInputStream(anInputStream);

    BufferedOutputStream out = null;
    try {
        out = new BufferedOutputStream(new FileOutputStream(aFile));
        // Read and write what you should write
    }
    finally {
        if (out != null) out.close();
    }
} finally {
    if (in != null) in.close();
}

您可以轻松添加输入流,但要小心确保所有流都已关闭。这可以通过嵌套 finally 块或在 finally 块内嵌套 try-catch 块来处理。

要么你从这个方法中抛出一个 IOException 并在外面处理它(通常是首选),要么你将上面的代码包装在一个新的 try-catch 语句中并在那里处理它。但是,在方法中处理它会将 UI 与逻辑混合在一起,并且代码通常更清晰地将 UI 和逻辑分开。

最后一点:1024 相当小。玩不同的价值观。另一方面,缓冲流将为您处理缓冲。

于 2012-09-10T19:46:56.927 回答
0

几年来,我一直在使用此功能从一个流读取到另一个流,并且从未对生成的文件有任何问题。只需照原样打开源文件和目标文件,并将它们各自的流传递到此函数中:

public static void streamToStream(InputStream is, OutputStream os) {

    int count = 0;
    try {
        while(count != -1) {
            byte[] bytes = new byte[2048];
            count = is.read(bytes);
            if(count == -1) {
                continue;
            }

            os.write(bytes, 0, count);
            bytes = null;
        }
    } catch (Exception e) {
        e.printStackTrace();
    }
}
于 2012-09-10T19:32:51.437 回答