如何在Android中复制大文件?

时间:2012-09-10 19:20:27

标签: android file pdf copy filesize

我正在尝试将原始文件夹中的大型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
        {

        }

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

2 个答案:

答案 0 :(得分:2)

我认为主要问题是你关闭操作系统时应关闭操作系统。您还需要将关闭操作放在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相当小。玩不同的价值观。另一方面,缓冲流将为您处理缓冲。

答案 1 :(得分: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();
    }
}