[TOC]
# 文件操作
## 什么是文件
文件是計算機中基本的數據存儲形式,在實際的存儲數據中,如果對數據的讀寫速度要求不高,而且存儲的數據量也不是很大,此時,可以選擇使用文件這種持久化的存儲方式。
所謂**持久化**,就是當程序退出,或者計算機關機以后,數據還是存在的。但是在程序內存中的數據會在程序關閉或計算機退出時丟失。
文件的組成:路徑+文件的全名(文件名和文件后綴)。
關于文件后綴:只是定義了文件的打開方式不一樣,如果更改后綴不會對文件的內部數據產生變化。
在不同的操作系統中,文件的路徑表示形式是不一樣的。
比如:
`windows c:\windows\system\driver.txt`
`Linux /user/my/tomcat/startup.txt`
> 如果程序需要在不同的操作系統中運行,那么如果出現文件路徑相關的設置時,必須要進行操作系統的判斷,特別是windows和Linux關于斜杠的區別。
## 絕對路徑和相對路徑
絕對路徑指文件的完整路徑,例如:c:\hello\hello.java。該路徑包含文件的路徑和文件的文件名即后綴。
使用該路徑可以唯一的找到該文件。但是,在不同的操作系統下,文件的絕對路徑表現形式是不一樣的。這樣就會比較麻煩。
相對路徑是書寫文件的部分路徑:
如下文件結構
~~~
D
└─test
│ a.txt
│
└─A
b.txt
~~~
如使用 `D:\test` 作為基準目錄
* a.txt 相對路徑:a.txt
* b.txt 相對路徑:A\b.txt
如使用D:\text\A作為基準目錄
* a.txt的相對路徑:..\a.txt
* b.txt的相對路徑:b.txt
> 在Java中\是轉義字符,如果要是\進行路徑的描述時,要使用“\\”表示。
> 可以通過System.getProperty("file.separator")的通用方式獲取不同操作系統的文件分隔符(如Linux/windows\)
**相對路徑**
Java 中文件的相對路徑是相對 JVM 的啟動路徑而言的。
表現當前路徑的方式:`.` 、`.\`、 `不使用任何的符號`;
一個點表示當前路徑,兩個點”..”表示上級目錄。
在大部分的應用程序中,我們都會使用相對路徑去構建文件。
通過 `Clazz.class` 獲取類的元數據,然后調用 `Clazz.class.getResource("相對路徑")` 獲取絕對路徑,進行文件創建。
## File 類
為了方便的通過Java對文件進行基本的處理,在 java.io 包中設計了 File 類。
> File只能表現文件本身和目錄(文件中的內容不在File類的管理范疇內)
### 文件常用的操作方法
~~~
public class FileClient1 {
public static void main(String[] args) throws IOException {
}
/**
* 創建一個新文件
* @param path
* @throws IOException
*/
public static void createNewFile(String path) throws IOException {
File file = new File(path);
boolean createFlag = file.createNewFile();
System.out.println(createFlag);
}
/**
* 刪除一個文件
* @param path
* @throws IOException
*/
public static void deleteFile(String path) throws IOException {
File file = new File(path);
boolean delteFlag = file.delete();
// 返回true表示刪除成功 false表示刪除失敗,失敗的原因大部分是文件不存在
System.out.println(delteFlag);
}
/**
* 判斷一個文件后者路徑是否存在
* @param path
*/
public static void existsFile(String path) {
File file = new File(path);
System.out.println(file.exists());
}
/**
* 獲取文件的絕對路徑
* @param path
*/
public static void getAbsolutePath(String path) {
File file = new File(path);
System.out.println(file.getAbsolutePath());
}
/**
* 獲取文件名
* @param path
*/
public static void getFileName(String path) {
File file = new File(path);
System.out.println(file.getName());
}
/**
* 獲取父路徑
*/
public static void getParent(String path) {
File file = new File(path);
System.out.println(file.getParent());
}
/**
* 判斷一個文件對象是否是目錄
*/
public static void isDirectory(String path) {
File file = new File(path);
System.out.println(file.isDirectory());
}
/**
* 判斷一個文件對象是否是文件
* @param path
*/
public static void isFile(String path) {
File file = new File(path);
System.out.println(file.isFile());
}
/**
* 獲取文件目錄下的所有文件和目錄清單
* @param path
*/
public static void list(String path) {
File file = new File(path);
String[] files = file.list();
for (String fileName : files) {
System.out.println(fileName);
}
}
/**
* 獲取文件目錄下的所有文件和目錄清單(文件名)
* @param path
*/
public static void listFiles(String path) {
File file = new File(path);
File[] files = file.listFiles();
for (File fileName : files) {
System.out.println(fileName.getAbsolutePath());
}
}
/**
* 創建目錄
* @param path
*/
public static void mkdir(String path) {
File file = new File(path);
System.out.println(file.mkdir());
}
/**
* 創建目錄(如果父目錄不存在,則創建父目錄)
* @param path
*/
public static void mkdirs(String path) {
File file = new File(path);
System.out.println(file.mkdirs());
}
/**
* 文件重命名
* @param oldFileName
* @param newFileName
*/
public static void renameTo(String oldFileName, String newFileName) {
File oldFile = new File(oldFileName);
File newFile = new File(newFileName);
System.out.println(oldFile.renameTo(newFile));
}
/**
* 設置文件只讀
* @param path
*/
public static void setReadonly(String path) {
File file = new File(path);
System.out.println(file.setReadOnly());
}
}
~~~
### 文件的遞歸讀取和遞歸刪除
遞歸遍歷文件
~~~
public static void main(String[] args) {
printAllFile(new File("D:\\test"));
}
public static void printAllFile(File file) {
String filePath = file.getAbsolutePath();
System.out.println(filePath);
if (file.isDirectory()) {
File[] files = file.listFiles();
for (File lf : files) {
printAllFile(lf);
}
}
}
~~~
遞歸刪除文件
~~~
public static void main(String[] args) {
deleteAllFile(new File("D:\\test"));
}
public static void deleteAllFile(File file) {
if (file.isFile()) {
// 直接刪除文件
file.delete();
} else {
File[] files = file.listFiles();
for (File fl : files) {
deleteAllFile(fl);
}
// 刪除目錄
file.delete();
}
}
~~~
## 文件讀取
文件的類型:字符型文件(簡單立即就是記事本可以打開的文件,比如.java文件)、二進制文件(可以簡單理解為編譯過的文件,如 .class 文件、 .jpg 等圖片文件、 .exe 可執行文件...)
對于文件讀取操作,使用輸入對應的子類:FileInputStream 和 FileReader 實現。
在Java的IO編程中,讀取文件分為:
1. 將文件中的數據轉換為流;
2. 讀取流內部的數據。
其中第一步是系統自動完成的,讀取流內部數據需要程序控制;
在通過輸入流進行編程時,分為3個部分
1. 創建流對象;
2. 讀取流對象內部的數據;
3. 關閉流。
代碼示例
~~~
public static void main(String[] args) {
// 聲明一個流對象
FileInputStream fis = null;
File file = new File("D:\\test1\\a.txt");
try {
// 通過File對象構建一個流對象
fis = new FileInputStream(file);
// 讀取數據,并將讀取的數據存儲在數組中
byte[] data = new byte[(int)file.length()];
// 讀取流中的第一個字節數據
int n = fis.read();
// 讀取的游標位置
int i = 0;
// 判斷是否讀到最后一個字符
while(n != -1) {
data[i] = (byte)n;
i++;
n = fis.read();
}
String rs = new String(data, "GBK");
System.out.println(rs);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
// 關閉流,釋放資源
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
~~~
## 文件寫入
~~~
public static void main(String[] args) {
String s = "Hello,Java!";
// 聲明一個輸出流
FileOutputStream fos = null;
File file = new File("d:\\test1\\a.txt");
try {
// 根據文件創建一個輸出流對象
fos = new FileOutputStream(file);
byte[] data = s.getBytes();
fos.write(data);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally {
try {
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
~~~
## Java中常見的編碼格式
在計算機系統中,ASCII碼是最基礎的編碼格式,8bit存儲一個字節數據,能夠表示的字符范圍為 255。
由于 ASCII 所變現的字符較少,隨后就出現了包括 `ISO-8859-1` 、`GB2312`、`GBK`、`GB18030`、`UTF-16`、`UTF-8` 等編碼格式。
目前在應用開發中,使用 UTF-8 的編碼方式是最常見的,其次為 GBK。
我們在標識符定義中所說的 unicode 字符集就是指的的 UTF 編碼方式。
除了 ASCII 碼是用一個字節表示數據的,其他都是 2-4 個字節表示。
在文件字節流中讀取的 `byte[]` 數據,最后通過 `new String(byte[], charsetName)` 方法構建的對象,第二個參數就是文件的編碼方式。(把一個字節數組轉化為字符串,如果不顯式的指明字節的編碼方式,則用系統默認的編碼方式)。
在控制臺輸入chcp命名可以查詢到系統目前使用的文字編碼方式 936 表示的是 GBK。
~~~
String rs = new String(data, "GBK");
~~~
## 字節流和字符流
字符流其實是字節流的一種特殊表現。
在IO流中,字符流的輸入輸出使用的 Writer/Reader,字節流使用InputStream/OutputStream。
* 輸入流:只能做讀操作
* 輸出流:只能做寫操作
## 使用RandomAccessFile類進行數據的追加
~~~
File file = new File("D:\\work\\Trade\\ws01\\JAVA88-1\\src\\test0613\\a1.txt");
RandomAccessFile raf = new RandomAccessFile(file, "rw");
raf.seek(raf.length());
raf.writeBytes("\r\nend");
raf.close();
~~~
- 前言
- 計算機概論
- 數據庫
- 數據庫介紹
- MySQL的安裝
- SQL
- 表基本操作
- 修改數據語句
- 數據檢索操作
- 多表數據操作
- 表結構設計
- 綜合應用
- JAVA
- JAVA 介紹
- JAVA 運行原理
- JDK 配置
- 類和對象
- 數據類型
- 變量
- 直接量
- 運算符
- 流程控制
- 數組結構
- 面向對象
- 隱藏和封裝
- 深入構造器
- 類的繼承
- 多態
- 包裝類
- final 修飾符
- 抽象類
- 接口
- 集合框架
- 常用類學習
- 異常處理
- 設計模式-單例模式
- JDBC
- JSP&Servlet
- Web應用
- Tomcat
- JSP
- Scriptlet
- Page 指令
- 包含指令
- 跳轉指令
- 用戶注冊實例
- JSP練習
- 內置對象
- Servlet
- 過濾器
- Web分層思想
- EL表達式
- JSTL
- 分頁實現
- AJAX&JSON
- 開發步驟
- 路徑問題
- Log4j
- 電子書城
- 案例分析
- 核心代碼
- Java 高級
- 文件操作
- 泛型
- 類加載機制和反射
- 注解 Annotation
- Mybatis框架
- 框架介紹
- Mybatis簡單實現
- 表基本操作
- 優化配置文件
- 表字段名與實體類屬性名不同的解決方案
- 一對一關聯
- 一對多關聯
- 教學管理
- 學員名錄
- 周測統計
- 2017-10-27
- 2017-11-03
- 2017-11-10
- 2017-11-17
- 課堂作業
- 班會紀要
- 2017-10-24
- 缺勤記錄
- 班級備忘錄
- 違紀統計
- 編程素養
- Day001
- Day002
- Day003
- Day004
- Day005
- Day006
- Day007
- Day008
- Day009
- Day010
- Day011
- Day012
- Day013
- Day014
- Day015
- Day016
- Day017
- Day018
- Day019