File與IO基礎
IO流的作用:持久化到磁盤
File類的使用
File類基本概念
- 文件和文件夾都是用File類來表示。
- File類是內存層面的對象,內存中創建出來的File對象不一定有一個真實存在的文件或文件夾,但是磁盤中真實的文件或文件夾必須創建一個對應的File對象才能操作。
- File文件可進行增刪改查,但不能訪問文件本身的內容,需要使用輸入/輸出流來進行訪問。
- File對象一般作為流對象的構造器參數傳入。如
FileInputStream fileInputStream = new FileInputStream(new File("hello.tex"));
File對象的創建
注意:文件夾和文件如果在磁盤中都沒有的話,要分開分別創建文件夾和文件。
構造器
分隔符
示例小結
public class FileTest {
/**
* 文件創建的字符串參數意義
* @throws FileNotFoundException
*/
@Test
public void test1() throws FileNotFoundException {
//windows環境下用\\來作為文件夾分隔符,之所以用\\是因為\是轉義符的意思,所有\\表示不轉義
File fileA1 = new File("F:\\newwork\\roy-practice-metaverse\\hello-io.txt");
//windows環境下也可以像linux環境一樣用/表示
File fileA2 = new File("F:/newwork/roy-practice-metaverse/hello-io.txt");
//Java提供了File.pathSeparator來拼接路徑分隔符,用於讀取不同的系統的路徑分隔符
File fileA3 = new File("F:" + File.pathSeparator + "newwork" + File.pathSeparator + "roy-practice-metaverse" + File.pathSeparator + "hello-io.txt");
//相當於當前module模塊下的hello-io.txt,如果是main方法則是當前工程下的hello-io.txt
File fileR = new File("hello-io.txt");
}
/**
* 文件創建的3種構造器
* @throws FileNotFoundException
*/
@Test
public void test2() throws FileNotFoundException {
//構造器1:File(String pathname)
File file1 = new File("F:/newwork/roy-practice-metaverse/hello-io.txt");
//構造器2:File(String parent, String child)
//child可以是文件或文件夾名稱
File file2 = new File("F:/newwork","roy-practice-metaverse");
//構造器3:File(File parent, String child)
//child可以是文件或文件夾名稱
File file3 = new File(file2,"hello-io.txt");
}
}
File類的常用方法
查詢方法
注意:File類中的查看方法操作不會因為文件或文件夾不存在而報錯,因為還都是內存層面的操作,沒有涉及磁盤文件。
示例小結
/**
* File類的常用方法
* @throws FileNotFoundException
*/
@Test
public void test3() throws FileNotFoundException {
File file1 = new File("hi-io.txt");//文件存在的情況
System.out.println(file1.getAbsolutePath());
System.out.println(file1.getPath());
System.out.println(file1.getName());
System.out.println(file1.getParent());
System.out.println(file1.length());//默認值0
System.out.println(file1.lastModified());//默認值0
System.out.println("------------------------------------");
File file2 = new File("F:/newwork/roy-practice-metaverse/hello-io.txt");
System.out.println(file2.getAbsolutePath());
//這個path的返回值就是我們創建file對象時傳入的參數,參數是絕對路徑就返回絕對路徑,否則就是相對路徑名
System.out.println(file2.getPath());
System.out.println(file2.getName());
System.out.println(file2.getParent());
System.out.println(file2.length());
System.out.println(file2.lastModified());
}
/**
* F:\newwork\roy-practice-metaverse\hi-io.txt
* hi-io.txt
* hi-io.txt
* null
* 0
* 0
* ------------------------------------
* F:\newwork\roy-practice-metaverse\hello-io.txt
* F:\newwork\roy-practice-metaverse\hello-io.txt
* hello-io.txt
* F:\newwork\roy-practice-metaverse
* 0
* 0
*/
/**
* File類的常用方法-文件夾方法
* @throws FileNotFoundException
*/
@Test
public void test4() throws FileNotFoundException {
//文件夾遍歷時該文件夾必須存在,否則NPE
File file1 = new File("F:/newwork/roy-practice-metaverse");
String[] list = file1.list();
for (String name : list) {
System.out.println(name);
}
File[] files = file1.listFiles();
for (File file : files) {
System.out.println(file);
}
//移動文件或者重命名,要保證操作成功,需要 from在磁盤存在,而to不能存在這兩個條件
File from = new File("hello-io.txt");
File to = new File("new-io.txt");
boolean success = from.renameTo(to);
System.out.println(success);
}
/**
* .idea
* hello-io.txt
* pom.xml
* src
* target
* F:\newwork\roy-practice-metaverse\.idea
* F:\newwork\roy-practice-metaverse\hello-io.txt
* F:\newwork\roy-practice-metaverse\pom.xml
* F:\newwork\roy-practice-metaverse\src
* F:\newwork\roy-practice-metaverse\target
* true
*
*
* Process finished with exit code 0
*/
File類的判斷方法
File類的創建刪除方法
示例小結
/**
* File類的判斷功能
*
* @throws FileNotFoundException
*/
@Test
public void test5() throws FileNotFoundException {
File existFile = new File("new-io.txt");
System.out.println(existFile.isDirectory());
System.out.println(existFile.isFile());
System.out.println(existFile.exists());
System.out.println(existFile.canRead());
System.out.println(existFile.canWrite());
System.out.println(existFile.isHidden());
System.out.println("------------------------");
File notExistFile = new File("notExist-new-io.txt");
//當文件不存在的時候,結果是既不是文件夾也不是文件,所有如果有需要可以先判斷是否存在
System.out.println(notExistFile.isDirectory());
System.out.println(notExistFile.isFile());
System.out.println(notExistFile.exists());
System.out.println(notExistFile.canRead());
System.out.println(notExistFile.canWrite());
System.out.println(notExistFile.isHidden());
}
/**
* false
* true
* true
* true
* true
* false
* ------------------------
* false
* false
* false
* false
* false
* false
*/
/**
* File類的創建刪除文件/文件夾
*
* @throws FileNotFoundException
*/
@Test
public void test6() throws IOException {
//創建刪除文件
File file = new File("create-file.txt");
if (!file.exists()) {
boolean flag = file.createNewFile();
if (flag) {
System.out.println("創建文件成功");
}
} else {
boolean delete = file.delete();
if (delete) {
System.out.println("刪除文件成功");
}
}
//創建刪除文件夾
File file2 = new File("create-dir");
if (!file2.exists()) {
boolean flag = file2.mkdir();
if (flag) {
System.out.println("創建文件夾成功");
}
} else {
boolean delete = file2.delete();
if (delete) {
System.out.println("刪除文件夾成功");
}
}
//創建刪除多級文件夾
File file3 = new File("create-dir1/sub-dir1");
if (!file3.exists()) {
//mkdirs可以遞歸創建文件夾,mkdir只能創建一級文件夾,如果有多級則創建不成功
boolean flag = file3.mkdirs();
if (flag) {
System.out.println("創建文件夾成功");
}
} else {
boolean delete = file3.delete();
if (delete) {
System.out.println("刪除文件夾成功");
}
}
//刪除多級文件夾,只能刪除葉子節點的文件或文件夾,不能級聯刪除
//要想刪除成功,被刪除的文件夾下不能有子文件夾或者文件,如果是文件則文件要存在。
// File file4 = new File("create-dir1");
// System.out.println(file4.delete());//false
}
IO流原理及流的分類
基本概念
-
I/O是指Input/Output(輸入流/輸出流)的意思,用來處理設備之間的數據傳輸。
-
輸入輸出流的劃分是個相對的概念,我們在操作選擇輸入輸出流是站在程序或者說內存的角度上看流屬於輸入還是輸出。
-
我們應該站在內存的角度上去看流,讀到內存中要找輸入流,從內存中讀到磁盤或者其他網絡端叫輸出流。
IO流模板四步走
- File類對象創建
- 輸入輸出流的創建
- 讀取/寫入數據操作
- 關閉流資源
IO流的分類
- 數據單位
- 流向
- 角色
IO流體系
節點流和處理流
基本概念
流的選擇
- 對於文本文件(.txt .java .c …),使用字符流處理。
- 對於非文本文件(.doc .ppt .jpg .avi …),(只能)使用位元組流處理。
注意:文本文件操作讀取輸入流後展示(即在內存層面去讀時)時要使用字符流操作,避免會有亂碼的情況。當然如果只是讀取數據並寫入到文件中,則都可以用。而非文本文件即使沒有在內存層面去讀,直接寫入硬盤,也不能用字符流處理,否則文件會打開失敗。
示例小結
字符流
public class FileReaderWriterTest {
/**
* 通過字符輸入流讀取文件數據打印到控制台
*/
@Test
public void test1() {
//注意,一開始寫代碼時可以先拋出異常,等後面整理時再針對性try-catch處理
//1、實例化要操作的文件對象
FileReader fr = null;
try {
//如果讀取的文件不存在會報文件未找到異常
File file = new File("new-io.txt");
//2、創建具體的流
fr = new FileReader(file);
//3、數據的讀入/寫出
//從輸入流中讀取數據的下一個位元組,沒有返回-1
int data;
while ((data = fr.read()) != -1) {
//強轉為字符
System.out.print((char) data);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
//在關閉流時都要先判斷字符輸入流是否不為空
if (fr != null) {
//關閉流
try {
fr.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
/**
* 通過字符輸入流讀取文件數據打印到控制台-加緩充
*/
@Test
public void test2() {
//注意,一開始寫代碼時可以先拋出異常,等後面整理時再針對性try-catch處理
//1、實例化要操作的文件對象
FileReader fr = null;
try {
//如果讀取的文件不存在會報文件未找到異常
File file = new File("new-io.txt");
//2、創建具體的流
fr = new FileReader(file);
//3、數據的讀入/寫出
//從輸入流中讀取數據的下一個位元組,沒有返回-1
int len;
char[] cbuff = new char[1024];
//一次讀取多個可以提供效率,len是每次讀取到cbuff數組中的個數,沒有則返回-1
while ((len = fr.read(cbuff)) != -1) {
//注意長度是len而不是數組cbuff的長度
//接收方式1:
System.out.print(new String(cbuff, 0, len));
//接收方式2:
/*for (int i = 0; i < len; i++) {
System.out.print(cbuff[i]);
}*/
}
} catch (IOException e) {
e.printStackTrace();
} finally {
//在關閉流時都要先判斷字符輸入流是否不為空
if (fr != null) {
//關閉流
try {
fr.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
/**
* 從內存中通過字符輸出流寫文件到硬盤中
* 輸出操作的文件可以不存在,不存在時會自動創建此文件。
* 創建字符輸出流時會有個append參數,默認是false,表示如果文件存在則覆蓋
* 如果設置append參數=true,表示如果文件存在則會追加數據在文件里的末尾。
*/
@Test
public void test3() {
FileWriter fw = null;
try {
//1、實例化要操作的文件對象
File file = new File("out-io.txt");
//2、創建具體的流
//FileOutputStream(File file, boolean append) append=false表示覆蓋,true表示在文件末尾追加
fw = new FileWriter(file);
//3、數據的寫出
//直接寫字符串,\n表示換行符
fw.write("everybody wants to rule the world!\n");
//也可以寫字符數組
fw.write("不是哦,我只是個良民,活着就好!".toCharArray());
} catch (IOException e) {
e.printStackTrace();
} finally {
if (fw != null) {
//4、關閉流資源
try {
fw.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
/**
* 讀取硬盤中的文件到新文件中(複製)-字符流版
*/
@Test
public void test5() {
FileReader fr = null;
FileWriter fw = null;
try {
//1、實例化要操作的讀入/寫出文件對象
File srcFile = new File("new-io.txt");
File destFile = new File("new-io-copy.txt");
//2、創建輸入流和輸出流
fr = new FileReader(srcFile);
fw = new FileWriter(destFile);
//3、數據的讀入和寫出操作
int len;
char[] buff = new char[1024];
while ((len = fr.read(buff)) != -1) {
//注意要讀多少個寫出多少長度len
fw.write(buff, 0, len);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
//4、關閉流資源
if (fw != null) {
try {
fw.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (fr != null) {
try {
fr.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
位元組流
public class FileInOutPutStreamTest {
/**
* 讀取硬盤中的文件到新文件中(複製)-位元組流版
*/
@Test
public void test() {
copyFile("是大臣.jpg", "是大臣-copy.jpg");
}
public void copyFile(String srcPath, String destPath) {
FileInputStream fis = null;
FileOutputStream fos = null;
try {
//1、實例化要操作的讀入/寫出文件對象
File srcFile = new File(srcPath);
File destFile = new File(destPath);
// File srcFile = new File("new-io.txt");
// File destFile = new File("new-io-copy.txt");
//2、創建輸入流和輸出流
fis = new FileInputStream(srcFile);
fos = new FileOutputStream(destFile);
//3、數據的讀入和寫出操作
int len;
byte[] buff = new byte[1024];
while ((len = fis.read(buff)) != -1) {
//注意要讀多少個寫出多少長度len
fos.write(buff, 0, len);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
//4、關閉流資源
if (fos != null) {
try {
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (fis != null) {
try {
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
緩衝流——處理流的一種
處理流就是套接在已有流的基礎上的流。
作用:提高流的讀寫速度。
原因:內部提供了一個默認8K的緩衝區。緩衝區大小我們可以在構造器中指定大小。
示例小結
public class BufferedTest {
/**
* 使用緩存流進行複製
*/
@Test
public void test1() {
//971M耗時1444ms 測試後如果指定的buff緩衝區越大理論上越好,因為順序寫速度更快
long start = System.currentTimeMillis();
BufferedInputStream bis = null;
BufferedOutputStream bos = null;
try {
//1、實例化要操作的讀入/寫出文件對象
File srcFile = new File("E:/mv/[電影天堂www.dygod.com]倩女幽魂3:道道道BD國語中字.rmvb");
File destFile = new File("nxq.rmvb");
//2.1、創建輸入流和輸出流
FileInputStream fis = new FileInputStream(srcFile);
FileOutputStream fos = new FileOutputStream(destFile);
//2.1、創建緩存流
bis = new BufferedInputStream(fis);
bos = new BufferedOutputStream(fos, 8192);//1444ms
// bos = new BufferedOutputStream(fos, 8192 / 2);//1952ms
// bos = new BufferedOutputStream(fos, 8192 * 2);//1202ms
// bos = new BufferedOutputStream(fos, 8192 * 8);//1101ms
//3、數據的讀入和寫出操作
byte[] buffer = new byte[1024];
int len;
while ((len = bis.read(buffer)) != -1) {
bos.write(buffer, 0, len);
//強制刷新緩衝區,會把緩衝區的數據刷新到磁盤中
// bos.flush();
}
long end = System.currentTimeMillis();
System.out.println(end - start);
} catch (IOException e) {
e.printStackTrace();
} finally {
//4、關閉流資源 關閉原則,先開啟的後關閉,關閉外層包裝流時內層流也會關閉,因此就不需要另外關閉
if (bis != null) {
try {
bis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (bos != null) {
try {
bos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
/**
* 使用緩存字符流進行文本複製
*/
@Test
public void test2() {
//971M耗時1444ms 測試後如果指定的buff緩衝區越大理論上越好,因為順序寫速度更快
long start = System.currentTimeMillis();
BufferedReader br = null;
BufferedWriter bw = null;
try {
//1、實例化要操作的讀入/寫出文件對象
//2.1、創建輸入流和輸出流
//2.1、創建緩存流
br = new BufferedReader(new FileReader(new File("new-io.txt")));
bw = new BufferedWriter(new FileWriter(new File("new-io-copy3.txt")));
//3、數據的讀入和寫出操作
//字符流讀寫的是字符,所以用字符容器
//方式一:使用char數組
/* char[] buffer = new char[1024];
int len;
while ((len = br.read(buffer)) != -1) {
bw.write(buffer, 0, len);
//強制刷新緩衝區,會把緩衝區的數據刷新到磁盤中
// bw.flush();
}*/
//方式二:使用String
String data;
while ((data = br.readLine()) != null) {
// bw.write(data+"\n");
//如果沒有換號符,則會寫在一起
bw.write(data);
bw.newLine();
}
long end = System.currentTimeMillis();
System.out.println(end - start);
} catch (IOException e) {
e.printStackTrace();
} finally {
//4、關閉流資源
if (br != null) {
try {
br.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (bw != null) {
try {
bw.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
轉換流
基本概念
-
轉換流屬於字符流,看流的歸屬看後綴。
-
InputStreamReader將位元組流轉換成字符流,並解碼(位元組、位元組數組—>字符、字符數組)。
-
OutputStreamWriter將字符流轉換成位元組流,並編碼(字符、字符數組—>位元組、位元組數組)。
-
編碼解碼過程需要字符集進行處理。
字符集
ASCII:因為只要表示字母這些所有一個位元組就夠了。
GBK,UTF-8都兼容了ASCII碼錶,所有在把原本是UTF-8的文本解碼GBK時對於英文的部分也不會有什麼問題,但中文部分就會亂碼。
GBK,GBK2312是通過首字符是0表示一個位元組代碼一個字符;首字符是1表示需要讀取2個位元組表示一個字符來規範編碼的,即用最高位是1或0來表示兩個位元組或一個位元組。
應用
編碼和解碼。
示例小結
public class TransferIOTest {
/**
* 轉換流讀文件打印
*/
@Test
public void test1() {
//1、創建位元組流對象
InputStreamReader isr = null;
try {
FileInputStream fis = new FileInputStream("new-io.txt");
//沒有指定解碼的字符集的話就使用默認的字符集
// InputStreamReader isr = new InputStreamReader(fis);
//2、創建字符轉換流
isr = new InputStreamReader(fis, "UTF-8");
//3、解碼讀取
char[] buff = new char[1024];
int len;
while ((len = isr.read(buff)) != -1) {
//因為我們使用了文件原本的UTF-8字符集編碼格式,所有在打印時就不會出現解碼出現亂碼的問題。
System.out.println(new String(buff, 0, len));
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (isr != null) {
//4、關閉流資源
try {
isr.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
/**
* hello,my io
* 我要被強轉了
* hello,my io
* 我要被強轉了
* hello,my io
* 我要被強轉了我要被強轉了我要被強轉了我要被強轉了我要被強轉了
*/
/**
* 轉換流讀UTF-8文件保存成GBK文件
*/
@Test
public void test2() {
//1、創建位元組流對象
InputStreamReader isr = null;
OutputStreamWriter osr = null;
try {
FileInputStream fis = new FileInputStream("new-io.txt");
FileOutputStream fos = new FileOutputStream("new-io-gbk.txt");
//沒有指定解碼的字符集的話就使用默認的字符集
// InputStreamReader isr = new InputStreamReader(fis);
//2、創建字符轉換流
//寫代碼時必須要指定字符集格式
isr = new InputStreamReader(fis, "UTF-8");
osr = new OutputStreamWriter(fos, "GBK");
//3、解碼讀取
char[] buff = new char[1024];
int len;
while ((len = isr.read(buff)) != -1) {
osr.write(buff,0,len);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (isr != null) {
//4、關閉流資源
try {
isr.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (osr != null) {
//4、關閉流資源
try {
osr.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
其他流
標準輸入、輸出流
打印流
數據流
示例小結
public class OtherTest {
/**
* 利用標準輸入輸出流從鍵盤中讀取輸入,轉換成大寫打印到控制台上
* 注意idea不支持使用@Test測試方法讀取鍵盤的輸入,所以要改用main方法
*
* @param args
*/
public static void main(String[] args) {
BufferedReader br = null;
try {
br = new BufferedReader(new InputStreamReader(System.in));
String data = "";
while (true) {
System.out.println("請輸入:");
data = br.readLine();
if ("exit".equalsIgnoreCase(data)) {
System.out.println("再見!");
break;
}
System.out.println(data.toUpperCase());
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (br != null) {
try {
br.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
/**
* 請輸入:
* hhhh
* HHHH
* 請輸入:
* exit
* 再見!
*/
/**
* 打印流
*/
@Test
public void test1() {
PrintStream ps = null;
try {
//創建打印輸出流,並設置自動刷新,默認是false,自動刷新當遇到換行符或者\n時會刷新輸出緩衝區
ps = new PrintStream(new FileOutputStream(new File("test-print.txt")),true);
//把標準輸出流(打印到控制台改成我們文件),我們的log日誌記錄到文本中就是用的打印流PrintStream/PrintWriter
System.setOut(ps);
String str = "我就是來測試打印流的\n現在開始測試:abcedsakjfslkdjfdfskgjdfkg\nsdfsdfsdf\n結束";
System.out.println(str);
} catch (FileNotFoundException e) {
e.printStackTrace();
} finally {
if (ps != null) {
ps.close();
}
}
}
/**
* 數據流:讀取和寫出8種基本數據類型和字符串
*/
@Test
public void test2() throws Exception {
DataOutputStream dos = new DataOutputStream(new FileOutputStream("data.txt"));
dos.writeUTF("期望薪資");
dos.writeInt(36000);
dos.writeBoolean(true);
dos.flush();
dos.close();
DataInputStream dis = new DataInputStream(new FileInputStream("data.txt"));
//注意讀取數據的時候要按照寫入的順序讀,否則會報錯
System.out.println(dis.readUTF());
System.out.println(dis.readInt());
System.out.println(dis.readBoolean());
dis.close();
}
}
對象流
對象可序列化需滿足3個條件
- 對象對應的類需要實現Serializable接口。
- 需定義一個全局常量serialVersionUID。
- 對象內的所有屬性也必須是可序列化的,比如自定義的Address類,基本數據類型都是可序列號的。
序列化**:把內存中的對象轉換為二進制流。這樣便可以將二進制流持久化到磁盤或者傳輸到另一個網絡節點上。
反序列化:將二進制流還原成Java對象。
serialVersionUID的作用
- 標識類的版本以便於版本兼容。
- 如果沒有定義serialVersionUID的話Java會根據類的內部細節自動生成,如果類的實例變量發生了修改,自動生成的serialVersionUID就會發生改變。
- Java序列化機制是通過serialVersionUID來驗證版本的一致性,如果版本不一致則在反序列化時會報版本不一致異常。
實例小結
ublic class ObjectInputOutputStreamTest {
/**
* 對象序列化
*
* @throws Exception
*/
@Test
public void test1() throws Exception {
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("object.txt"));
oos.writeObject(new Person("張三", 30, new Address("紫禁城1號")));
oos.writeObject(new String("我是艾米"));
oos.flush();
oos.close();
}
/**
* 對象反序列化
*
* @throws Exception
*/
@Test
public void test2() throws Exception {
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("object.txt"));
//需按照寫入的對象順序讀取,否則會報錯
Person person = (Person) ois.readObject();
String str = (String) ois.readObject();
System.out.println(person);
System.out.println(str);
ois.close();
}
/**
* Person(name=張三, age=30, address=Address(location=紫禁城1號))
* 我是艾米
*/
}
/**
* 對象可序列化需滿足3個條件:
* 對象對應的類需要實現Serializable接口
* 需定義一個全局常量serialVersionUID
* 對象內的所有屬性也必須是可序列化的,比如自定義的Address類,基本數據類型都是可序列號的。
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Person implements Serializable {
private static final long serialVersionUID = -6849344724054667710L;
private String name;
private int age;
private Address address;
}
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Address implements Serializable {
private static final long serialVersionUID = -684934470754667710L;
private String location;
}
隨記存取文件流——斷點續傳
實例小結
public class RandomAccessFileTest {
/**
* 隨機存取文件-讀文件寫到新的文件中
*/
@Test
public void test1() {
RandomAccessFile read = null;
RandomAccessFile write = null;
try {
//只讀
read = new RandomAccessFile(new File("new-io.txt"), "r");
//可讀可寫
write = new RandomAccessFile(new File("test.txt"), "rw");
byte[] buff = new byte[1024];
int len;
while ((len = read.read(buff)) != -1) {
write.write(buff, 0, len);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (read != null) {
try {
read.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (write != null) {
try {
write.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
/**
* 使用RandomAccessFile實現數據的插入效果
*/
@Test
public void test2() throws Exception {
//可讀可寫
RandomAccessFile raf = new RandomAccessFile(new File("test.txt"), "rw");
//將指針調到角標為3的位置,0開始。
raf.seek(3);
//保存角標3後的數據,然後再實現插入,最後再把角標3後位置的數據繼續追加進來
//用位元組數組輸出流來保存數據避免亂碼
ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte[] buff = new byte[1024];
int len;
while ((len = raf.read(buff)) != -1) {
baos.write(buff, 0, len);
}
//調回要插入位置的指針
raf.seek(3);
raf.write("哈哈哈我插入進來了".getBytes());
raf.write(baos.toString().getBytes());
raf.close();
baos.close();
}
}
NIO.2中Path、Paths、Files類的使用
第三方common-io實現IO讀寫
依賴
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.4</version>
</dependency>
示例
public class CommonsIOTest {
@Test
public void test() throws IOException {
File srcFile = new File("是大臣.jpg");
File destFile = new File("是大臣-copy3.jpg");
FileUtils.copyFile(srcFile, destFile);
}
}
參考
577-617