IO概述
????????之前寫過的程序蛛株,數(shù)據(jù)都是在內(nèi)存中,一旦程序運(yùn)行結(jié)束育拨,這些數(shù)據(jù)都沒有了谨履,等下次再想使用這些數(shù)據(jù),可是已經(jīng)沒有了至朗。那怎么辦呢屉符?能不能把運(yùn)算完的數(shù)據(jù)都保存下來,下次程序啟動(dòng)的時(shí)候,再把這些數(shù)據(jù)讀出來繼續(xù)使用呢矗钟?其實(shí)要把數(shù)據(jù)持久化存儲(chǔ)唆香,就需要把內(nèi)存中的數(shù)據(jù)存儲(chǔ)到內(nèi)存以外的其他持久化設(shè)備(硬盤、光盤吨艇、U盤等)上
當(dāng)需要把內(nèi)存中的數(shù)據(jù)存儲(chǔ)到持久化設(shè)備上這個(gè)動(dòng)作稱為輸出(寫)Output操作
當(dāng)把持久設(shè)備上的數(shù)據(jù)讀取到內(nèi)存中的這個(gè)動(dòng)作稱為輸入(讀)Input操作
因此我們把這種輸入和輸出動(dòng)作稱為IO操作
IO的分類
Java IO一般包含兩個(gè)部分:
java.io包中堵塞型IO躬它;
java.nio包中的非堵塞型IO,通常稱為NewIO东涡。
????????學(xué)過操作系統(tǒng)的朋友都知道系統(tǒng)運(yùn)行的瓶頸一般在于IO操作冯吓,一般打開某個(gè)IO通道需要大量的時(shí)間,同時(shí)端口中不一定就有足夠的數(shù)據(jù)疮跑,這樣read方法就一直等待讀取此端口的內(nèi)容组贺,從而浪費(fèi)大量的系統(tǒng)資源。有人也許會(huì)提出使用java的多線程技術(shù)白婺铩失尖!但是在當(dāng)前進(jìn)程中創(chuàng)建線程也是要花費(fèi)一定的時(shí)間和系統(tǒng)資源的,因此不一定可取渐苏。Java New IO的非堵塞技術(shù)主要采用了Observer模式掀潮,就是有一個(gè)具體的觀察者和=監(jiān)測IO端口,如果有數(shù)據(jù)進(jìn)入就會(huì)立即通知相應(yīng)的應(yīng)用程序琼富。這樣我們就避免建立多個(gè)線程仪吧,同時(shí)也避免了read等待的時(shí)間。不過本篇主要講述java的堵塞型IO鞠眉,就是我們通常應(yīng)用的那個(gè)包薯鼠。
Java的IO主要包含三個(gè)部分:
流式部分――IO的主體部分;
非流式部分――主要包含一些輔助流式部分的類凡蚜,如:File類人断、RandomAccessFile類和FileDescriptor等類;
文件讀取部分的與安全相關(guān)的類朝蜘,如:SerializablePermission類。以及與本地操作系統(tǒng)相關(guān)的文件系統(tǒng)的類涩金,如:FileSystem類和Win32FileSystem類和WinNTFileSystem類谱醇。
流式部分可以概括為:兩個(gè)對應(yīng)一個(gè)橋梁。
兩個(gè)對應(yīng)指:
字節(jié)流(Byte Stream)和字符流(Char Stream)的對應(yīng)步做;
輸入和輸出的對應(yīng)副渴。一個(gè)橋梁指:從字節(jié)流到字符流的橋梁呵扛。對應(yīng)于輸入和輸出為InputStreamReader和OutputStreamWriter桃犬。
在流的具體類中又可以具體分為:
????????介質(zhì)流(Media Stream或者稱為原始流Raw Stream)――主要指一些基本的流衡楞,他們主要是從具體的介質(zhì)上从撼,如:文件胚嘲、內(nèi)存緩沖區(qū)(Byte數(shù)組、Char數(shù)組古话、StringBuffer對象)等牺氨,讀取數(shù)據(jù);
????????過濾流(Filter Stream)――主要指所有FilterInputStream/FilterOutputStream和FilterReader/FilterWriter的子類草娜,主要是對其包裝的類進(jìn)行某些特定的處理挑胸,如:緩存等。
File類
我們先從file類學(xué)起宰闰,file類是文件和目錄路徑名的抽象表示茬贵。
File類的構(gòu)造函數(shù)
通過構(gòu)造方法創(chuàng)建File對象
/**
* 通過構(gòu)造方法創(chuàng)建File對象
*/
public static void test1() {
? ? // File構(gòu)造函數(shù)演示
? ? String pathName = "e:\\test\\Hello.java";
? ? // 注意:可以封裝不存在文件或者文件夾,變成對象移袍。
? ? File file1 = new File(pathName);
? ? System.out.println("file1 = " + file1);
? ? File file2 = new File("e:\\test", "Hello.java");
? ? System.out.println("file2 = " + file2);
? ? // 將 parent 封裝成 file 對象
? ? File dir = new File("e:\\test");
? ? File file3 = new File(dir, "Hello.java");
? ? System.out.println("file3 = " + file3);
? ? //file1 = e:\test\Hello.java
? ? //file2 = e:\test\Hello.java
? ? //file3 = e:\test\Hello.java
}
File類獲取文件相關(guān)信息
創(chuàng)建完了File對象之后解藻,那么File類中都有如下常用方法,可以獲取文件相關(guān)信息
/**
* File類獲取文件相關(guān)信息
*/
public static void test2() {
? ? // 創(chuàng)建文件對象
? ? File file = new File("Test2.java");
? ? // 獲取文件的絕對路徑葡盗,即全路徑
? ? String absPath = file.getAbsolutePath();
? ? // File中封裝的路徑是什么獲取到的就是什么
? ? String path = file.getPath();
? ? // 獲取文件名稱
? ? String fileName = file.getName();
? ? // 獲取文件大小
? ? long size = file.length();
? ? System.out.println("absPath = " + absPath);
? ? System.out.println("path = " + path);
? ? System.out.println("fileName = " + fileName);
? ? System.out.println("size = " + size);
? ? //absPath = F:\JetBrains\myProject\springboot2-examples\Test2.java
? ? //path = Test2.java
? ? //fileName = Test2.java
? ? //size = 0
}
文件和文件夾的創(chuàng)建與刪除等
/**
* 文件和文件夾的創(chuàng)建與刪除等
*/
public static void test3() throws IOException {
? ? // 對文件或者文件夾進(jìn)行操作
? ? File file = new File("e:\\test3.txt");
? ? // 創(chuàng)建文件螟左,如果文件不存在,創(chuàng)建 true戳粒。 如果文件存在路狮,則不創(chuàng)建 false。 如果路徑錯(cuò)誤蔚约,IOException奄妨。
? ? boolean b1 = file.createNewFile();
? ? System.out.println("b1 = " + b1);
? ? // 刪除文件操作 - 慎用
? ? boolean b2 = file.delete();
? ? System.out.println("b2 = " + b2);
? ? // 判斷文件是否存在
? ? boolean b3 = file.exists();
? ? System.out.println("b3 = " + b3);
? ? // 對目錄操作 創(chuàng)建、刪除苹祟、判斷
? ? File dir = new File("e:\\abc");
? ? // mkdir()創(chuàng)建單個(gè)目錄;? mkdirs()創(chuàng)建多級目錄
? ? boolean b4 = dir.mkdir();
? ? System.out.println("b4 = " + b4);
? ? // 刪除目錄時(shí)砸抛,如果目錄中有文件,無法直接刪除
? ? // 只有將目錄中的內(nèi)容都刪除后树枫,保證該目錄為空直焙。這個(gè)目錄才可以刪除。
? ? boolean b5 = dir.delete();
? ? System.out.println("b5 = " + b5);
? ? // 要判斷是否是文件還是目錄砂轻,必須先判斷存在
? ? File file1 = new File("e:\\hello.txt");
? ? // file1.mkdir();//file1.createNewFile(); // 要判斷是否是文件還是目錄奔誓,先判斷存在。
? ? System.out.println("file1.isFile() = " + file1.isFile());
? ? System.out.println("file1.isDirectory() = " + file1.isDirectory());
? ? //b1 = true
? ? //b2 = true
? ? //b3 = false
? ? //b4 = true
? ? //b5 = true
? ? //file1.isFile() = false
? ? //file1.isDirectory() = false
}
獲取目錄下的所有文件和文件夾
????????文件都存放在目錄(文件夾)中搔涝,那么如何獲取一個(gè)目錄中的所有文件或者目錄中的文件夾呢厨喂?那么我們先想想,一個(gè)目錄中可能有多個(gè)文件或者文件夾庄呈,那么如果File中有功能獲取到一個(gè)目錄中的所有文件和文件夾蜕煌,那么功能得到的結(jié)果要么是數(shù)組,要么是集合诬留。
/**
* 獲取目錄下的所有文件和文件夾
*/
public static void test4() throws IOException {
? ? File dir = new File("e:\\java_code");
? ? File file1 = new File(dir, "aaa");
? ? file1.mkdirs();
? ? File file2 = new File(dir, "a.txt");
? ? file2.createNewFile();
? ? //獲取的是目錄下的當(dāng)前的文件以及文件夾的名稱斜纪。
? ? String[] names = dir.list();
? ? for (String name :
? ? ? ? ? ? names) {
? ? ? ? System.out.println("name = " + name);
? ? }
? ? //獲取目錄下當(dāng)前文件以及文件對象贫母,只要拿到了文件對象,那么就可以獲取其中想要的信息
? ? File[] files = dir.listFiles();
? ? for (File file :
? ? ? ? ? ? files) {
? ? ? ? System.out.println("file = " + file);
? ? }
? ? //name = a.txt
? ? //name = aaa
? ? //file = e:\java_code\a.txt
? ? //file = e:\java_code\aaa
}
文件過濾器
????????通過listFiles()方法盒刚,我們可以獲取到一個(gè)目錄下的所有文件和文件夾腺劣,但能不能對其進(jìn)行過濾呢?比如我們只想要一個(gè)目錄下的指定擴(kuò)展名的文件伪冰,或者包含某些關(guān)鍵字的文件夾呢
????????我們是可以先把一個(gè)目錄下的所有文件和文件夾獲取到誓酒,并遍歷當(dāng)前獲取到所有內(nèi)容,遍歷過程中在進(jìn)行篩選贮聂,但是這個(gè)動(dòng)作有點(diǎn)麻煩靠柑,Java給我們提供相應(yīng)的功能來解決這個(gè)問題
? ? /**
? ? * 文件過濾器
? ? * 獲取擴(kuò)展名為.java所有文件
? ? */
? ? public static void test5() {
? ? ? ? // 創(chuàng)建 File 對象
? ? ? ? File file = new File("e:\\java_code");
? ? ? ? // 獲取指定擴(kuò)展名的文件,由于要對所有文件進(jìn)行擴(kuò)展名篩選,因此調(diào)用方法需要傳遞過濾器
? ? ? ? File[] files = file.listFiles(new MyFileFilter());
? ? ? ? // 遍歷獲取到的所有符合條件的文件
? ? ? ? for (File f :
? ? ? ? ? ? ? ? files) {
? ? ? ? ? ? System.out.println("f = " + f);
? ? ? ? }
? ? ? ? // f = e:\java_code\b.java
? ? }
/**
* 定義類實(shí)現(xiàn)文件名稱FilenameFilter過濾器
*/
class MyFileFilter implements FilenameFilter {
? ? @Override
? ? public boolean accept(File dir, String name) {
? ? ? ? return name.endsWith(".java");
? ? }
}
值得一提的是 我們要注意這個(gè)用法 只能是下一級目錄吓懈,不能說是2級 就比如例子中的 必須要是java_code/下的歼冰,就是說java_code/aaa/下的bbb.java 也是找不到的
遞歸打印所有子目錄中的文件路徑
/**
* 遞歸打印所有子目錄中的文件路徑
*/
public static void test6() {
? ? File file = new File("e:\\java_code");
? ? getFileAll(file);
? ? //file = e:\java_code\a.txt
? ? //file = e:\java_code\aaa\b.java
? ? //file = e:\java_code\b.java
}
public static void getFileAll(File file) {
? ? File[] files = file.listFiles();
? ? // 遍歷當(dāng)前目錄下的所有文件和文件夾
? ? for (File f :
? ? ? ? ? ? files) {
? ? ? ? // 判斷當(dāng)前遍歷到的是否為目錄
? ? ? ? if (f.isDirectory()) {
? ? ? ? ? ? // 是目錄,繼續(xù)獲取這個(gè)目錄下的所有文件和文件夾
? ? ? ? ? ? getFileAll(f);
? ? ? ? } else {
? ? ? ? ? ? // 不是目錄耻警,說明當(dāng)前f就是文件隔嫡,那么就打印出來
? ? ? ? ? ? System.out.println("file = " + f);
? ? ? ? }
? ? }
}
File總結(jié)
File: 文件和目錄路徑名的抽象表示形式
構(gòu)造方法
public File(String pathname) 通過給定的文件或文件夾的路徑,來創(chuàng)建對應(yīng)的File對象
public File(String parent, String child) 通過給定的父文件夾路徑甘穿,與給定的文件名稱或目錄名稱來創(chuàng)建對應(yīng)的File對象
public File(File parent,? String child)通過給定的File對象的目錄路徑腮恩,與給定的文件夾名稱或文件名稱來創(chuàng)建對應(yīng)的File對象
路徑的分類
絕對路徑, 帶盤盤符? E:\\work\\a.txt
相對路徑, 不帶盤符? work\\a.txt 注意: 當(dāng)指定一個(gè)文件路徑的時(shí)候温兼,如果采用的是相對路徑秸滴,默認(rèn)的目錄為 項(xiàng)目的根目錄?
常用方法
public boolean createNewFile()創(chuàng)建文件
返回值為true, 說明創(chuàng)建文件成功
返回值為false募判,說明文件已存在荡含,創(chuàng)建文件失敗
public boolean mkdir() 創(chuàng)建單層文件夾
創(chuàng)建文件夾成功,返回 true
創(chuàng)建文件夾失敗届垫,返回 false
public boolean mkdirs() 創(chuàng)建多層文件夾
public boolean delete()
刪除此抽象路徑名表示的文件或目錄
如果此路徑名表示一個(gè)目錄释液,則該目錄必須為空才能刪除
public boolean isDirectory() 判斷是否為文件夾
public boolean isFile() 判斷是否為文件
public boolean exists() 判斷File對象對應(yīng)的文件或文件夾是否存在
public String getAbsolutePath() 獲取當(dāng)前File的絕對路徑
public String getName() 獲取當(dāng)前File對象的文件或文件夾名稱
public long length() 獲取當(dāng)前File對象的文件或文件夾的大小(字節(jié))
public File[] listFiles() 獲取File所代表目錄中所有文件或文件夾的絕對路徑
Java學(xué)習(xí)視頻
Java基礎(chǔ):
Java300集装处,Java必備優(yōu)質(zhì)視頻_手把手圖解學(xué)習(xí)Java误债,讓學(xué)習(xí)成為一種享受
Java項(xiàng)目:
【Java游戲項(xiàng)目】1小時(shí)教你用Java語言做經(jīng)典掃雷游戲_手把手教你開發(fā)游戲
【Java畢業(yè)設(shè)計(jì)】OA辦公系統(tǒng)項(xiàng)目實(shí)戰(zhàn)_OA員工管理系統(tǒng)項(xiàng)目_java開發(fā)