99.Java中IO流_字节流_文件拷贝

字节流文件拷贝

1.1.   字节输入输出流综合使用

通过字节输出流向文件中写入一些信息,并使用字节输入流把文件中的信息显示到控制台上。

public class IoTest3 {
    public static void main(String[] args) throws IOException {
        String path = "c:\\b.txt";
        String content = "hello java";

        writeFile(path, content);

        readFile(path);
    }

    public static void writeFile(String path, String content)
            throws IOException {
        // 打开文件输出流
        FileOutputStream fos = new FileOutputStream(path);
        byte[] buffer = content.getBytes();
        // 向文件中写入内容
        fos.write(buffer);
        // 关闭流
        fos.close();

    }

    public static void readFile(String path) throws IOException {
        FileInputStream fis = new FileInputStream(path);
        byte[] byt = new byte[1024];
        int len = 0;
        while ((len = fis.read(byt)) != -1) {
            System.out.println(new String(byt, 0, len));
        }
        // 关闭流
        fos.close();

    }
}

注意输出流的细节:

   这个输出流显然只适合小数据的写入,如果有大数据想要写入,我们的byte数组,该如何定义?

上述案例中我们将输入流和输出流进行和综合使用,如果尝试进输出流换成文本文件就可以实现文件的拷贝了.

什么是文件拷贝?很显然,先开一个输入流,将文件加载到流中,再开一个输出流,将流中数据写到文件中。就实现了文件的拷贝。

分析:
第一步:需要打开输入流和输出流
第二步:读取数据并写出数据
第三步:关闭流
public class IoTest3 {

    public static void main(String[] args) throws IOException {

        String srcPath = "c:\\a.txt";
        String destPath = "d:\\a.txt";
        copyFile(srcPath, destPath);
    }

    public static void copyFile(String srcPath, String destPath)
            throws IOException {

    }

}

1.2.   字节流拷贝文件实现1

读一个字节写一个字节read 和write

public class IoTest3 {

    public static void main(String[] args) throws IOException {

        String srcPath = "c:\\a.txt";
        String destPath = "d:\\a.txt";
        copyFile(srcPath, destPath);
    }

    public static void copyFile(String srcPath, String destPath)
            throws IOException {
        // 打开输入流,输出流
        FileInputStream fis = new FileInputStream(srcPath);
        FileOutputStream fos = new FileOutputStream(destPath);

        // 读取和写入信息
        int len = 0;
        while ((len = fis.read()) != -1) {
            fos.write(len);
        }

        // 关闭流
        fis.close();
        fos.close();
    }

}

 

文本文件在计算机中是以二进制形式存在的,可以通过io流来拷贝,那么图片能不能拷贝呢?视频呢?音频呢?

public class IoTest3 {

    public static void main(String[] args) throws IOException {

        String srcPath = "c:\\秋.jpg";
        String destPath = "d:\\秋.jpg";
        copyFile(srcPath, destPath);
    }

    public static void copyFile(String srcPath, String destPath)
            throws IOException {
        // 打开输入流,输出流
        FileInputStream fis = new FileInputStream(srcPath);
        FileOutputStream fos = new FileOutputStream(destPath);

        // 读取和写入信息
        int len = 0;
        while ((len = fis.read()) != -1) {
            fos.write(len);
        }

        // 关闭流
        fis.close();
        fos.close();
    }

}

测试统统通过,所以字节流可以操作所有的文件。只是发现程序很慢,需要很长时间。特别是拷贝音频和视频文件时。

为什么?因为每次读一个字节再写一个字节效率很低。很显然这样效率低下的操作不是我们想要的。有没有更快更好的方法呢,是否可以使用缓冲区来提高程序的效率呢。

 

1.3.   字节流拷贝文件实现2;

使用字节数组作为缓冲区

public static void copyFile2(String srcPath, String destPath)
            throws IOException {
        // 打开输入流,输出流
        FileInputStream fis = new FileInputStream(srcPath);
        FileOutputStream fos = new FileOutputStream(destPath);

        // 读取和写入信息
        int len = 0;

        // 使用字节数组,当做缓冲区
        byte[] byt = new byte[1024];
        while ((len = fis.read(byt)) != -1) {
            fos.write(byt);
        }

        // 关闭流
        fis.close();
        fos.close();
    }

问题1: 使用缓冲(字节数组)拷贝数据,拷贝后的文件大于源文件.

测试该方法,拷贝文本文件,仔细观察发现和源文件不太一致。

打开文件发现拷贝后的文件和拷贝前的源文件不同,拷贝后的文件要比源文件多一些内容问题就在于我们使用的容器,这个容器我们是重复使用的,新的数据会覆盖掉老的数据,显然最后一次读文件的时候,容器并没有装满,出现了新老数据并存的情况。

所以最后一次把容器中数据写入到文件中就出现了问题。

如何避免?使用FileOutputStream 的write(byte[] b, int off, int len)

b 是容器,off是从数组的什么位置开始,len是获取的个数,容器用了多少就写出多少。

public static void copyFile2(String srcPath, String destPath)
            throws IOException {
        // 打开输入流,输出流
        FileInputStream fis = new FileInputStream(srcPath);
        FileOutputStream fos = new FileOutputStream(destPath);

        // 读取和写入信息
        int len = 0;

        // 使用字节数组,当做缓冲区
        byte[] byt = new byte[1024];
        while ((len = fis.read(byt)) != -1) {
            fos.write(byt, 0, len);
        }

        // 关闭流
        fis.close();
        fos.close();
    }

使用缓冲拷贝视频,可以根据拷贝的需求调整数组的大小,一般是1024的整数倍。发现使用缓冲后效率大大提高。

posted @ 2020-09-07 02:50  nohert  阅读(97)  评论(0编辑  收藏  举报