java中的IO流

本文轉自我的博客缚柏,您可以閱讀原文.

File類

概覽

創(chuàng)建一個代表一個文件或者文件夾對象朦促,也就是你要操作的目標。

// 創(chuàng)建一個文件對象(不管是不是真實存在)
File file = new File("F:\\a.txt"); // Linux里面是一個正斜杠(windows也是支持的)
// 判斷文件對象是否存在
file.exists();
// 獲取系統(tǒng)的目錄分隔符
File.separator();

構造方法

// 指定文件或文件夾洪己,創(chuàng)建文件對象
File(String pathname);
// 將路徑拆開來(應用場景:先要操作父文件對象屡贺,再操作子文件)
File(File parent, String child);
// 沒太多意義蠢棱,純粹拆開路徑
File(String parent, String child);

注意:使用相對路徑時,當前路徑指的是項目根目錄甩栈。

File類中常用方法

創(chuàng)建

File file = new File("F:\\a.txt");
File dir = new File("F:\\a");
// 基于文件對象創(chuàng)建一個文件(會拋出異常泻仙,返回Boolean)
file.createNewFile();
// 基于文件對象創(chuàng)建一個單級文件夾
dir.mkdir();
// 創(chuàng)建一個多級文件夾
dir.mkdirs();
// 重命名(包含剪切)
file.renemeTo(destFile);

刪除

// 刪除文件或空文件夾
delete();
// 在虛擬機終止時,刪除此抽象路徑下的文件或目錄量没,保證程序異常時創(chuàng)建的臨時文件也可以刪除
deleteOnExit()

判斷

exists();
isFile();
isDirectory();
isHidden();
isAbsolute(); // 判斷該路徑是否為絕對路徑

獲取

getName();
getPath();
getAbsolutePath();
// 獲取文件大杏褡(字節(jié)數(shù)),如果文件不存在或者是文件夾則返回0L
length();
getParent();
lastModified();
// 列出系統(tǒng)根目錄
static File[] listRoots();
// 返回指定目錄中的子文件或子目錄
list();
// 返回指定目錄中符合過濾條件的子文件或子目錄
list(Filename filter);
// 列出指定目錄下的文件或目錄對象(File實例)
listFiles();
// 返回指定目錄下符合過濾條件的子文件或子目錄
listFiles(Filename filter);

實例

場景:分開列出目錄中所有子文件名與子目錄名允蜈。

public static viod listAllFilesAndDirs(String path) {
  File dir = new File(path);
  File[] name = dir.listFiles();
  List<File> fileList = new ArrayList<File>();
  List<File> dirList = new ArrayList<File>();
  for(int i = 0; i < name.length; i++) {
    File file = names[i];
    if(file.isFile) {
      fileList.add(file);
    }else if(file.isDirectory) {
      dirList.add(file);
    }
  }
  System.out.println("子文件:");
  for(int i = 0; i < fileList.size(); i++) {
    System.out.println("\t" + fileList[i].getName());
  }
  System.out.println("子目錄:");
  for(int i = 0; i < dirList.size(); i++) {
    System.out.println("\t" + dirList[i].getName());
  }
}

字節(jié)流

上面我們已經(jīng)知道File對象封裝的是文件或者路徑屬性冤吨,但是不包含向(從)文件讀(寫)數(shù)據(jù)的方法,此時就該是IO流粉墨登場的時候了饶套。

輸入流

read()

這種方式料率底下漩蟆,不推薦使用。

/* 一次讀取一個字節(jié)妓蛮,讀到文末返回-1 */
private viod showContent(String path) throws IOException {
  // 打開流管道
  FileInputStream fis = new FileInputStream(path);
  int len;
  while(len = fis.read() != -1) {
    System.out.println((char)len);
  }
  fis.close();
}

read(byte[] b)

使用read()的時候怠李,流需要讀一次就處理一次。read(byte[] b)可以將讀到的數(shù)據(jù)裝入字節(jié)數(shù)組中蛤克,一次性地操作數(shù)組捺癞,可以提高效率。
read()就類似你從井里一次舀一杯水送到房間里給別人喝构挤;read(byte[] b)就相當于你從井里一次舀一杯水先放到桶子里髓介,等舀滿一桶水再將這桶水運到房間里給別人喝。

private viod showContent(String path) throws IOException {
  FileInputStream fis = new FileInputStream(path);
  byte[] byt = new byte[1024];
  int len = 0;
  while((len = fis.read(byt))! = -1) {
    // 字節(jié)數(shù)組里面存的是二進制數(shù)據(jù)筋现,要將之解析出來需要借助字符串的構造方法
    System.out.println(new String(byt, 0, len));
  }
}

read(byte[] b, int off, int len)

其實就是把數(shù)組的一部分當作流的容器來使用唐础。告訴容器從什么地方開始裝多少。

輸出流

輸出流基本就是用來寫入數(shù)據(jù)的矾飞。

write(int b)

write(int b)一次寫出一個字節(jié)一膨。
雖然write(int b)接收的是int類型參數(shù),但是write(int b)的常規(guī)協(xié)定是:向輸入流寫入一個字節(jié)洒沦,要寫入的字節(jié)是參數(shù)的低八位豹绪,高24個高位將將被忽略。

write(byte[] b)

write(byte[] b)相比write(int b)效率更高申眼。原因就不多說了瞒津。
我們只需要將字符串轉化為字節(jié)數(shù)組蝉衣,然后通過該方法就可以一次寫入多個字節(jié)。
創(chuàng)建輸出字節(jié)流對象時巷蚪,如果不想覆蓋已存在內容买乃,而是追加內容只需如此這般:new FileOutputStream(path, true)

private static void writeTxtFile(String path) throwss IOException {
  FileOutputStream fos = new FileOutputStream(path);
  byte[] byt = "要插入的數(shù)據(jù)".getBytes();
  fos.write(byt);
  fos.close();
}

字節(jié)流文件拷貝

public static copyFile(String srcPath, String destPath) throwss IOException {
  // 打開輸入輸出流
  FileInputStream fis = new FileInputStream(srcPath);
  FileOutputStream fos = new FileOutputStream(destPath);
  // 讀取和寫入信息
  int len = 0;
  byte[] byt = [1024];
  while((len = fis.read(byt)) != -1) {
    fos.write(byt, 0, length);
  }
  // 關閉流
  fis.close();
  fos.close();
}

字節(jié)流的異常處理

上述例子中,我們使用了拋出異常的方式來處理異常钓辆。但實際上,這樣做是不合適的肴焊。
例如第一個通道關閉出錯會導致第二個通道無法關閉前联。正確的做法是使用try--catch--finelly語句塊來處理異常。

字節(jié)緩沖流

字節(jié)緩沖流內部有一個緩沖區(qū)娶眷,其實內部也是封裝了字節(jié)數(shù)組似嗤,默認的字節(jié)是8192。
緩沖區(qū)輸入流與緩沖區(qū)輸出流要配合使用届宠。首先緩沖區(qū)輸入流會將讀取到的數(shù)據(jù)寫入緩沖區(qū)烁落,當緩沖區(qū)滿時,或者調用flush()方法豌注,緩沖輸出流會將數(shù)據(jù)寫出伤塌。

public static viod copyFile(String srcPath, String destPath) throws IOException {
  // 打開輸入流,輸出流
  FileInputStream fis = new FileInputStream(srcPath);
  FileOutputStream fos = new FileOutputStream(destPath);
  // 使用緩沖流
  BufferedInputStream bis = new BufferedInputStream(fis);
  BufferedOutputStream bos = new BufferedOutputStream(fos);
  // 讀取和寫入信息
  int len = 0;
  while((len = bis.read()) != -1) {
    bos.write(len);
  }
  // 關閉流
  bis.close();
  bos.close();
}

字符流(FileReader & FileWwiter)

字節(jié)流以字節(jié)為單位轧铁,而字符流是以字符為單位每聪。更方便地處理文本文檔。

常見的碼表

計算機不管是存文本文件還是二進制文件本質上都是存的二進制數(shù)據(jù)齿风。如果是文本文件的話药薯,計算機需要一套規(guī)則才能將二進制的數(shù)據(jù)翻譯成我們能看懂的字符。這套規(guī)則就是指的碼表救斑。

  • ASCII:美國標準信息交換碼童本。一個字符占一個字節(jié),用一個字節(jié)的7位可以表示
  • ISO8859-1:拉丁碼表脸候。歐洲碼表穷娱,用一個字節(jié)的8位表示
  • GBG2312: 英文占一個字節(jié),中文占兩個字節(jié)
  • GBK:中國的中文碼表升級纪他,融合了更多的中文文字符號
  • Unicode:國際標準碼規(guī)范鄙煤。所有文字都用兩個字節(jié)來表示(java就是用的這個)
  • UTF-8:英文一個字節(jié),中文三個字節(jié)

Reader

方法

int reader();讀取一個字符茶袒。返回的是讀到的那個字符梯刚。如果讀到流的末尾則返回-1;
int read(char[]);將讀到的字符存入指定的數(shù)組中薪寓,返回的是讀到的字符個數(shù)亡资,也就是往數(shù)組里裝的元素的個數(shù)澜共。讀到流的末尾則返回-1;
close();使用完畢后锥腻,進行資源的釋放嗦董;

public static void readFileByReader(String path) throws  Exception {
  Reader reader = new FileReader(path);
  int len = 0;
  while((len = reader.read()) != -1) {
    System.out.println((char)len);
  }
  reader.close();
}

Writer

write(ch)將一個字符寫入到流中。
write(char[])將一個字符數(shù)組寫入到流中瘦黑。
write(String)將字符串寫入到流中京革。
flush()刷新流,將流中的數(shù)據(jù)刷新到目的地中幸斥,流還存在匹摇。
close()關閉資源。關閉前會先調用flush()甲葬,刷新流中數(shù)據(jù)到目的地廊勃,然后流關閉。

public static void writeToFile(String path) throws Exception {
  // 這里的第二個參數(shù)表示是否為追加
  Write write = new FileWiter(path, true);
  write.write('中');
  write.write("世界".toCharArray());
  write.write("中國");
  // 這里沒有調用flush()是因為close()會調用flush()
  write.close();
}

用字符流拷貝文本文件

public static void copyFile(String path1, String path2) throws Exception {
  Reader reader = new FileReader(path1);
  Writer writer = new FileWiter(path2);
  int ch = -1;
  char[] arr = new char[1024];
  while((ch = reader.reader(arr)) != -1) {
    writer.writer(arr, 0, ch);
  }
  reader.close();
  writer.close();
}

字符流的緩沖區(qū)

緩沖的存在是為了增強流的功能而存在经窖,所以在建立緩沖區(qū)對象時坡垫,先要有流對象存在。
緩沖區(qū)的出現(xiàn)提高了對流的操作效率画侣。原理就是將數(shù)組進行封裝冰悠。

private static void copyFile(File srcFile, File destFile) throws IOException {
  // 創(chuàng)建輸入輸出流
  FileReader fr = new FileReader(srcFile);
  FileWriter fw = new FileWriter(destFile);
  // 創(chuàng)建字符輸出流
  BufferedReader br = new BufferedReader(fr);
  BufferedWriter bw = new BufferedWriter(fw);
  // 拷貝(可以一行一行地讀)
  String line = null;
  while((line = br.readLine()) != null) {
    // 一次寫出一行
    bw.write(line);
    // 刷新緩沖
    bw.flush();
    // 換行,readLine方法默認沒有換行配乱,需要手動換行
    bw.newLine();
  }
  // 關閉流
  br.close();
  bw.close();
}
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末屿脐,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子宪卿,更是在濱河造成了極大的恐慌的诵,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,755評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件佑钾,死亡現(xiàn)場離奇詭異西疤,居然都是意外死亡,警方通過查閱死者的電腦和手機休溶,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,305評論 3 395
  • 文/潘曉璐 我一進店門代赁,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人兽掰,你說我怎么就攤上這事芭碍。” “怎么了孽尽?”我有些...
    開封第一講書人閱讀 165,138評論 0 355
  • 文/不壞的土叔 我叫張陵窖壕,是天一觀的道長。 經(jīng)常有香客問我,道長瞻讽,這世上最難降的妖魔是什么鸳吸? 我笑而不...
    開封第一講書人閱讀 58,791評論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮速勇,結果婚禮上晌砾,老公的妹妹穿的比我還像新娘。我一直安慰自己烦磁,他們只是感情好养匈,可當我...
    茶點故事閱讀 67,794評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著都伪,像睡著了一般乖寒。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上院溺,一...
    開封第一講書人閱讀 51,631評論 1 305
  • 那天,我揣著相機與錄音磅轻,去河邊找鬼珍逸。 笑死,一個胖子當著我的面吹牛聋溜,可吹牛的內容都是我干的谆膳。 我是一名探鬼主播,決...
    沈念sama閱讀 40,362評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼撮躁,長吁一口氣:“原來是場噩夢啊……” “哼漱病!你這毒婦竟也來了?” 一聲冷哼從身側響起把曼,我...
    開封第一講書人閱讀 39,264評論 0 276
  • 序言:老撾萬榮一對情侶失蹤杨帽,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后嗤军,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體注盈,經(jīng)...
    沈念sama閱讀 45,724評論 1 315
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,900評論 3 336
  • 正文 我和宋清朗相戀三年叙赚,在試婚紗的時候發(fā)現(xiàn)自己被綠了老客。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,040評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡震叮,死狀恐怖胧砰,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情苇瓣,我是刑警寧澤尉间,帶...
    沈念sama閱讀 35,742評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響乌妒,放射性物質發(fā)生泄漏汹想。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,364評論 3 330
  • 文/蒙蒙 一撤蚊、第九天 我趴在偏房一處隱蔽的房頂上張望古掏。 院中可真熱鬧,春花似錦侦啸、人聲如沸槽唾。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,944評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽庞萍。三九已至,卻和暖如春忘闻,著一層夾襖步出監(jiān)牢的瞬間钝计,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,060評論 1 270
  • 我被黑心中介騙來泰國打工齐佳, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留私恬,地道東北人。 一個月前我還...
    沈念sama閱讀 48,247評論 3 371
  • 正文 我出身青樓炼吴,卻偏偏與公主長得像本鸣,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子硅蹦,可洞房花燭夜當晚...
    茶點故事閱讀 44,979評論 2 355

推薦閱讀更多精彩內容