我正在尝试将原始文件夹中的大型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
{
}
我没有收到任何错误,但输出文件比原始文件小几个字节,无法打开。 我需要做些什么来解决这个问题?
答案 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();
}
}