IO流
File類
File類的使用
1.File類的一個對象,代表一個文件或一個文件目錄(文件夾)
2.File類的聲明在java.io包下
3.File類中涉及到關於文件或文件目錄的創建、刪除、重命名、修改時間、文件大小等方法,並未涉及到寫入或讀取文件內容的操作。如果需要讀取或寫入文件內容,必須使用IO流來完成。
4.後續File類的對象常會作爲參數傳遞到流的構造器中,指明讀取或寫入的"終點"。
一、常用構造
-
public File(String pathname)
以pathname爲路徑創建File對象,可以是絕對路徑或者相對路徑,如果 pathname是相對路徑,則默認的當前路徑在系統屬性user.dir中存儲。
絕對路徑:是一個固定的路徑,從盤符開始
相對路徑:是相對於某個位置開始
-
public File(String parent,String child)
以parent爲父路徑,child爲子路徑創建File對象。
-
public File(File parent,String child)
根據一個父File對象和子文件路徑創建File對象
二、常用方法
File類的獲取功能
public String getAbsolutePath():獲取絕對路徑
public String getPath() :獲取路徑
public String getName() :獲取名稱
public String getParent():獲取上層文件目錄路徑。若無,返回null public long length() :獲取文件長度(即:字節數)。不能獲取目錄的長度。
public long lastModified() :獲取最後一次的修改時間,毫秒值
public String[] list() :獲取指定目錄下的所有文件或者文件目錄的名稱數組
public File[] listFiles() :獲取指定目錄下的所有文件或者文件目錄的File數組
File類的重命名功能
public boolean renameTo(File dest):文件重命名爲指定的文件路徑
File類的判斷功能
public boolean isDirectory():判斷是否是文件目錄
public boolean isFile() :判斷是否是文件
public boolean exists() :判斷是否存在
public boolean canRead() :判斷是否可讀
public boolean canWrite() :判斷是否可寫
public boolean isHidden() :判斷是否隱藏
File類的創建功能
public boolean createNewFile() :創建文件。若文件存在,則不創建,返回false
public boolean mkdir() :創建文件目錄。如果此文件目錄存在,就不創建了。 如果此文件目錄的上層目錄不存在,也不創建。
public boolean mkdirs() :創建文件目錄。如果上層文件目錄不存在,一併創建
注意事項:如果你創建文件或者文件目錄沒有寫盤符路徑,那麼,默認在項目路徑下。
File類的刪除功能
public boolean delete():刪除文件或者文件夾
刪除注意事項: Java中的刪除不走回收站。
要刪除一個文件目錄,請注意該文件目錄內不能包含文件或者文件目錄
Java IO原理
-
I/O是Input/Output的縮寫, I/O技術是非常實用的技術,用於處理設備之間的數據傳輸。如讀/寫文件,網絡通訊等。
-
Java程序中,對於數據的輸入/輸出操作以“流(stream)” 的 方式進行。
-
java.io包下提供了各種“流”類和接口,用以獲取不同種類的數據,並通過標準的方法輸入或輸出數據。
-
輸入input:讀取外部數據(磁 盤、光盤等存儲設備的數據)到程序(內存)中。
-
輸出output:將程序(內存)數據輸出到磁盤、光盤等存儲設備中。
流的分類
-
按操作數據單位不同分爲:字節流(8 bit),字符流(16 bit)
-
按數據流的流向不同分爲:輸入流,輸出流
-
按流的角色的不同分爲:節點流,處理流
IO 流體系
流的體系結構
InputStream & Reader
1.對於文本文件(.txt,java,c,c++) 使用字符流處理Reader和Writer
2.對於非文本文件(.jpg,mp3,mp4,avi,ppt),使用字節流Stream
InputStream 和 Reader 是所有輸入流的基類。
InputStream(典型實現:FileInputStream) 字節流
int read()
從輸入流中讀取數據的下一個字節,到達末尾返回-1
int read(byte[] b)
從輸入流將字節讀入一個byte數組中
int read(byte[] b, int off, int len)
從輸入流中將最多len個數據字節讀入 byte 數組
Reader(典型實現:FileReader) 字符流
int read()
讀取單個字符。
int read(char [] c)
將字符讀入數組。如果已到達流的末尾,則返回-1
int read(char [] c, int off, int len)
將字符讀入數組的某一部分。存到數組c中,從off處開始存儲,最多讀len個字符
OutputStream&Writer
OutputStream
void write(int b)
將指定的字節寫入此輸出流。
void write(byte[] b)
將b.length個字節從指定的byte數組寫入此輸出流。
void write(byte[] b,int off,int len)
將指定 byte 數組中從偏移量 off 開始的 len 個字節寫入此輸出流。
public void flush()throws IOException
刷新此輸出流並強制寫出所有緩衝的輸出字節,調用此方法指示應將這些字節立 即寫入它們預期的目標。
public void close() throws IOException 關閉此輸出流並釋放與該流關聯的所有系統資源。
Writer
void write(int c) 寫入單個字符。
void write(char[] cbuf) 寫入字符數組。
void write(char[] cbuf,int off,int len)
寫入字符數組的某一部分。從off開始,寫入len個字符
void write(String str) 寫入字符串。
void write(String str,int off,int len) 寫入字符串的某一部分。
void flush() 刷新該流的緩衝,則立即將它們寫入預期目標。
public void close() throws IOException 關閉此輸出流並釋放與該流關聯的所有系統資源。
關閉時先關外層流再關內層,外層流關閉同時內層流也自動關閉,內層可以省略不寫。
節點流
讀取文件
寫入文件
緩衝流
處理流之一:緩衝流的使用
BufferedInputStream
BufferedOutputStream
BufferedReader
BufferedWriter
作用:提供流的讀取、寫入的速度。提供讀寫速度的原因:內部提供了一個緩衝區3.處理流:就是套接在已有流基礎上
轉換流
轉換流提供了在字節流和字符流之間的轉換
Java API提供了兩個轉換流:
- InputStreamReader:將InputStream轉換爲Reader
- OutputStreamWriter:將Writer轉換爲OutputStream
字節流中的數據都是字符時,轉成字符流操作更高效。
很多時候我們使用轉換流來處理文件亂碼問題。實現編碼和 解碼的功能。
InputStreamReader
- 實現將字節的輸入流按指定字符集轉換爲字符的輸入流。
- 需要和InputStream“套接”。
- 構造器
public InputStreamReader(InputStream in)
public InputSreamReader(InputStream in,String charsetName)
如: Reader isr = new InputStreamReader(System.in,”gbk”);
OutputStreamWriter
- 實現將字符的輸出流按指定字符集轉換爲字節的輸出流。
- 需要和OutputStream“套接”。
- 構造器
public OutputStreamWriter(OutputStream out)
public OutputSreamWriter(OutputStream out,String charsetName)
對象流
ObjectInputStream和OjbectOutputSteam
用於存儲和讀取基本數據類型數據或對象的處理流。它的強大之處就是可以把Java中的對象寫入到數據源中,也能把對象從數據源中還原回來。
- 序列化:用ObjectOutputStream類保存基本類型數據或對象的機制
- 反序列化:用ObjectInputStream類讀取基本類型數據或對象的機制
- ObjectOutputStream和ObjectInputStream不能序列化static和transient修 飾的成員變量
若某個類實現了 Serializable 接口,該類的對象就是可序列化的:
- 創建一個 ObjectOutputStream
- 調用 ObjectOutputStream 對象的 writeObject(對象) 方法輸出可序列化對象
- 注意寫出一次,操作flush()一次
反序列化
- 創建一個 ObjectInputStream
- 調用 readObject() 方法讀取流中的對象
自定義類需要滿足如下的要求,方可序列化
1.實現如下接口:Serializable Externalizable
2.需要當前類提供全局常量serialVersionUID
3.除了當前自定義類需要實現Serializable接口之外, 還必須保證其內部所有屬性也必須是可序列化的。(默認情況下基本數據類型都是可序列化的)
4.序列化機制:
對象序列化機制允許把內存中的java對象轉換成平臺無關的二進制流,從而允許把這種 二進制流持久地保存在磁盤上,或通過網絡將這種二進制流傳輸到另一個網絡節點。 當其他程序獲取了這種二進制流,就可以恢復成原來的java對象。
隨機存取文件流
RandomAccessFile 類
1. RandomAccessFile 聲明在java.io包下,但直接繼承於java.lang.Object類。並且它實現了DataInput、DataOutput這兩個接口,也就意味着這個類既可以讀也可以寫。
2. RandomAccessFile 類支持 “隨機訪問” 的方式,程序可以直接跳到文件的任意地方來讀、寫文件
- 支持只訪問文件的部分內容
- 可以向已存在的文件後追加內容
3. RandomAccessFile 對象包含一個記錄指針,用以標示當前讀寫處的位置。 RandomAccessFile 類對象可以自由移動記錄指針:
- long getFilePointer():獲取文件記錄指針的當前位置
- void seek(long pos):將文件記錄指針定位到 pos 位置
4. 構造器
- public RandomAccessFile(File file, String mode)
- public RandomAccessFile(String name, String mode)
5. 創建 RandomAccessFile 類實例需要指定一個 mode 參數,該參數指定 RandomAccessFile 的訪問模式
- r: 以只讀方式打開
- rw:打開以便讀取和寫入 (若文件不存在,則會創建文件)
- rwd: 打開以便讀取和寫入;同步文件內容的更新
- rws: 打開以便讀取和寫入;同步文件內容和元數據的更新
讀取文件內容
RandomAccessFile raf = new RandomAccessFile(“test.txt”, “r”);
raf.seek(3);
byte [] b = new byte[1024];
int len = 5;
raf.read(b, 0, len);
String str = new String(b, 0, len);
System.out.println(str);
raf.close();
寫入文件內容
RandomAccessFile raf = new RandomAccessFile("test.txt", "rw");
raf.seek(3);
String temp = raf.readLine();
raf.seek(3);
raf.write("xyz".getBytes());
raf.write(temp.getBytes());
raf.close()