織夢通用seo網(wǎng)站模板百度客服電話24小時
1 什么是文件?
針對硬盤這種持久化存儲的I/O設(shè)備,當(dāng)我們想要進行數(shù)據(jù)保存時,往往不是保存成一個整體,而是獨立成一個個的單位進行保存,這個獨立的單位就被抽象成文件的概念
2 文件路徑
文件路徑就是指咱們文件系統(tǒng)中一個文件/目錄(文件夾)的具體位置
由于文件系統(tǒng)是以樹形結(jié)構(gòu)來組織文件和目錄,所以文件路徑就是從樹根節(jié)點出發(fā),沿著樹杈往下走,直到到達目標文件,這中間所經(jīng)過的內(nèi)容
2.1 絕對路徑
Windows是從“此電腦”開始的,表示路徑的時候可以忽略“此電腦”,直接從盤符開始
例如:F:\人工智能程序設(shè)計\我的python案例\Test1.py
實際表示路徑是通過字符串來表示,每個目錄之間使用‘/’(斜杠)來分割.(只有Windows采用‘\’(反斜杠)來分割)
從盤符開始一層層往下找,這個過程,得到的路徑就叫絕對路徑
2.2 相對路徑
從給定的目標開始,一層一層往下找,這個過程得到的路徑就是相對路徑
eg:
其中:
‘.’是一個特殊符號,在相對路徑中代表當(dāng)前目錄
‘. .’表示當(dāng)前目錄的上級目錄
3 文本文件和二進制文件
文本文件存儲的是被字符集編碼的文本
二進制文件存儲的是二進制文件,不被字符集限制
4 文件系統(tǒng)操作
java標準庫給我們提供了File類,File對象是對硬盤上一個文件的抽象
(文件是儲存在硬盤上的,直接用代碼操作硬盤不方便,就在內(nèi)存中創(chuàng)建一個對應(yīng)的對象,操作這個內(nèi)存中的對象就可以間接的影響到硬盤中的文件的情況了~~遙控器)
4.1 構(gòu)造File對象
構(gòu)造的過程可以使用相對路徑/絕對路徑來進行初始化,這個路徑指向的文件可以是真實存在的也可以是不存在的
4.2 File提供的方法
get方法代碼演示:
import java.io.File;
import java.io.IOException;public class IO_Test1 {public static void main(String[] args) throws IOException {File file = new File("./cat.jpg");System.out.println(file.getParent()); //返回 File 對象的父目錄文件路徑System.out.println(file.getName()); //返回 FIle 對象的純文件名稱System.out.println(file.getPath()); //返回 File 對象的文件路徑System.out.println(file.getAbsolutePath()); //返回 File 對象的絕對路徑System.out.println(file.getCanonicalPath()); //返回 File 對象的修飾過的絕對路徑}
}
普通文件的創(chuàng)建和刪除:
import java.io.File;
import java.io.IOException;public class IO_Test2 {public static void main(String[] args) throws IOException {// 在相對路徑中, ./ 通??梢允÷?/span>File file = new File("hello_IO.txt"); // 該文件不存在System.out.println(file.exists()); //判斷 File 對象描述的文件是否真實存在System.out.println(file.isDirectory()); //判斷 File 對象代表的文件是否是一個目錄System.out.println(file.isFile()); //判斷 File 對象代表的文件是否是一個普通文件//創(chuàng)建文件file.createNewFile(); //根據(jù) File 對象,自動創(chuàng)建一個空文件。成功創(chuàng)建后返回 true//創(chuàng)建后該文件存在System.out.println(file.exists()); //判斷 File 對象描述的文件是否真實存在System.out.println(file.isDirectory()); //判斷 File 對象代表的文件是否是一個目錄System.out.println(file.isFile()); //判斷 File 對象代表的文件是否是一個普通文件//刪除文件file.delete();System.out.println("刪除文件之后");System.out.println(file.exists());}
}
5 文件內(nèi)容操作
5.1 字符流
什么是字符流?
針對文本文件,提供了一組類,統(tǒng)稱為“字符流”
典型代表:Reader , Writer。 讀寫的基本單位是字符
InputStream使用方法
🚀打開文件和關(guān)閉文件
InputStream是抽象類:
關(guān)于 InputStream 的實現(xiàn)類有很多,我們現(xiàn)在只關(guān)心從文件中讀取,所以使用 FileInputStream類
InputStream inputStream = new FileInputStream("f:/test.txt");
注意!!!:這里有了打開文件的操作,后面需要手動釋放資源(文件描述符)!!!! inputStream.close();
進程的PCB結(jié)構(gòu)中又“文件描述符表”,其記錄了當(dāng)前進程都打開了哪些文件,每次打開文件,就會在表中申請到一個位置~這個表可以視為一個數(shù)組,數(shù)組的下標就是文件描述符,數(shù)組元素就是這個文件在內(nèi)核中的結(jié)構(gòu)體的表示。
由于這個表長度是有限的不能無休止的打開又不釋放,一旦滿了再嘗試打開就會打開失敗,造成文件資源泄露!!!
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;public class IO_Test3 {public static void main(String[] args) throws IOException {// 這個過程, 相當(dāng)于 C 中的 fopen , 文件的打開操作InputStream inputStream = new FileInputStream("f:/test.txt");inputStream.close();}
}
執(zhí)行中間,可能會出一些問題,比如return或者拋異常,就會導(dǎo)致close執(zhí)行不到!
所以我們使用try...finally
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;public class IO_Test3 {public static void main(String[] args) throws IOException {// 這個過程, 相當(dāng)于 C 中的 fopen , 文件的打開操作InputStream inputStream = null;try {inputStream = new FileInputStream("f:/test.txt");}finally {inputStream.close();}}
}
但是上面這個代碼太麻煩了(丑)
我們使用try with resources
(帶有資源的try操作,會在try結(jié)束自動執(zhí)行close關(guān)閉操作)
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;public class IO_Test3 {public static void main(String[] args) throws IOException {try(InputStream inputStream = new FileInputStream("f:/test.txt")) {//打開文件和關(guān)閉文件}}
}
🚀讀文件:
InputStream提供的read方法有三個版本:
其中read的無參數(shù)版本是一次讀一個字節(jié)(一次返回一個字節(jié))
但是我們需要用int來接受read的返回值====>
int b = inputStream.read();
完整代碼:
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;public class IO_Test3 {public static void main(String[] args) throws IOException {try(InputStream inputStream = new FileInputStream("f:/test.txt")) {//讀文件// read 一次返回的是一個字節(jié). 但是此處的返回值類型是 int !!!while (true) {int b = inputStream.read();if (b == -1) {// 讀到末尾了, 結(jié)束循環(huán)即可break;}System.out.printf("%x\n", b);}}}
}
🚀 寫文件
package io;import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;public class IODemo7 {public static void main(String[] args) {try (OutputStream outputStream = new FileOutputStream("d:/test.txt")) {outputStream.write(97);outputStream.write(98);outputStream.write(99);} catch (IOException e) {e.printStackTrace();}}
}
6 文件操作案例
掃描指定目錄,并找到名稱或者內(nèi)容中包含指定字符的所有普通文件(不包含目錄)
解:
import java.io.*;
import java.util.Scanner;public class IO_Test4 {public static void main(String[] args) {Scanner scanner = new Scanner(System.in);// 1. 先讓用戶指定一個要搜索的根目錄System.out.println("請輸入要掃描的根目錄: ");File rootDir = new File(scanner.next());if (!rootDir.isDirectory()) {System.out.println("輸入有誤, 您輸入的目錄不存在!");return;}// 2. 讓用戶輸入一個要查詢的詞.System.out.println("請輸入要查詢的詞: ");String word = scanner.next();// 3. 遞歸的進行目錄/文件的遍歷了scanDir(rootDir, word);}private static void scanDir(File rootDir, String word) {// 列出當(dāng)前的 rootDir 中的內(nèi)容. 沒有內(nèi)容, 直接遞歸結(jié)束File[] files = rootDir.listFiles();if (files == null) {// 當(dāng)前 rootDir 是一個空的目錄, 這里啥都沒有.// 沒必要往里遞歸了return;}// 目錄里有內(nèi)容, 就遍歷目錄中的每個元素for (File f : files) {System.out.println("當(dāng)前搜索到: " + f.getAbsolutePath());if (f.isFile()) {// 是普通文件// 打開文件, 讀取內(nèi)容, 比較看是否包含上述關(guān)鍵詞String content = readFile(f);if (content.contains(word)) {System.out.println(f.getAbsolutePath() + " 包含要查找的關(guān)鍵字!");}} else if (f.isDirectory()) {// 是目錄// 進行遞歸操作scanDir(f, word);} else {// 不是普通文件, 也不是目錄文件, 直接跳過continue;}}}private static String readFile(File f) {// 讀取文件的整個內(nèi)容, 返回出來.// 使用字符流來讀取. 由于咱們匹配的是字符串, 此處只能按照字符流處理, 才是有意義的.StringBuilder stringBuilder = new StringBuilder();try (Reader reader = new FileReader(f)) {// 一次讀一個字符, 把讀到的結(jié)果給拼裝到 StringBuilder 中. 統(tǒng)一轉(zhuǎn)成 Stringwhile (true) {int c = reader.read();if (c == -1) {break;}stringBuilder.append((char)c);}} catch (IOException e) {e.printStackTrace();}return stringBuilder.toString();}
}