哈嘍,大家好~我是保護小周?,本期為大家?guī)淼氖?Java 文件操作,理解文件的概念以及,常用的操作文件的類和方法, FileInputStream 類 和 FileOutputStream? , PrintWriter? and Scnner,? Reader and?Wirter?確定不來看看嘛~
更多精彩敬請期待:保護小周? *★,°*:.☆( ̄▽ ̄)/$:*.°★* ‘
一、文件的基本概念
1.1 為什么使用文件
在我們程序中輸入的數(shù)據(jù)一般會隨著 main() (主線程)—— 進程的結束而清空,這是因為此時的數(shù)據(jù)是存放在內存中的,程序結束,內存回收,等我們下次再次運行程序的時候又需要重新輸入數(shù)據(jù),如果我們想要將數(shù)據(jù)持續(xù)化存儲,就必須依托于第三方介質,依托于硬盤,依托于數(shù)據(jù)庫等等Windows中對硬盤中信息的管理和使用是以文件為單位的,Windows系統(tǒng)中推行萬物皆文件的模式,這樣對整體數(shù)據(jù)的存儲、管理就有了一個統(tǒng)一的規(guī)范,降低了管理的復雜度。
1.2 什么是文件
文件可以認為是操作系統(tǒng)使用、管理數(shù)據(jù)的基本單位,是硬盤存儲和管理數(shù)據(jù)的基本單位,我們想要某些相關聯(lián)的數(shù)據(jù)作為一個獨立的整體的進行保存,這個獨立的整體就可以認為是一個文件。
百度百科:
文件后綴名也叫文件的擴展名,是用來表示某種文件所采用的機制。文件擴展名是加在主文件名后面的,用“.”分隔。不同的軟件要求不同的文件格式,后綴名可以幫助用戶了解文件是應該使用哪種軟件打開文件。
在程序設計中從文件功能的角度分析有兩種文件:程序文件,數(shù)據(jù)文件。
程序文件:包括我們編寫的目標源文件(. java, . C), 目標文件 (windows環(huán)境后綴為 .obj), 可執(zhí)行文件(windows環(huán)境后綴為 . exe)。我們的 . java 文件經過編譯后得到一個 .class 文件,由Java JVM 解析文件。
數(shù)據(jù)文件:文件的內容不一定是程序,還可以是程序運行中讀寫的數(shù)據(jù),例如程序運行時需要從內存(CPU 只能直接對內存的數(shù)據(jù)進行處理,所以要處理的數(shù)據(jù)會先從第三方介質:硬盤等讀取到內存)中讀取數(shù)據(jù)進行處理,將處理后的數(shù)據(jù)又寫回第三方介質,那么這個過程中讀取和寫入數(shù)據(jù)的源頭就可以稱之為數(shù)據(jù)文件。
根據(jù)數(shù)據(jù)的類型可以將文件劃分為 文本文件 和 二進制文件
文本文件:是指以ASCII字符集方式(也稱文本方式)存儲的文件,依托于某種字符集來識別,C語言中使用的是ASCll 編碼,所以一個 char 類型只占 一個字節(jié), 例如: 大寫字符 A? 的ASCll 編碼 0110 0001??(65),Java 中使用的是 Unicode?字符集 一個char 類型兩個字節(jié),可以用來描述更多的字符,也包括中文,Unicode?字符集兼容 Utf -8 字符集,utf- 8 兼容 ASCll 字符集??但是 utf- 8 使用三個字節(jié)描述中文。
二進制文件(binary):二進制文件是按機器(即電腦)能夠閱讀的格式(只有0和1)進行存儲的文件,所有文件都是以二進制的形式存儲,文本文件不同是,它可以使用字符集來解析二進制,二進制文件反正操作系統(tǒng)能解析,正常人都是看不懂的,如果使用某種字符集解析(utf-8)大概率也是無法成功的,編碼的規(guī)則不同,自然就無法顯示,即使顯示了字符,也是偶然適配了字符,是沒有意義的。
以下是一個二進制文件使用 utf-8 字符集解析的信息,沒有意義,但是系統(tǒng)可是識別出信息。
?小正方塊就是無法被字符集識別統(tǒng)一顯示的信息。
1.3 文件的組織
伴隨著文件越來越多,就需要一種管理文件的機制,在 Windows 系統(tǒng)中采用樹型結構來組織管理文件夾。文件除了有數(shù)據(jù)內容之外,還有文件本身的一個信息,例如:文件名、文件類型、文件大小,文件路徑、文件源地址,我們把這一塊這信息稱之文件的 “元信息”。
每一個文件夾對應硬盤上一塊存儲空間,它提供了指向對應空間的地址——子文件,可以把文件夾看作是一顆樹的 Node 節(jié)點,節(jié)點中可以保存另一個節(jié)點或者是文本文件,二進制文件等等(實際上存儲的是文件的元信息)。
文件夾是計算機術語也稱之為 “目錄” 是用來組織和管理磁盤文件的一種數(shù)據(jù)結構。
1.4?文件路徑(Path)
熟悉電腦的朋友應該,Windows 不允許在同一文件下有相同類型并同名的文件。
文件命名規(guī)則:
(1)文件名最長可以使用255個字符。
(2)可以使用擴展名,擴展名用來表示文件類型,也可以使用多間隔符的擴展名。如 txt.jpg.exe是一個合法的文件名,但其文件類型由最后一個擴展名決定。
(3)文件名中允許使用空格,但不允許使用下列字符(英文輸入法狀態(tài)):< > / \ | : " * ?
(4)windows系統(tǒng)對文件名中字母的大小寫在顯示時有不同,但在使用時不區(qū)分大小寫。
如何在文件管理系統(tǒng)中定位我們的唯一的文件?Windows 中不同文件夾中允許已使用的文件名,如果我們需要對文件精確定位,就需要使用文件路徑了。
所謂文件路徑就是從樹形結構的角度來看,從根節(jié)點開始,逐漸向子節(jié)點延申,直到找到目標文件,那么找到該文件的所經過的節(jié)點,就稱之為文件路徑,從根節(jié)點開始掃描這種描述方式也被稱之為文件的 “絕對路徑”。
舉個例子:D:\JAVA\JDK\bin\jave.exe 這是一個絕對路徑
除了使用絕對路徑定位文件,還有一種相對路徑的方式,相對表示根據(jù)當前文件為根節(jié)點直至目標文件的路徑,相對路徑的表示方式也是我們常用的,缺點是文件路徑不過精確,有時候會識別不到文件。
" .?" 符號在相對路徑中是一個特殊符號,表示當前目錄
" .. " 符號也是特殊符號,表示當前目錄中的上級目錄
在相對路徑的情況下要描述當前目錄的上上級目錄,或者級別更高的目錄時,可以使用 “..\ ..\ ..\ ” 的形式,每一個 " ../ " 表示上一個目錄。
在絕對路徑中可以理解為以 “此電腦” 為根目錄。
這一切的大前提都是建立在 Windows 操作系統(tǒng)的情況下,在其他操作系統(tǒng)的環(huán)境中可能會有所差異。
二、Java 中的文件操作
Java 中通過 java. io 包中的 File 類來對一個文件(包括目錄)進行抽象的描述,F(xiàn)ile 對象是硬盤上的一個文件的“抽象”表示,為什么這么說呢,文件是存儲來硬盤上的(第三方介質)的,直接通過代碼操作硬盤,怕是不太友好,于是就在內存中創(chuàng)建一個文件對應的對象,然后我們通過操作內存中的對象,就可以間接的操作硬盤中的文件了。
2.1 File 類解析
我們從 File 類中常見的屬性、構造方法和方法及其使用這幾個方面來講述。
2.1.1 構造方法
??2.1.2 方法
2.2 常用方法演示
2.2.1 文件屬性?
// 文件的屬性
public static void main(String[] args) throws IOException {
File file = new File("hello_world.txt"); // 使用相對路徑
//file.createNewFile();
System.out.println(file.exists()); // 判斷文件是否存在
System.out.println(file.isDirectory()); // 判斷file 對象是否是一個目錄
System.out.println(file.isFile()); // 判斷對象是否是一個普通文件
System.out.println(file.createNewFile()); // 根據(jù)file 對象自動創(chuàng)建一個空文件,成功創(chuàng)建后返回 true
System.out.println(file.exists()); // 判斷文件是否存在
System.out.println(file.isDirectory());
System.out.println(file.isFile());
System.out.println(file.createNewFile()); // 文件如果存在返回 false
}
?2.2.2 文件路徑顯示
public static void main(String[] args) throws IOException {
File file = new File("..\\hello-world.txt"); // 代碼中要使用 \ 要使用轉意字符
System.out.println(file.getParent()); // 返回對象的父目錄文件路徑
System.out.println(file.getName()); //返回對象的純文本名稱
System.out.println(file.getPath()); // 返回對象的文件路徑
System.out.println(file.getAbsolutePath()); // 返回對象的絕對路徑
System.out.println(file.getCanonicalFile()); // 返回對象的修飾過的絕對路徑
}
2.2.3? 文件的刪除
public static void main(String[] args) throws IOException {
File file = new File("some-file.txt");
System.out.println(file.exists()); // 判斷文件是否存在
System.out.println(file.createNewFile()); // 根據(jù)file 對象自動創(chuàng)建一個空文件,成功創(chuàng)建后返回 true
System.out.println(file.exists()); // 判斷文件是否存在
System.out.println(file.delete()); // 刪除這個文件,刪除成功返回 true
System.out.println(file.exists());
file.deleteOnExit();// 標注這個文件將被刪除,刪除動作會到 JVM 運行結束時才會進行
}
2.2.4? 創(chuàng)建目錄?
public static void main(String[] args) {
File dir = new File("some-dir");
System.out.println(dir.isDirectory()); // 判斷對象是否是一個目錄
System.out.println(dir.isFile());// 判斷對象是一個普通的文件
System.out.println(dir.mkdir());// 創(chuàng)建file 對象的目錄
System.out.println(dir.isDirectory());
System.out.println(dir.isFile());
dir.mkdirs();// 可以創(chuàng)建中間目錄, mkdir 只能創(chuàng)建單極目錄
}
?2.2.5? 文件的重命名
運行結果博主已經驗證,helloWorld,被創(chuàng)建博主手動向文件中添加了數(shù)據(jù),最后再運行一次,renameTo() 方法,helloWorld 就替換掉成 helloWorld2 其中的數(shù)據(jù)沒有丟失,重命名成功?。?/p>
?三、Java 操作文件內容
第三個模塊涉及的是文件內容的讀寫操作,學習向指定文件中寫入數(shù)據(jù),從指定文件中讀取數(shù)據(jù)。
Java 標準庫提供了一組類專門用于對文件進行讀寫操作。
針對文本文件,提供了一組類,面向?“字符流” 操作,經典代表: Reader, Writer ,讀寫的基本單位是字符。
針對二進制文件,提供了一組類,面向 “字節(jié)流” 操作,經典代表: InputStream, OutputStream . 讀寫的基本單位是字節(jié)。
?3.1 文件緩沖區(qū)
先給大家補充一下 文件怎樣寫入信息或讀出信息,當給文件寫入數(shù)據(jù)時,最先應該在輸出緩沖區(qū),等緩沖區(qū)滿了再輸出到磁盤保存,當從文件里讀取信息時,數(shù)據(jù)應先到達輸入緩沖區(qū),然后再給到程序對應的數(shù)據(jù)類型變量等。
?3.2?InputStream 抽象類
InputStream 提供的抽象方法
InputStream 只是一個抽象類,關于 InputStream 的實現(xiàn)類有很多,基本上可以認為不同的輸入設備都對應有一個?InputStream類的實現(xiàn)類,這里我們從文件中讀取數(shù)據(jù),可以使用 FileInputStream 類。
FileInputStream 構造方法
使用:先準備一個 hello.txt 文件,向文件內部填充一些內容:
// InputStream 字節(jié)文件讀取
public static void main(String[] args) throws IOException {
try(InputStream file = new FileInputStream("hello.txt")) {
byte[] buf = new byte[1024]; // 數(shù)組長度自定義,不可擴容
while (true) {
int data = file.read(buf);
if(data == -1) { // 表示文件已經全部讀完
break;
}
//1. 每次讀取 3 字節(jié)進行 utf-8 解碼,得到中文字符,utf-8 字符集一個漢字三個字節(jié)
//2. 利用 String 的構造方法完成
//3. data統(tǒng)計的是字節(jié)數(shù)
for (int i = 0; i < data; i += 3) {
String str = new String(buf, i, 3, "utf-8");
System.out.printf("%s", str);// java 保留了C語言的打印機制
}
}
}
}
字節(jié)流讀取數(shù)據(jù),我們想讀到漢字的話巧妙的利用了 String 類的構造方法,將指定區(qū)間內(3個字節(jié))的數(shù)據(jù)按照 utf- 8 編碼集轉換成字符。
3.3?Scanner 進行字符讀取
上文 InputStream 針對字符進行字節(jié)流讀取很不方便,還要轉換,所以我們可以使用 Scanner 類將字節(jié)流讀取,包裝成 “字符流”,自動的轉換~~
?使用:先準備一個 hello.txt 文件,向文件內部填充一些內容:
// 利用 Scanner 進行字符讀取
public static void main(String[] args) throws IOException{
try(InputStream data = new FileInputStream("hello.txt")) {
try(Scanner in = new Scanner(data, "utf-8") ) {
while (in.hasNext()) {
String str = in.next();
System.out.println(str);
}
}
}
}
?因為 str = in.next 遇到空格會換行,所以 world! 再第二行打印。
3.4?OutputStream 抽象類
InputStream 提供的抽象方法
OutputStream 也只是一個抽象類,關于 OutputStream 的實現(xiàn)類有很多,這里我們往文件中寫入數(shù)據(jù),可以使用 FileOutputStream 類,面向字節(jié)流。
?使用 write() 方法向文件中寫入數(shù)據(jù)
?注意:博主的文件流資源會隨著進程(main)的結束而結束,所以并沒有手動的調用 close() 。
3.5 PrintWirter??進行字符寫入
使用字節(jié)流 向文件中 “寫” 數(shù)據(jù)總歸是不方便的,所以可以使用 PrintWirter 將字節(jié)流數(shù)據(jù)包裝成指定字符集的數(shù)據(jù)來完成輸出。
PrintWriter 類中提供了我們熟悉的 print(),??println(), printf ()方法。
PrintWriter 類是基于 Reader 類實現(xiàn)的,關于 Reader 類稍后再講。
// PrintWriter 字符寫數(shù)據(jù)
public static void main(String[] args) throws IOException {
try(OutputStream data = new FileOutputStream("output.txt")) {
try(OutputStreamWriter os = new OutputStreamWriter(data, "utf-8")) {
// 如果想要使得每次寫入的數(shù)據(jù)不被覆蓋可以向構造方法中添加 true
try(PrintWriter writer = new PrintWriter(os,true)) {
writer.println("我是第一行");
writer.printf("%d:我是第二行 \n", 1 + 2);
writer.print("我是第三行");
}
}
}
}
?避免二次寫入文件被覆蓋:
PrintWriter writer = new PrintWriter(os,true)
這一組文件操作類,InputStream 和 OutputStream 面向字節(jié)流操作文件,?read() 和 write() 也可以一次讀寫多個字節(jié),使用 byte[] 數(shù)組來表示,read() 方法會盡可能的 byte[] 數(shù)組填滿,如果讀到文件末尾,返回 -1 , writer() 方法會把 byte[] 數(shù)組中所有的數(shù)據(jù)都寫入文件。?
3.6? Reader 類字符讀取
// Reader 類 read 方法 以字符的形式讀取
public static void main(String[] args) {
try(Reader reader = new FileReader("hello.txt")) {
while (true) {
int c = reader.read();
if(c == -1) {
break;
}
char ch = (char)c;
System.out.print(ch);
}
reader.close(); //釋放資源
} catch (IOException e) {
e.printStackTrace();
}
}
?3.7 Writer?類字符寫入
// Writer 類 writer 方法 以字符的形式寫入
public static void main(String[] args) {
try(Writer writer = new FileWriter("output3.txt",true) ){ // true文件不覆蓋寫
String str = "我的老哥";
writer.write(str);
} catch (IOException e) {
e.printStackTrace();
}
}
以上一組 Reader 和 Writer 類,構造方法打開文件,寫入時文件不存在會自動的創(chuàng)建一個文件。
read() 方法來讀,一次讀取一個 char 或者?char[]
write() 方法來寫,一次寫入一個 char 或者 char[] 或者 String
close()關閉資源
到這里,Java的文件操作 IO 流博主已經分享完了,希望對大家有所幫助,如有不妥之處歡迎批評指正。
本期收錄于博主的專欄——JavaEE,適用于編程初學者,感興趣的朋友們可以訂閱,查看其它“JavaEE基礎知識”。
感謝每一個觀看本篇文章的朋友,更多精彩敬請期待:保護小周? *★,°*:.☆( ̄▽ ̄)/$:*.°★*?文章來源:http://www.zghlxwxcb.cn/news/detail-414480.html
遇見你,所有的星星都落在我的頭上……文章來源地址http://www.zghlxwxcb.cn/news/detail-414480.html
到了這里,關于【Java文件操作】手把手教你拿捏IO 流的文章就介紹完了。如果您還想了解更多內容,請在右上角搜索TOY模板網以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網!