我编写了一个只读取文件内容并将其写入新副本的小程序。这与文本文件完美配合,但对于PNG和视频文件,它无法正确创建文件(图像全黑或视频无法播放)。我知道有些API可以用一行复制文件,但我很想知道为什么这不起作用。这是代码:
import java.io.*;
public class CopyFile
{
public static void main(String[] args) throws Exception
{
File file = new File("test.mp4");
File copy = new File("copy.mp4");
InputStreamReader input = new InputStreamReader(new FileInputStream(file));
OutputStreamWriter out = new OutputStreamWriter(new FileOutputStream(copy));
System.out.println(input.ready());
while(input.ready())
{
int i = input.read();
//System.out.print( (char) ( (byte) i));
out.write(i);
}
input.close();
out.flush();
out.close();
}
}
答案 0 :(得分:4)
Reader
和Writer
用于读取字符流(即文本)。图片和视频是二进制数据,而不是文本,如果您通过字符流传递它们可能会损坏。这是因为,根据字符集,字节和字符之间不一定存在可逆映射。如果解释为字符,则某些字节序列是乱码,然后将乱码写回文件。
使用您直接打开的InputStream
和OutputStream
,而不是将其整理为Reader
和Writer
,它将正常运行。这些是字节流,可以处理任何类型的数据。
如,
InputStream input = new FileInputStream(file);
OutputStream out = new FileOutputStream(copy);
P.S。这仍然会很慢。您可以将流包装在BufferedInputStream
和BufferedOutputStream
中以获得提高性能的简单方法,尽管单行复制API可能仍然会更快。
答案 1 :(得分:4)
Reader
和Writer
。使用InputStream
和OutputStream.
ready(),
或者,对于Sotirios的好处,available()
。它们都不是流结束的有效测试。它们都关心输入是否可以在没有阻塞的情况下读取,这根本不是一回事。见Javadoc。read()
返回-1,您仍然将其复制到输出。在Java中复制流的规范方法如下:
while ((count = in.read(buffer)) > 0)
{
out.write(buffer, 0, count);
}
其中count
是int,
而buffer
是任何大小为零的byte[]
,通常为8192.