檔案:文本、圖片、視頻、程式等存盤在計算機上
檔案目錄:檔案夾,管理檔案, linux 下有權限、運算子、用戶組、用戶等
路徑分割符:
\ 表示 windows 系統檔案目錄分割符
/ 表示 mac/linux 下的路徑分割符
java 代碼在 windows 下寫某個檔案的話需要下面的方式
D:\\soft\\sd.txt 其中一個單斜杠是用來轉義的
java 代碼在 linux 或者 Mac 下寫某個檔案的話需要下面的方式
usr/local/soft/sd.txt 其中一個單斜杠是用來轉義的
代碼和檔案目錄的關系: 對檔案和目錄增刪改查
IO,輸入和輸出 Input/Output
把持久化設備上的資料讀取到記憶體中的動作稱為輸入, Input 操作
記憶體中的資料持久化到設備上的動作, Output 輸出操作
一般把輸入和輸出動作稱為 IO 操作, IO 分為網路 IO 和檔案 IO
java 檔案類 File :
主要是對計算機檔案目錄的操作,對檔案和目錄的增刪改查, File 類表示磁盤中存在的檔案和目錄
實作了 Serializable, Comparable 兩大介面,可進行序列化和比較
File.separator 目錄分隔符,在不同的系統下不一樣, windows 下是 "\" , mac/Linux 下是 "/",操作檔案時可以用來連接目錄的分隔符
常見的建構式:
//路徑和檔案名的拼接
public File(String pathname)
//父路徑,子路徑
public File(String parent, String child)
// 獲取帶檔案名的檔案路徑,即 new File 建構式傳入的路徑
String getPath()
String dir = "C:\\Users\\79466\\Desktop\\";
String name = "a.txt";
File file = new File(dir, name);
// File file = new File(dir); 目錄物件
System.out.println(file.getPath()); // 列印檔案的路徑和檔案名
System.out.println(File.separator); // 列印不同系統的檔案分隔符
// 常用的檔案操作 api
file.getPath(); // 獲取帶檔案名的檔案路徑, C:\Users\79466\Desktop\a.txt
file.getName(); // 獲取檔案名, a.txt
file.getAbsolutePath(); // 獲取檔案的絕對路徑 C:\Users\79466\Desktop\a.txt
file.getParent(); // 獲取檔案的父路徑 C:\Users\79466\Desktop
file.exists(); // 檔案或者目錄是否存在
file.isFile(); // 是否是一個檔案
file.isDirectory(); // 是否是一個目錄
file.isAbsolute(); //是否是絕對路徑
// 如果 file 是目錄,獲取檔案目錄下所有的檔案及目錄的名稱,操作物件是目錄,如果是檔案會報錯
String[] arr = file.list();
for (String temp : arr) {
System.out.println(temp);
}
// 創建指定目錄
File mkdir = new File(dir + "\\xd");
mkdir.mkdir(); //創建一級目錄
File mkdirs = new File(dir + "\\xd\\aa\\bb\\cc"); // 或者 dir + "\\xd\\aa\\bb\\cc\\"
mkdirs.mkdirs(); //創建多級目錄
File newFile = new File(dir + "\\xxxx.txt");
// 如果 dir 不存在或者創建檔案失敗需要捕獲例外
try {
newFile.createFile();
} catch (IOException e) {
e.printStackTrace();
}
newFile.delete(); //洗掉操作,當前檔案如果是最終的檔案才可以洗掉,如果是目錄,里面還有檔案,需要先洗掉檔案才能洗掉該目錄
File 的建構式只是創建一個 File 實體,即使目錄錯誤也不會報錯,因為沒有對檔案進行操作
輸出流: 程式到外界設備 輸入流: 外界設備到程式
處理資料型別分類
字符流: 處理字符相關,如文本資料( txt 檔案), Reader / Writer
位元組流: 處理位元組相關,聲音或者圖片等二進制, InputStream/OutputStream
兩者區別:
位元組流以位元組(8bit)為單位,字符流以字符為單位,根據碼表映射字符,一次可能讀多個位元組
位元組流可以處理幾乎所有檔案,字符流只能處理字符型別的資料,如果檔案都是中文文本的話可以使用字符流,速度更快,更省空間
功能不同,但是具有共性內容,抽象成4個抽象類
字符流 Reader/Writer
位元組流 InputStream/OutputStream
使用的時候都不會使用抽象類進行實作,開發使用對應的子類
位元組流:
InputStream: 實作類及子類有 FileInputStream (這個類用的最多, 可以用 BufferedInputStream 提高性能)、 ObjectInputStream (物件輸入流,序列化的時候) 、 ByteArrayInputStream
OutputStream 和 InputStream 一樣
int read(byte[] buf) // 從輸入流中讀取一定數量的位元組,并將其存盤在緩沖區陣列 buf 中,回傳實際讀取的位元組數
int available() // 回傳這個流中有多少個位元組數,可以把 buf 陣列長度定為這個
void close() throws IOException // 關閉輸入流并釋放與該流關聯的系統資源
FileInputStream 位元組輸入流:
// 傳入檔案所在地址
public FileInputStream(String name) throws FileNotFoundException
// 傳入檔案物件
public FileInputStream(File file) throws FileNotFoundException
public static void main (String [] args) {
File file = new File(dir, name);
InputStream inputStream = new FileInputStream(file);
// 讀取一個位元組
int read = inputStream.read();
// 位元組對應的 ASCII 碼
System.out.println(read);
// 強轉成字符
System.out.println((char)read);
}
inputStream.skip(); // 跳過,從輸入流中跳過并丟棄 n 個位元組的資料
byte[] buf = new byte[1024];
int length;
// 一次性讀取 buf.length 個位元組并放到 buf 陣列中,回傳型別是讀取到的位元組數
while ((length = inputStream.read(buf)) != -1) {
System.out.println(new String(buf, 0, length)); // 從0開始,長度是3
System.out.println(new String(buf, 0, length, "UTF-8"));
}
FileOutputStream 位元組輸出流:
構造:
// 傳入輸出的檔案地址
public FileOutputStream(String name)
// 傳入目標輸出的檔案物件
public FileOutputStream(File file)
// 傳入目標輸出的檔案物件,是否可以追加內容
public FileOutputStream(File file, boolean append)
public static void main(String [] args) {
String target = "a.txt";
InputStream inputStream = new FileInputStream(file);
// 會創建檔案,但是不會創建多級目錄
// OutputStream outputStream = new FileOutputStream(dir + File.separator + target);
// 不覆寫檔案,只追加資料
OutputStream outputStream = new FileOutputStream(dir + File.separator + target, true);
byte[] buf = new byte[1024];
int length;
// 一次性讀取 buf.length 個位元組并放到 buf 陣列中,回傳型別是讀取到的位元組數
while ((length = inputStream.read(buf)) != -1) {
// 按位元組陣列的長度寫出
outputStream.write(buf, 0, length);
}
// 例外處理見下面,此處如果上面出現例外就無法關閉
inputStream.close();
outputStream.close();
}
緩沖 Buffer :
記憶體空間的一部分,在記憶體空間預留了一定的存盤空間,這些存盤空間用來緩沖輸入或輸出的資料,這部分空間就叫做緩沖區,緩沖區默認大小是8k,使用緩沖區暫存資料,
可以減少和磁盤的互動,讀入時與磁盤連接后讀入較多的資料到緩沖區,記憶體再慢慢去消耗
BufferInputStream 緩沖位元組輸入流,讀取資料時,與磁盤連接一次讀取到記憶體,緩沖區滿時會再讀取下一截資料重新填充到緩沖區
建構式:
// 對輸入流進行包裝,里面默認的緩沖區是8k
public BufferedInputStream(InputStream in);
// 對輸入流進行包裝,創建具有指定緩沖區大小的 Buffer
public BufferedInputStream(InputStream in, int size);
常用方法:
// 從輸入流中讀取一個位元組
public int read();
// 從位元組輸入流中給定偏移量處開始將各位元組讀取到指定的 byte 陣列中
public int read(byte[] buf, int off, int len);
// 關閉資源,關閉這個流即可, InputStream 會在里面被關閉
void close();
BufferOutputStream 緩沖位元組輸出流,當緩沖區滿時,會自動寫出到磁盤
構造同 BufferInputStream
常用方法:
// 向輸出流中輸出一個位元組
public void write(int b);
// 將指定 byte 陣列中從偏移量 off 開始的 len 個位元組寫入緩沖的輸出流
public void write(byte[] buf, int off, int len);
// 重繪此緩沖的輸出流,強制使所有緩沖的輸出位元組被寫出到底層輸出流中,當緩沖區的大小未滿時,需要手動刷到磁盤
public void flush();
// 關閉釋放資源, OutputStream 會在里面被關閉, JDK7 新特性 try (在這里宣告的 流 會自動關閉){}
void close();
緩沖輸入輸出流進行檔案拷貝:
try {
FileInputStream fis = new FileInputStream("C:\\Users\\79466\\Desktop\\test\\a.txt");
BufferedInputStream bis = new BufferedInputStream(fis);
FileOutputStream fos = new FileOutputStream("C:\\Users\\79466\\Desktop\\test\\copy.txt");
BufferedOutputStream bos = new BufferedOutputStream(fos);
int size;
byte[] buf = new byte[1024];
while (( size = bis.read(buf)) != -1) {
// 將位元組輸出流寫到緩沖區里面,等緩沖區滿后自動寫出
bos.write(buf, 0, size);
}
// 重繪此緩沖區的輸出流,才可以保證資料全部輸出完成,關閉的時候也會進行重繪,寫了也不要緊,也就是多刷一次, close 方法的關閉前會先進行重繪
// bos.flush();
// 內部會關掉 InputStream 和 OutputStream 例外處理見下面,此處如果上面出現例外就無法關閉
bis.close();
// close 原始碼里面會有 flush ,可以不用單獨呼叫 flush ,jdk7 之后 close 原始碼里的 try 里面宣告了 OutputStream ,會自動關閉 outputStream 流
bos.close();
} catch (Exception e) {
e.printStackTrace();
}
流的關閉順序,后開的先關,如果A依賴B,先關閉B
IO 的例外處理:
大部分公司的做法: 在 finally 里面進行關閉
catch (Exception e) {
e.printStackTrace();
} finally {
if(bis != null) {
try {
bis.close();
}catch () {
e.printStackTrace();
}finally {
if(bos != null) {
try {
bos.close();
}catch (Exception e) {
e.printStackTrace();
}
}
}
}
}
jdk7 之后的做法: try-with-resource
try 里面宣告的 OutputStream 和 InputStream 會自動關閉, jdk7 之后的 InputStream 都實作了 AutoCloseable
在 try 里面定義多個資源,關閉的順序是最后在 try() 定義的資源最先關閉
try (
FileInputStream fis = new FileInputStream("C:\\Users\\79466\\Desktop\\test\\a.txt");
BufferedInputStream bis = new BufferedInputStream(fis);
FileOutputStream fos = new FileOutputStream("C:\\Users\\79466\\Desktop\\test\\copy.txt");
BufferedOutputStream bos = new BufferedOutputStream(fos);) {
int size;
byte[] buf = new byte[1024];
while(( size = bis.read(buf)) != -1 ) {
bos.write(buf, 0, size);
}
bos.flush();
} catch (Exception e) {
e.printStackTrace();
}
關于位元組:
位元組(Byte簡寫B):作為一個單位來處理的一個二進制數字串,是構成資訊的一個小單位,最常用的位元組是八位的位元組,即它包含八位的二進制數,1B=8bit,1KB=1024B
一個英文字母(不分大小寫)占一個位元組的空間,位元組作為一個二進制數字序列,在計算機中作為一個數字單元,一般為8位二進制數,換算為十進制,最小值-128,最大值127,如一個ASCII碼就是一個位元組
UTF-8編碼:一個英文字符等于一個位元組,一個中文(含繁體)等于三個位元組,中文標點占三個位元組,英文標點占一個位元組
Unicode編碼:一個英文等于兩個位元組,一個中文(含繁體)等于兩個位元組,中文標點占兩個位元組,英文標點占兩個位元組
字串轉換為位元組陣列:byte[] b = string.getBytes();
位元組轉換成字串:String string = new String(byte[] bytes, Charset charset);
byte[] b="我是一個兵".getBytes("GBK"); GBK編碼的字串轉為位元組陣列
需要把string保存到檔案中,必須把string轉換成一個有序的位元組流,以便系統在硬碟上做物理保存,String到位元組流的轉換涉及到使用何種編碼,使用不同的編碼得到的位元組碼不同
存 byte 的方式要優于存 string
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/161517.html
標籤:其他
