1. 程式人生 > >位元組流 字元流 和 轉換流

位元組流 字元流 和 轉換流

位元組流

位元組流 又稱 萬能流 不但可以讀寫文字,還可以讀寫圖片 音訊 視訊

使用位元組流進行 檔案的複製

需要對異常進行處理  且計算複製時間

long start = System.currentTimeMillis();
	// 被讀檔案
	File file1 = new File("/Users/lanou/Desktop/lna/抽獎系統案例.pdf");
	// 寫入檔案
	File file2 = new File("/Users/lanou/Desktop/lna/抽獎.pdf");
	FileInputStream fis = null;
	FileOutputStream fos = null;
        try {
		fis = new FileInputStream(file1);
		fos = new FileOutputStream(file2);
		// 讀寫
		int num = 0;
		while ((num = fis.read()) != -1) {
			// 寫
			fos.write(num);	
		}
	} catch (FileNotFoundException e) {
		throw new RuntimeException("檔案找不到");
	} catch (IOException e) {
		throw new RuntimeException("讀寫失敗");
	}
	finally {
		// (進行流關閉) 先關哪個都行(讀寫完畢)
		if (fis != null) {
			try {
				fis.close();
			} catch (IOException e) {
				throw new RuntimeException("關閉失敗");
			} finally {
				if (fos != null) {
					try {
						fos.close();
					} catch (IOException e) {
						throw new RuntimeException("關閉失敗");
					}
				}
			}
		}
	}
	// 結束事件
	long stop = System.currentTimeMillis();
	System.out.println(stop - start);
檔案的續寫
File file = new File("/Users/lanou/Desktop/lna/xuxie.txt");
		// 利用構造方法的引數進行續寫(布林引數)
		// mac 換行\n
		// windows \r\n
		FileOutputStream fos = new FileOutputStream(file,true);
		fos.write("wanglong\n".getBytes());
		fos.write("nihao\n".getBytes());
		fos.close();

將一個資料夾 複製到另一個資料夾下

需要進行 遞迴  遍歷

引數

1.原始檔(要被複制的檔案) src

2.目標檔案(複製到哪個資料夾下) dest



public static void copyDir(File src,File dest) throws IOException {
		// 去目標資料夾下 建立一個資料夾出來
		// 新資料夾的名字 是原始檔的名字
		// 路徑是 目標檔案的路徑
		File newFile = new File(dest, src.getName());
		newFile.mkdir();
		// 遍歷 src
		File[] files = src.listFiles();
		for (File subfile : files) {
			if (subfile.isFile()) {
				// 是檔案 複製(進行讀寫)
				// 讀寫
				FileInputStream fis = new FileInputStream(subfile);
				// 建立一個要寫入的檔案(拼接檔案路徑和檔名字)
				File tempFile = new File(newFile,subfile.getName());
				FileOutputStream fos = new FileOutputStream(tempFile);
				// 讀
				int num = 0;
				byte[] b = new byte[1024];
				while ((num=fis.read(b)) != -1) {
					// 寫
					fos.write(b,0,num);
				}
				fis.close();
				fos.close();
			} else {
				// 資料夾就遍歷
				copyDir(subfile, newFile);
				
			}
		}
		
	}

將一個資料夾下的所有txt檔案 複製到

另一個資料夾下並且儲存為.java檔案

需要用到過濾器

// 過濾器
class getTxt implements FileFilter {

	@Override
	public boolean accept(File pathname) {
		if (pathname.isDirectory()) {
			return true;
		}
		return pathname.getName().endsWith("txt");
	}	
}

主要實現方法

public static void copyTxt(File src,File dest) throws IOException {
		// 遍歷原始檔
		//File newFile = new File(dest, src.getName());
		File[] files = src.listFiles(new getTxt());
		for (File subFile : files) {
			if (subFile.isFile()) {
				FileInputStream fis = new FileInputStream(subFile);
				// 構建寫的路徑
				String name = subFile.getName();
				String[] split = name.split("\\.");
				// 構建寫入的檔案
				File temp = new File(dest, split[0]+".java");
				FileOutputStream fos = new FileOutputStream(temp);  // 建立寫的輸出流
				// 讀
				int len = 0;
				byte[] b = new byte[1024];
				while ((len = fis.read(b)) != -1) {
					fos.write(b, 0, len);
				}
				fis.close();
				fos.close();
						
			} else {
				// 繼續遍歷
				copyTxt(subFile, dest);
			}
		}
	}

測試

public static void main(String[] args) throws IOException {
		File file1 = new File("/Users/lanou/Desktop/lna");
		File file2 = new File("/Users/lanou/Desktop/haha");
		copyTxt(file1, file2);	
	}

技巧: 找準讀寫檔案的路徑 就一路暢通


字元流

基本的編碼格式

 Mac 預設使用utf-8格式(通用編碼格式)

一箇中文字元 佔3個位元組

 Windows 預設使用的是GBK格式(簡體中文格式)

一箇中文字元 佔2個位元組

Writer(寫檔案) 字元輸出流

Reader(讀檔案) 字元輸入流

這兩個類 是所有字元流的父類(抽象類)

public static void main(String[] args) throws IOException {
		// 建立一個檔案字元輸出流
		File file = new File("/Users/lanou/Desktop/lna/dongdong.txt");
		FileWriter fw = new FileWriter(file);
		// 寫
		fw.write(65);
		// 重新整理
		// 相當於 寫入的時候有一個緩衝區
		// 寫的字元 實際上是 先寫入到緩衝區
		// 重新整理時 才會將寫的字元全部寫入到檔案中
		// 建議: 寫一次重新整理一次
		fw.flush();
		
		// 利用字元陣列寫入
		char[] c = {'x','w','t','m'};
		fw.write(c);
		fw.flush();
		fw.write("\n");
		// 利用字串寫入
		fw.write("人生若只如初見\n");
		fw.write("何事秋風悲畫扇\n");
		
		// 關閉流資源
		// 關閉流資源之前 會自動重新整理緩衝區
		fw.close();
	}

字元流的兩種讀取方式

File file = new File("/Users/lanou/Desktop/lna/dongdong.txt");
	FileReader fr = new FileReader(file);
	// 單個字元讀
	/*
	int num = 0;
	while ((num = fr.read()) != -1) {
		System.out.print((char)num);
	}
	*/
	// 利用緩衝陣列讀
	char[] c = new char[1024];
	int len = 0;  // 有效個數
	while ((len = fr.read(c)) != -1) {
		// 字元陣列 轉 字串
		System.out.println(new String(c, 0, len));
	}
	fr.close();

通過字元流 複製檔案

注意: 字元流只支援讀寫文件類

public static void main(String[] args) throws IOException {
		// 被讀檔案
		File file1 =new File("/Users/lanou/Desktop/lna/dongdong.txt");
		// 寫入檔案
		File file2 = new File("/Users/lanou/Desktop/lna/binbin.txt");
		FileReader fr = null;
		FileWriter fw = null;
		try {
			fr = new FileReader(file1);
			fw = new FileWriter(file2);
			// 讀寫
//			int num = 0;
//			while ((num = fr.read()) != -1) {
//				fw.write(num);
//			}
			int len = 0;
			char[] c = new char[1024];
			while ((len = fr.read(c)) != -1) {
				fw.write(c, 0, len);
				// 重新整理
				fw.flush();
			}
			
		} catch (FileNotFoundException e) {
			throw new RuntimeException("檔案找不到");
		} catch (IOException e) {
			throw new RuntimeException("讀寫失敗");
		}
		finally {
			if (fr != null) {
				try {
					fr.close();
				} catch (IOException e) {
					throw new RuntimeException("關閉失敗");
				} finally {
					if (fw != null) {
						try {
							fw.close();
						} catch (IOException e) {
							throw new RuntimeException("關閉失敗");
						}
					}
				}
			}
		}
		
	}

轉換流

OutputStreamWriter(字元流通向位元組流的橋樑)

1.程式中寫入字元時 先使用轉換流 根據轉換流想查詢的碼錶格式 去查詢

2.如果查的是GBK格式 那麼一箇中文字元

就查到了兩個位元組的 位元組編碼

3.這個位元組最後給到了 構建轉換流時 傳入的位元組流

4.通過這個位元組流 按位元組寫入到檔案中

  轉換流: 可以查詢對應編碼表

轉換流可以根據你想要的編碼格式 進行讀寫

讀寫時 可以設定編碼格式

構造方法(不傳編碼格式 預設使用的系統的編碼格式)

 1.需要一個位元組輸出流

 2.編碼格式的名字(utf-8 , gbk不區分大小寫)

InputStreamReader(讀取檔案 位元組流通向字元流的橋樑)

1.按位元組讀取檔案 將位元組編碼給到轉換流

2.如果是utf-8的 需要3個位元組

3.使用字元流讀取到程式中

// 按GBK格式寫入檔案
	public static void getGBK() throws IOException {
		FileOutputStream fos = new FileOutputStream("/Users/lanou/Desktop/lna/GBK.txt");
		OutputStreamWriter osw = new OutputStreamWriter(fos, "GBK");
		osw.write("哈嘍");
		osw.close();
	}
// 按預設UTF8格式讀檔案
	public static void readUTF8() throws IOException {
		// 建立一個位元組輸入流
		FileInputStream fis = new FileInputStream("/Users/lanou/Desktop/lna/UTF8.txt");
		InputStreamReader isr = new InputStreamReader(fis);
		int len = 0;
		while ((len = isr.read()) != -1) {
			System.out.println((char)len);
		}
	}

緩衝流(高效流)

內部自帶了一個緩衝區(位元組陣列)

BufferedOutputStream(寫檔案) 緩衝位元組輸出流

從程式中一個一個的寫入緩衝陣列中 通過位元組輸出流寫到檔案中

BufferedInputStream(讀檔案)緩衝位元組輸入流

通過檔案位元組輸入流進行讀取 一個位元組一個位元組的讀 讀進緩衝流的陣列中