1. 程式人生 > >java使用IO流完成檔案的複製(文字、圖片、視訊)

java使用IO流完成檔案的複製(文字、圖片、視訊)

一、使用位元組流實現

複製檔案中的地址可以是圖片或視訊。

1.基礎版

package com.uwo9.test01;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

public class Test08 {

	public static void main(String[] args) {
		long startTime = System.currentTimeMillis();
		// 被複制的檔案
		File fromFile = new File("E:/Temp/1.jpg");
		// 複製出來的檔案
		File toFile = new File("E:/Temp/2.jpg");
		// 宣告入流
		InputStream is = null;
		//
		OutputStream os=null;
		try {
			is = new FileInputStream(fromFile);//建立輸入流
			os = new FileOutputStream(toFile);// 建立輸出流
			// 逐個位元組讀取
			int content = is.read();
			while (content != -1) {
				// System.out.print((char)content); 控制檯
				// 使用輸出流將讀取到的content寫入檔案
				os.write(content);
				// 重新整理流
				// os.flush();
				content = is.read();
			}
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}finally {
			// 關閉流
			try {
				is.close();
				os.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
			long endTime = System.currentTimeMillis();
			long costTime = endTime - startTime;
			System.out.println("複製檔案完成,耗時:" + costTime + "毫秒");
		}
		
		
	}

}

發現問題:我們發現,上面的方法,可以實現複製功能,但複製的檔案比較大時,複製比較慢

2.第一次優化

我們可以用位元組陣列來做緩衝區,提升效率。

package com.uwo9.test01;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

public class Test08 {

	public static void main(String[] args) {
		long startTime = System.currentTimeMillis();
		// 被複制的檔案
		File fromFile = new File("E:/Temp/1.avi");
		// 複製出來的檔案
		File toFile = new File("E:/Temp/2.avi");
		// 宣告入流
		InputStream is = null;
		//
		OutputStream os = null;
		try {
			is = new FileInputStream(fromFile);// 建立輸入流
			os = new FileOutputStream(toFile);// 建立輸出流
			// 建立用來做緩衝區的位元組陣列
			byte[] array = new byte[512];
			// 將陣列讀取到array中,count記錄的為讀取陣列中位元組數
			int count = is.read(array);
			while (count != -1) {
				// 使用輸出流將讀取到的content寫入檔案
				// os.write(array);
				// 將讀取到的有效資料寫入檔案
				os.write(array, 0, count);
				// 重新整理流
				// os.flush();
				count = is.read(array);
			}
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			// 關閉流
			try {
				is.close();
				os.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
			long endTime = System.currentTimeMillis();
			long costTime = endTime - startTime;
			System.out.println("複製檔案完成,耗時:" + costTime + "毫秒");
		}

	}

}
發現問題:效率提升了,但我們java裡是否有更好的實現方法呢

3.第二次優化

我們可以加入緩衝字元流

節點流與處理流(包裝流):

1.節點流:可以直接從資料來源或目的地讀寫資料。節點流處於IO操作的第一線,所有操作必須通過他們進行。

2.處理流:不能直接連線到資料來源或目的地,是其他流進行封裝。目的是主要是簡化操作和提高效能。處理流可以對其他流進行處理(提高效率或操作靈活性)。

package com.uwo9.test01;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

public class Test08 {

	public static void main(String[] args) {
		long startTime = System.currentTimeMillis();
		File fromFile = new File("E:/Temp/1.avi");
		File toFile = new File("E:/Temp/2.avi");
		InputStream is = null;
		OutputStream os = null;
		BufferedInputStream bis = null;
		BufferedOutputStream bos = null;
		try {
			is = new FileInputStream(fromFile);
			os = new FileOutputStream(toFile);
			// 建立緩衝流
			bis = new BufferedInputStream(is);
			bos = new BufferedOutputStream(os);
			int content = bis.read();
			while (content != -1) {
				// 使用緩衝流寫資料
				bos.write(content);
				// 重新整理
				bos.flush();
				content = bis.read();
			}
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} finally {
			try {
				is.close();
				os.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}

		long endTime = System.currentTimeMillis();
		System.out.println("視訊複製完成,耗時:" + (endTime - startTime) + "毫秒");

	}

}

發現問題:我們還想繼續提升效率

4.第三次優化:

我們可以在緩衝流的基礎上再加位元組陣列來做緩衝區,提升效率

package com.uwo9.test01;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

public class Test08 {

	public static void main(String[] args) {
		long startTime = System.currentTimeMillis();
		File fromFile = new File("E:/Temp/1.avi");
		File toFile = new File("E:/Temp/2.avi");
		InputStream is = null;
		OutputStream os = null;
		BufferedInputStream bis = null;
		BufferedOutputStream bos = null;
		try {
			is = new FileInputStream(fromFile);
			os = new FileOutputStream(toFile);
			// 建立緩衝流
			bis = new BufferedInputStream(is);
			bos = new BufferedOutputStream(os);
			byte[]buffer = new byte[8192];
			int count = bis.read(buffer);
			while(count != -1){
				//使用緩衝流寫資料
				bos.write(buffer,0,count);
				//重新整理
				bos.flush();
				count = bis.read(buffer);
			}
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			try {
				is.close();
				os.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}

		long endTime = System.currentTimeMillis();
		System.out.println("視訊複製完成,耗時:" + (endTime - startTime) + "毫秒");

	}

}

我們會發現,效率再次大大提升。

二、使用字元流

1.基礎版

package com.uwo9.test01;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.Reader;
import java.io.Writer;

public class Test08 {

	public static void main(String[] args) {
		long startTime = System.currentTimeMillis();
		//1.建立檔案物件
		File fromFile = new File("E:/Temp/Test1.java");
		File toFile = new File("E:/Temp/Test2.java");
		//2.建立字元輸入流
		Reader reader=null;
		Writer writer=null;
		try {
			reader = new FileReader(fromFile);
			writer = new FileWriter(toFile);
			//3.迴圈讀取(列印)
			int content = reader.read();
			while(content != -1){
				//將字元寫入檔案
				writer.write(content);
				//繼續讀取
				content = reader.read();
			}
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}finally {
			//4.關閉流
			try {
				reader.close();
				writer.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		long endTime = System.currentTimeMillis();
		System.out.println("複製完成,耗時:"+(endTime-startTime)+"毫秒");
		
		

	}

}

發現問題:我們發現,字元流複製二進位制普通文字型別的檔案沒問題,但讀取圖片、視訊檔案時,會出現丟幀、檔案損壞現象。

2.優化普通二進位制文字檔案方法

我們可以使用包裝流(處理流),及其特有的逐行讀取方法提升效率

package com.uwo9.test01;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.Reader;
import java.io.Writer;

public class Test08 {

	public static void main(String[] args) {
		long startTime = System.currentTimeMillis();
		File fromFile = new File("E:/Temp/Test1.java");
		File toFile = new File("E:/Temp/Test1.java");
		Reader reader = null;
		Writer writer = null;
		BufferedReader br = null;
		BufferedWriter bw = null;
		try {
			reader = new FileReader(fromFile);
			writer = new FileWriter(toFile);
			br = new BufferedReader(reader);
			bw = new BufferedWriter(writer);
			String content = br.readLine();//讀取一行
			while (content != null) {
				bw.write(content);
				// 換行操作
				bw.newLine();
				bw.flush();
				content = br.readLine();
			}
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			try {
				reader.close();
				writer.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}

		long endTime = System.currentTimeMillis();
		System.out.println("檔案複製完成,耗時:" + (endTime - startTime) + "毫秒");

	}

}


FileWriter(File file, boolean append)

FileOutputStream(File file, boolean append)