位元組流 字元流 和 轉換流
位元組流
位元組流 又稱 萬能流 不但可以讀寫文字,還可以讀寫圖片 音訊 視訊
使用位元組流進行 檔案的複製
需要對異常進行處理 且計算複製時間
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(讀檔案)緩衝位元組輸入流
通過檔案位元組輸入流進行讀取 一個位元組一個位元組的讀 讀進緩衝流的陣列中