繁体   English   中英

文件无法使用Java正确复制

[英]Files not copying correctly with Java

我编写了一个只读取文件内容并将其写入新副本的小程序。 这与文本文件完美配合,但对于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();
}

}

ReaderWriter用于读取字符流(即文本)。 图片和视频是二进制数据,而不是文本,如果您通过字符流传递它们可能会损坏。 这是因为,根据字符集,字节和字符之间不一定存在可逆映射。 如果解释为字符,则某些字节序列是乱码,然后将乱码写回文件。

使用您直接打开的InputStreamOutputStream ,而不是将它们包装为Reader and Writer ,它将正常工作。 这些是字节流,可以处理任何类型的数据。

例如,

InputStream input = new FileInputStream(file);
OutputStream out = new FileOutputStream(copy);

PS这仍然会很慢。 您可以将流包装在BufferedInputStreamBufferedOutputStream ,以获得提高性能的简单方法,尽管单行复制API可能仍然会更快。

  1. 除非您知道输入是文本,否则不要使用ReaderWriter 使用InputStreamOutputStream.
  2. 不要使用ready(),或者,对于Sotirios的好处,也available() 它们都不是流结束的有效测试。 它们都关注输入是否可以在没有阻塞的情况下被读取这根本不是一回事。 见Javadoc。
  3. 您没有正确检测到流的结尾。 如果read()返回-1,你仍然将它复制到输出。
  4. 一次复制单个字符或单个字节非常慢。

在Java中复制流的规范方法如下:

while ((count = in.read(buffer)) > 0)
{
    out.write(buffer, 0, count);
}

其中count是一个int,buffer是一个大于零的任何大小的byte[] ,通常是8192。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM