字节流文件拷贝
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的整数倍。发现使用缓冲后效率大大提高。