Java 复制的文档文件与原始文档文件的大小和哈希不同
我试图在Android应用程序中复制文档文件,但在检查创建的副本时,它似乎与原始文件不完全相同(这导致了一个问题,因为我需要在下次调用副本时对这两个文件进行MD5检查,以避免覆盖相同的文件) 程序如下:Java 复制的文档文件与原始文档文件的大小和哈希不同,java,android,file,documentfile,Java,Android,File,Documentfile,我试图在Android应用程序中复制文档文件,但在检查创建的副本时,它似乎与原始文件不完全相同(这导致了一个问题,因为我需要在下次调用副本时对这两个文件进行MD5检查,以避免覆盖相同的文件) 程序如下: 用户从“操作”\u“打开”\u“文档”树中选择文件 已获取源文件的类型 已初始化目标位置中的新文档文件 第一个文件的内容复制到第二个文件中 初始阶段使用以下代码完成: //获取源文件的类型 字符串sourceFileType=MimeTypeMap.getSingleton().getExten
//获取源文件的类型
字符串sourceFileType=MimeTypeMap.getSingleton().getExtensionFromMimeType(contextRef.getContentResolver().getType(file.getUri());
//创建新(空)文件
DocumentFile newFile=targetLocation.createFile(sourceFileType,file.getName());
//复制文件
CopyBufferedFile(新建BufferedInputStream(contextRef.getContentResolver().openInputStream(file.getUri())),新建BufferedOutputStream(contextRef.getContentResolver().openOutputStream(newFile.getUri()));
使用以下代码段完成主复制过程:
void CopyBufferedFile(BufferedInputStream BufferedInputStream,BufferedOutputStream BufferedOutputStream)
{
//将临时本地文件的内容复制到DocumentFile
尝试
{
字节[]buf=新字节[1024];
bufferedInputStream.read(buf);
做
{
bufferedOutputStream.write(buf);
}
while(bufferedInputStream.read(buf)!=-1);
}
捕获(IOE异常)
{
e、 printStackTrace();
}
最后
{
尝试
{
if(bufferedInputStream!=null)bufferedInputStream.close();
if(bufferedOutputStream!=null)bufferedOutputStream.close();
}
捕获(IOE异常)
{
e、 printStackTrace();
}
}
}
我面临的问题是,尽管文件复制成功并且可用(它是一张猫的图片,在目标中仍然是一张猫的图片),但它略有不同
提前感谢。您的复制代码不正确。它(错误地)假设每次调用
read
都将返回buffer.length
字节或返回-1
您应该做的是捕获每次在变量中读取的字节数,然后准确地写入该字节数。您关闭流的代码冗长且(理论上)有缺陷
这里是一个重写,解决了这两个问题,以及其他一些问题
void copyBufferedFile(BufferedInputStream bufferedInputStream,
BufferedOutputStream bufferedOutputStream)
throws IOException
{
try (BufferedInputStream in = bufferedInputStream;
BufferedOutputStream out = bufferedOutputStream)
{
byte[] buf = new byte[1024];
int nosRead;
while ((nosRead = in.read(buf)) != -1) // read this carefully ...
{
out.write(buf, 0, nosRead);
}
}
}
正如您所看到的,我已经摆脱了虚假的“捕获和挤压异常”处理程序,并使用Java7+try with resources修复了资源泄漏
还有几个问题:
file
或Path
对象)作为参数,并负责打开流Buffered*
类使用的默认缓冲区大小相同。。。。或更大transferFrom
,如下所述:
1-理论上,如果
bufferedInputStream.close()
引发异常,则将跳过bufferedOutputStream.close()
调用。实际上,关闭输入流不太可能引发异常。但无论采用哪种方式,资源试用方法都能正确地处理这一问题,而且要简洁得多。用户从“操作”、“打开”、“文档”树中选择一个文件。
。你的意思是用行动文件。精彩的回答,完美地解决了所有问题,并给了我一些东西来阅读关于你的建议。谢谢你!