java复制二进制数据
我试图读取一个视频文件,并将其写入另一个文件,但由于某种原因,当我进行md5sum比较时,它们不同,新文件无法被VLC读取。想法
MD5原始文件的总和:B13D9ACED2DD3F869245C8E085F88C2
MD5新文件总数:d41d8cd98f00b204e9800998ecf8427e
public void copyFile() throws IOException {
BufferedInputStream in = new BufferedInputStream(new FileInputStream("/home/zevrant/tmp/test.h264"));
BufferedOutputStream fileOutputStream = new BufferedOutputStream(new FileOutputStream(new File("/security/footage/test.h264")));
while(in.available() > 0) {
bytes = in.readNBytes(in.available());
fileOutputStream.write(bytes);
fileOutputStream.flush();
}
}
# 1 楼答案
来自@Stephen的答案。C很好。只是普通复制的代码:
# 2 楼答案
问题是,您需要对InputStream使用read()方法,而不是available()方法,并检查read()是否返回-1(如example)。available()方法只返回当前可读取的数据量,而不是整个流的大小。如果底层inputstream来自网络(例如套接字),那么available()可以返回0,即使没有现成的数据
# 3 楼答案
你的
copyFile
方法的根本问题是:这是一个问题,因为
in.available()
返回当前可以从输入流读取的字节数,而不阻塞。如果数据的消费者“赶上”生产者,那可能是零字节,即使你还没有到达流的末尾:对于套接字,如果远程服务器或网络运行缓慢,或者网络中出现“故障”,则可能会发生这种情况
对于管道,如果管道另一端的程序不能足够快地写入数据,就会发生这种情况
对于常规文件(或文件共享上的文件),这种情况可能会发生。文件系统预读无法在缓存中保留足够的数据。(文件的实际行为取决于操作系统和文件系统类型。做出假设是不明智的…)
如果发生这种情况,您可能会错误地认为它已到达终点,并关闭流。。。在复制整个流之前
如果要“手动”复制流,正确的编写方法如下:
注:
我们不使用
available()
来决定阅读多少。我们最多读取8192字节的块。(这个数字可能会更大,但缓冲区过大也会带来负面影响。)这不需要使用缓冲流。我们正在做我们自己的(简单的)缓冲
我们需要确保文件已经关闭。使用资源进行尝试是最好的方法(从Java7开始)。资源(
in
和out
)将自动关闭。(收盘时会导致冲水。)也可以使用
Channel
和ByteBuffer
,这可能更快但是,如果要将一个文件复制到一个文件中,那么Java8
Files.copy(...)
将更简单、更高效(可能是最高效的)。所有的复制都是在幕后进行的,因此可以合理地假设它将以最佳方式进行(对于Java)在Java 9中,您还可以选择使用
InputStream.transferTo(...)
,它利用特殊的I/O系统调用,在将数据从一个“文件描述符”传输到另一个“文件描述符”时,减少内存到内存的复制# 4 楼答案
您正在使用
in.available()
在到达文件末尾之前,它可以返回0如果你想使用你的循环
当in关闭或耗尽时,它将返回-1
不过,你可以使用一些更新的方法
或者直接使用Files选项
# 5 楼答案
在我看来,要以字节形式读取文件,请遵循以下选项:-
1-你可以一个字节一个字节地读
2-可以声明一个具有特定大小(例如64)的字节数组来读取字节
3-另一个简单且有保证的解决方案,您可以使用
java.nio.file
类来复制、创建和删除文件或目录。例:以下代码仅用于检查总和
如果要检查文件的总和,可以使用
DigestInputStream
和MessageDigest
包中的java.security
类。例: