## Java編程那些事兒86——文件操作之File類使用
陳躍峰
出自:[http://blog.csdn.net/mailbomb](http://blog.csdn.net/mailbomb)
### 11.3 I/O類使用
由于在IO操作中,需要使用的數據源有很多,作為一個IO技術的初學者,從讀寫文件開始學習IO技術是一個比較好的選擇。因為文件是一種常見的數據源,而且讀寫文件也是程序員進行IO編程的一個基本能力。本章IO類的使用就從讀寫文件開始。
### 11.3.1 文件操作
文件(File)是最常見的數據源之一,在程序中經常需要將數據存儲到文件中,例如圖片文件、聲音文件等數據文件,也經常需要根據需要從指定的文件中進行數據的讀取。當然,在實際使用時,文件都包含一個的格式,這個格式需要程序員根據需要進行設計,讀取已有的文件時也需要熟悉對應的文件格式,才能把數據從文件中正確的讀取出來。
文件的存儲介質有很多,例如硬盤、光盤和U盤等,由于IO類設計時,從數據源轉換為流對象的操作由API實現了,所以存儲介質的不同對于程序員來說是透明的,和實際編寫代碼無關。
#### 11.3.1.1 文件的概念
文件是計算機中一種基本的數據存儲形式,在實際存儲數據時,如果對于數據的讀寫速度要求不是很高,存儲的數據量不是很大時,使用文件作為一種持久數據存儲的方式是比較好的選擇。
存儲在文件內部的數據和內存中的數據不同,存儲在文件中的數據是一種“持久存儲”,也就是當程序退出或計算機關機以后,數據還是存在的,而內存內部的數據在程序退出或計算機關機以后,數據就丟失了。
在不同的存儲介質中,文件中的數據都是以一定的順序依次存儲起來,在實際讀取時由硬件以及操作系統完成對于數據的控制,保證程序讀取到的數據和存儲的順序保持一致。
每個文件以一個文件路徑和文件名稱進行表示,在需要訪問該文件的時,只需要知道該文件的路徑以及文件的全名即可。在不同的操作系統環境下,文件路徑的表示形式是不一樣的,例如在Windows操作系統中一般的表示形式為C:/windows/system,而Unix上的表示形式為/user/my。所以如果需要讓Java程序能夠在不同的操作系統下運行,書寫文件路徑時還需要比較注意。
##### 11.3.1.1.1 絕對路徑和相對路徑
絕對路徑是指書寫文件的完整路徑,例如d:/java/Hello.java,該路徑中包含文件的完整路徑d:/java以及文件的全名Hello.java。使用該路徑可以唯一的找到一個文件,不會產生歧義。但是使用絕對路徑在表示文件時,受到的限制很大,且不能在不同的操作系統下運行,因為不同操作系統下絕對路徑的表達形式存在不同。
相對路徑是指書寫文件的部分路徑,例如/test/Hello.java,該路徑中只包含文件的部分路徑/test和文件的全名Hello.java,部分路徑是指當前路徑下的子路徑,例如當前程序在d:/abc下運行,則該文件的完整路徑就是d:/abc/test。使用這種形式,可以更加通用的代表文件的位置,使得文件路徑產生一定的靈活性。
在Eclipse項目中運行程序時,當前路徑是項目的根目錄,例如工作空間存儲在d:/javaproject,當前項目名稱是Test,則當前路徑是:d:/javaproject/Test。在控制臺下面運行程序時,當前路徑是class文件所在的目錄,如果class文件包含包名,則以該class文件最頂層的包名作為當前路徑。
另外在Java語言的代碼內部書寫文件路徑時,需要注意大小寫,大小寫需要保持一致,路徑中的文件夾名稱區分大小寫。由于’/’是Java語言中的特殊字符,所以在代碼內部書寫文件路徑時,例如代表“c:/test/java/Hello.java”時,需要書寫成“c://test//java//Hello.java”或“c:/test/java/Hello.java”,這些都需要在代碼中注意。
##### 11.3.1.1.2 文件名稱
文件名稱一般采用“文件名.后綴名”的形式進行命名,其中“文件名”用來表示文件的作用,而使用后綴名來表示文件的類型,這是當前操作系統中常見的一種形式,例如“readme.txt”文件,其中readme代表該文件時說明文件,而txt后綴名代表文件時文本文件類型,在操作系統中,還會自動將特定格式的后綴名和對應的程序關聯,在雙擊該文件時使用特定的程序打開。
其實在文件名稱只是一個標示,和實際存儲的文件內容沒有必然的聯系,只是使用這種方式方便文件的使用。在程序中需要存儲數據時,如果自己設計了特定的文件格式,則可以自定義文件的后綴名,來標示自己的文件類型。
和文件路徑一樣,在Java代碼內部書寫文件名稱時也區分大小寫,文件名稱的大小寫必須和操作系統中的大小寫保持一致。
另外,在書寫文件名稱時不要忘記書寫文件的后綴名。
##### 11.3.1.2 File類
為了很方便的代表文件的概念,以及存儲一些對于文件的基本操作,在java.io包中設計了一個專門的類——File類。
在File類中包含了大部分和文件操作的功能方法,該類的對象可以代表一個具體的文件或文件夾,所以以前曾有人建議將該類的類名修改成FilePath,因為該類也可以代表一個文件夾,更準確的說是可以代表一個文件路徑。
下面介紹一下File類的基本使用。
1、File對象代表文件路徑
File類的對象可以代表一個具體的文件路徑,在實際代表時,可以使用絕對路徑也可以使用相對路徑。
下面是創建的文件對象示例。
public File(String pathname)
該示例中使用一個文件路徑表示一個File類的對象,例如:
File f1 = new File(“d://test//1.txt”);
File f2 = new File(“1.txt”);
File f3 = new File(“e://abc”);
這里的f1和f2對象分別代表一個文件,f1是絕對路徑,而f2是相對路徑,f3則代表一個文件夾,文件夾也是文件路徑的一種。
public File(String parent, String child)
也可以使用父路徑和子路徑結合,實現代表文件路徑,例如:
File f4 = new File(“d://test//”,”1.txt”);
這樣代表的文件路徑是:d:/test/1.txt。
2、File類常用方法
File類中包含了很多獲得文件或文件夾屬性的方法,使用起來比較方便,下面將常見的方法介紹如下:
a、createNewFile方法
public boolean createNewFile() throws IOException
該方法的作用是創建指定的文件。該方法只能用于創建文件,不能用于創建文件夾,且文件路徑中包含的文件夾必須存在。
b、delect方法
public boolean delete()
該方法的作用是刪除當前文件或文件夾。如果刪除的是文件夾,則該文件夾必須為空。如果需要刪除一個非空的文件夾,則需要首先刪除該文件夾內部的每個文件和文件夾,然后在可以刪除,這個需要書寫一定的邏輯代碼實現。
c、exists方法
public boolean exists()
該方法的作用是判斷當前文件或文件夾是否存在。
d、getAbsolutePath方法
public String getAbsolutePath()
該方法的作用是獲得當前文件或文件夾的絕對路徑。例如c:/test/1.t則返回c:/test/1.t。
e、getName方法
public String getName()
該方法的作用是獲得當前文件或文件夾的名稱。例如c:/test/1.t,則返回1.t。
f、getParent方法
public String getParent()
該方法的作用是獲得當前路徑中的父路徑。例如c:/test/1.t則返回c:/test。
g、isDirectory方法
public boolean isDirectory()
該方法的作用是判斷當前File對象是否是目錄。
h、isFile方法
public boolean isFile()
該方法的作用是判斷當前File對象是否是文件。
i、length方法
public long length()
該方法的作用是返回文件存儲時占用的字節數。該數值獲得的是文件的實際大小,而不是文件在存儲時占用的空間數。
j、list方法
public String[] list()
該方法的作用是返回當前文件夾下所有的文件名和文件夾名稱。說明,該名稱不是絕對路徑。
k、listFiles方法
public File[] listFiles()
該方法的作用是返回當前文件夾下所有的文件對象。
l、mkdir方法
public boolean mkdir()
該方法的作用是創建當前文件文件夾,而不創建該路徑中的其它文件夾。假設d盤下只有一個test文件夾,則創建d:/test/abc文件夾則成功,如果創建d:/a/b文件夾則創建失敗,因為該路徑中d:/a文件夾不存在。如果創建成功則返回true,否則返回false。
m、mkdirs方法
public boolean mkdirs()
該方法的作用是創建文件夾,如果當前路徑中包含的父目錄不存在時,也會自動根據需要創建。
n、renameTo方法
public boolean renameTo(File dest)
該方法的作用是修改文件名。在修改文件名時不能改變文件路徑,如果該路徑下已有該文件,則會修改失敗。
o、setReadOnly方法
public boolean setReadOnly()
該方法的作用是設置當前文件或文件夾為只讀。
3、File類基本示例
以上各方法實現的測試代碼如下:
~~~
import java.io.File;
/**
?* File類使用示例
?*/
public class FileDemo {
???????? public static void main(String[] args) {
?????????????????? //創建File對象
?????????????????? File f1 = new File("d://test");
?????????????????? File f2 = new File("1.txt");
?????????????????? File f3 = new File("e://file.txt");
?????????????????? File f4 = new File("d://","1.txt");
?????????????????? //創建文件
?????????????????? try{
??????????????????????????? boolean b = f3.createNewFile();
?????????????????? }catch(Exception e){
??????????????????????????? e.printStackTrace();
?????????????????? }
?????????????????? //判斷文件是否存在
?????????????????? System.out.println(f4.exists());
?????????????????? //獲得文件的絕對路徑
?????????????????? System.out.println(f3.getAbsolutePath());
?????????????????? //獲得文件名
?????????????????? System.out.println(f3.getName());
?????????????????? //獲得父路徑
?????????????????? System.out.println(f3.getParent());
?????????????????? //判斷是否是目錄
?????????????????? System.out.println(f1.isDirectory());
?????????????????? //判斷是否是文件
?????????????????? System.out.println(f3.isFile());
?????????????????? //獲得文件長度
?????????????????? System.out.println(f3.length());
?????????????????? //獲得當前文件夾下所有文件和文件夾名稱
?????????????????? String[] s = f1.list();
?????????????????? for(int i = 0;i < s.length;i++){
??????????????????????????? System.out.println(s[i]);
?????????????????? }
?????????????????? //獲得文件對象
?????????????????? File[] f5 = f1.listFiles();
?????????????????? for(int i = 0;i < f5.length;i++){
??????????????????????????? System.out.println(f5[i]);
?????????????????? }
?????????????????? //創建文件夾
?????????????????? File f6 = new File("e://test//abc");
?????????????????? boolean b1 = f6.mkdir();
?????????????????? System.out.println(b1);
?????????????????? b1 = f6.mkdirs();
?????????????????? System.out.println(b1);
?????????????????? //修改文件名
?????????????????? File f7 = new File("e://a.txt");
?????????????????? boolean b2 = f3.renameTo(f7);
?????????????????? System.out.println(b2);
?????????????????? //設置文件為只讀
?????????????????? f7.setReadOnly();?????????????
???????? }
}
~~~
4、File類綜合示例
下面以兩個示例演示File類的綜合使用。第一個示例是顯示某個文件夾下的所有文件和文件夾,原理是輸出當前名稱,然后判斷當前File對象是文件還是文件夾,如果則獲得該文件夾下的所有子文件和子文件夾,并遞歸調用該方法實現。第二個示例是刪除某個文件夾下的所有文件和文件夾,原理是判斷是否是文件,如果是文件則直接刪除,如果是文件夾,則獲得該文件夾下所有的子文件和子文件夾,然后遞歸調用該方法處理所有子文件和子文件夾,然后將空文件夾刪除。則測試時謹慎使用第二個方法,以免刪除自己有用的數據文件。示例代碼如下:
~~~
import java.io.File;
/**
?* 文件綜合使用示例
?*/
public class AdvanceFileDemo {
???????? public static void main(String[] args) {
?????????????????? File f = new File("e://Book");
?????????????????? printAllFile(f);
?????????????????? File f1 = new File("e://test");
?????????????????? deleteAll(f1);
???????? }
????????
???????? /**
???????? ?* 打印f路徑下所有的文件和文件夾
???????? ?* @param f 文件對象
???????? ?*/
???????? public static void printAllFile(File f){
?????????????????? //打印當前文件名
?????????????????? System.out.println(f.getName());
?????????????????? //是否是文件夾
?????????????????? if(f.isDirectory()){
??????????????????????????? //獲得該文件夾下所有子文件和子文件夾
??????????????????????????? File[] f1 = f.listFiles();
??????????????????????????? //循環處理每個對象
??????????????????????????? int len = f1.length;
??????????????????????????? for(int i = 0;i < len;i++){
???????????????????????????????????? //遞歸調用,處理每個文件對象
???????????????????????????????????? printAllFile(f1[i]);
??????????????????????????? }
?????????????????? }
???????? }
????????
???????? /**
???????? ?* 刪除對象f下的所有文件和文件夾
???????? ?* @param f 文件路徑
???????? ?*/
???????? public static void deleteAll(File f){
?????????????????? //文件
?????????????????? if(f.isFile()){
??????????????????????????? f.delete();
?????????????????? }else{ //文件夾
??????????????????????????? //獲得當前文件夾下的所有子文件和子文件夾
??????????????????????????? File f1[] = f.listFiles();
??????????????????????????? //循環處理每個對象
??????????????????????????? int len = f1.length;
??????????????????????????? for(int i = 0;i < len;i++){
???????????????????????????????????? //遞歸調用,處理每個文件對象
???????????????????????????????????? deleteAll(f1[i]);
??????????????????????????? }
??????????????????????????? //刪除當前文件夾
??????????????????????????? f.delete();
?????????????????? }
???????? }
}
~~~
關于File類的使用就介紹這么多,其它的方法和使用時需要注意的問題還需要多進行練習和實際使用。
- 前言
- (1)序言
- (2)程序設計是什么?
- (3)你適合學習程序設計嗎?
- (4)如何學好程序設計?
- (5)程序設計介紹小結
- (6)計算機軟件基本概念
- (7)進制的概念
- (8)計算機內部的數據表達
- (9)網絡編程基礎
- (10)Java語言簡介
- (11)JDK的獲得、安裝和配置
- (12)第一個HelloWorld程序
- (13)Eclipse基本使用
- (14)Eclipse基礎使用進階
- (15)如何學好Java語法
- (16)代碼框架、關鍵字和標識符
- (17)基本數據類型
- (18)變量和常量
- (19)數據類型轉換
- (20)空白、語句結束和注釋
- (21)算術運算符
- (22)比較運算符
- (23)邏輯運算符
- (24)賦值運算符
- (25)位運算符
- (26)移位運算符
- (27)其它運算符
- (28)運算符優先級
- (29)表達式
- (30)流程控制基礎
- (31)if語句語法(1)
- (32)if語句語法(2)
- (33)if語句語法(3)
- (34)switch語句語法
- (35)while語句語法
- (36)do-while語句語法
- (37)for語句語法
- (38)break和continue語句
- (39)流程控制綜合示例1
- (40)流程控制綜合示例2
- (41)流程控制綜合示例3
- (42)流程控制綜合練習
- (43)數組概述
- (44)數組基礎語法
- (45)數組使用示例1
- (46)數組使用示例2
- (47)數組使用示例3
- (48)多維數組基礎
- (49)多維數組使用示例1
- (50)多維數組使用示例2
- (51)多維數組練習
- (52)方法聲明
- (53)方法聲明示例
- (54)方法調用
- (55)方法重載和參數傳遞
- (56)方法練習
- (57)面向對象基礎
- (58)類(一)
- (59)類(二)
- (60)對象
- (61)面向對象設計方法和面向對象特性(一)
- (62)繼承(二)
- (63)多態性
- (64)訪問控制符、修飾符和其它關鍵字
- (65)static修飾符
- (66)final修飾符
- (67)this和super
- (68)抽象類和接口(一)
- (69)抽象類和接口(二)
- (70)抽象類和接口(三)
- (71)內部類簡介
- (72)包的概念
- (73)JDK文檔使用
- (74)java.lang包介紹1
- (75)String類使用
- (76)StringBuffer類和System類
- (77)包裝類
- (78)時間和日期處理
- (79)Random隨機處理
- (80)集合框架簡述
- (81)異常處理概述
- (82)異常處理語法1
- (83)異常處理語法2
- (84)IO簡介
- (85)IO類體系
- (86)文件操作之File類使用
- (87)文件操作之讀取文件
- (88)文件操作之寫文件
- (89)讀取控制臺輸入
- (90)裝飾流使用1
- (91)裝飾流使用2
- (92)IO使用注意問題
- (93)多線程基礎
- (94)多線程實現方式1
- (95)多線程實現方式2
- (96)多線程使用示例1
- (97)多線程使用示例2
- (98)多線程問題及處理1
- (99)多線程問題及處理2
- (100)多線程問題及處理3
- (101)網絡編程概述
- (102)網絡編程技術1
- (103)網絡編程技術2
- (104)網絡編程技術3
- (105)網絡編程技術4
- (106)網絡編程技術5
- (107)網絡協議概念
- (108)網絡編程示例1
- (109)網絡編程示例2
- (110)網絡編程小結