詳細介紹了Java IO中的基本檔案位元組流FileInputStream、FileOutputStream的方法以及使用方式。
文章目錄
- 1 FileInputStream檔案位元組輸入流
-
- 1.1 構造器
- 1.2 API方法
-
- 1.2.1 補充
- 2 FileOutputStream檔案位元組輸出流
-
- 2.1 構造器
- 2.2 API方法
-
- 2.2.1 補充
- 3 案例
-
- 3.1 寫入檔案
- 3.2 讀取檔案
- 3.3 拷貝檔案
1 FileInputStream檔案位元組輸入流
public abstract class InputStream
extends Object
implements Closeable
此抽象類是表示位元組輸入流的所有類的超類。需要定義 InputStream 子類的應用程式必須總是提供傳回下一個輸入位元組的方法。
public class FileInputStream
extends InputStream
和檔案相關的位元組輸入流,讀取檔案位元組資料。
1.1 構造器
建立一個對象,建立的時候,指定一個抽象路徑。如果指定檔案不存在,或者它是一個目錄,而不是一個正常檔案,抑或因為其他某些原因而無法打開進行讀取,則抛出 FileNotFoundException。
通過打開一個到實際檔案的連接配接來建立一個 FileInputStream。如果指定檔案不存在,或者它是一個目錄,而不是一個正常檔案,抑或因為其他某些原因而無法打開進行讀取,則抛出 FileNotFoundException。
1.2 API方法
一次讀取一個位元組,能夠讀取英文。讀取中文時,會出現亂碼,因為中文占兩個位元組,一次隻能讀取半個漢字。
傳回 0 到 255 範圍内的 int類型位元組Unicode值;如果到達流的末尾,則傳回-1。
從輸入流中讀取一定數量的位元組,并将其存儲在緩沖區數組 b 中。
傳回一次讀入緩沖區的總位元組數;如果因為已經到達流末尾而不再有資料可用,則傳回 -1,即讀取到的位元組數為-1。緩沖區的位元組将會被後面讀入的位元組重索引0開始一一覆寫!
傳回檔案當中剩餘(未讀取)的位元組個數。
1.2.1 補充
使用位元組流讀取檔案時:
- 使用read()方法,不能直接讀取中文,因為中文占兩個位元組,而read讀取一個位元組。
- 使用read(byte b[])方法,可能會讀取不到中文(數組最後索引為中文)。
- 使用available和read(byte b [])結合,可以讀取中文,但是如果檔案過大,可能會造成記憶體溢出,導緻程式卡頓等問題。是以适用于自己明确檔案大小不會很大的時候。
2 FileOutputStream檔案位元組輸出流
public abstract class OutputStream
extends Object
implements Closeable, Flushable
OutputStream抽象類是所有位元組輸出流的基類。
public class FileOutputStream
extends OutputStream
和檔案相關的位元組輸出流,向檔案輸出位元組資料。
2.1 構造器
建立具有指定名稱的檔案,指定一個字元串抽象路徑。路徑檔案不存在,則建立;存在,則覆寫;指定路徑的盤符不存在或者檔案是目錄則不建立并抛出異常。以下三個構造器同理!等同于調用FileOutputStream(name,false);
建立具有指定名稱的檔案,指定一個字元串抽象路徑。append:如果為 true,則将位元組寫入檔案末尾處,而不是寫入檔案開始處,即追加寫檔案而不是覆寫。
建立一個向指定 File 對象表示的檔案中寫入資料的檔案輸出流。
建立一個向指定 File 對象表示的檔案中寫入資料的檔案輸出流。如果第二個參數為 true,則将位元組寫入檔案末尾處,而不是寫入檔案開始處。建立一個新 FileDescriptor 對象來表示此檔案連接配接。
2.2 API方法
将指定的位元組寫入此輸出流。
要寫入的位元組是參數b的八個低位,b 的24個高位将被忽略。因為參數類型是int,它是一個32位二進制數,占4個位元組,而一個位元組隻需要占8位,要轉換為Unicode對應字元輸出,是以隻需要取低位8位即可。
将 b.length 個位元組從指定的 byte 數組寫入此輸出流。等效于調用 write(b, 0, b.length)
将指定 byte 數組中從偏移量 off 開始的 len 個位元組寫入此輸出流。
将數組 b 中的某些位元組按順序寫入輸出流:元素 b[off] 是此操作寫入的第一個位元組,b[off+len-1] 是此操作寫入的最後一個位元組。
public void flush();
public void close();
2.2.1 補充
計算機是如何識别什麼時候該把兩個位元組轉換為一個中文呢?
在計算機中,中文的存儲分兩個位元組:
第一個位元組肯定是負數。第二個位元組常見的是負數,可能有正數。但是沒影響。即計算機讀到負數就會把該數和後面的數拼起來,然後再去編碼表裡面查詢即可轉換為中文展示出來。
3 案例
3.1 寫入檔案
public class FileOutputStreamDemo01 {
public static void main(String[] args) throws IOException {
FileOutputStream fo = new FileOutputStream("C:\\Users\\lx\\Desktop\\test.txt");
String test = "Aa你好呀";
byte[] bytes = test.getBytes();
System.out.println(Arrays.toString(bytes));
//寫位元組
fo.write(bytes);
fo.flush();
fo.close();
}
/**
* 追加寫入
*/
@Test
public void test1() throws IOException {
FileOutputStream fo = new FileOutputStream("C:\\Users\\lx\\Desktop\\test.txt", true);
String test = "aA你好呀";
byte[] bytes = test.getBytes();
for (byte aByte : bytes) {
fo.write(aByte);
}
fo.flush();
fo.close();
}
}
3.2 讀取檔案
位元組流可以操作任何類型的檔案,如果要讀取檔案檔案,隻需要先讀取檔案的位元組資料,然後将位元組數組轉換為String字元串即可。
public class FileInputStreamdemo01 {
public static void main(String[] args) throws IOException {
FileInputStream fi = new FileInputStream("C:\\Users\\lx\\Desktop\\test.txt");
int i;
/*while((i=fi.read())!=-1)
{
System.out.print((char)i); //傳回的是一個位元組的字元的ASCII值,列印應該轉換為字元 不能讀取中文
}*/
/*byte []by=new byte[3];
while ((i=fi.read(by))!=-1)
{
System.out.print(new String(by,0,i)); //可能讀取不到中文
}*/
//一次讀取全部,能讀取中文,但是如果檔案過大會造成記憶體溢出.
byte[] by = new byte[fi.available()];
while ((i = fi.read(by)) != -1) {
System.out.print(new String(by, 0, i));
}
fi.close();
}
}
3.3 拷貝檔案
使用位元組流可以操作任何類型的檔案,除了文本檔案之外,這裡的拷貝還可以拷貝圖檔、視訊等等非文本類型的檔案。
public class CopyFile {
public static void main(String[] args) {
//拷貝圖檔測試
String str1 = "C:\\Users\\lx\\Desktop\\test.jpg";
String str2 = "C:\\Users\\lx\\Desktop\\test2.jpg";
// copy(str1, str2);
//拷貝視訊測試
String str3 = "C:\\Users\\lx\\Desktop\\test.wmv";
String str4 = "C:\\Users\\lx\\Desktop\\test2.wmv";
copy(str3, str4);
}
public static void copy(String str1, String str2) {
FileInputStream fi = null;
FileOutputStream fo = null;
try {
fi = new FileInputStream(str1);
fo = new FileOutputStream(str2);
byte[] by = new byte[1024];
int i;
while ((i = fi.read(by)) != -1) {
fo.write(by, 0, i);
fo.flush();
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (fi != null) {
try {
fi.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (fo != null) {
try {
fo.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
如有需要交流,或者文章有誤,請直接留言。另外希望點贊、收藏、關注,我将不間斷更新各種Java學習部落格!