文件流:使用文件輸入流讀取文件中的數據:
public class FISDemo {public static void main(String[] args) throws IOException {//將fos.dat文件中的字節讀取回來/*fos.dat文件中的數據:00000001 00000010*/FileInputStream fis = new FileInputStream("fos.dat");
java.io.InputStream(所有字節輸入流的超類)定義著讀取字節的相關方法
? ? ? ? ? ? int read()
? ? ? ? ? ? 讀取1個字節并以int型整數返回讀取到的字節內容,返回的int值中對應的2進制的"低八位"
? ? ? ? ? ? 就是讀取到的數據。如果返回的int值為整數-1(這是一個特殊值,32位2進制全都是1)表達是流讀取到了末尾了。
?
int read(byte[] data)
文件輸入流重寫了上述兩個方法用來從文件中讀取對應的字節。
?fos.dat文件中的數據:
? ? ? ? ? ? ?00000001 00000010
? ? ? ? ? ? ?^^^^^^^^
? ? ? ? ? ?第一次讀取的字節
? ? ? ? ? ? ?當我們第一次調用:
? ? ? ? ? ? ?int d = fis.read();//讀取的是文件中第一個字節
? ? ? ? ? ? ?該int值d對應的2進制:
? ? ? ? ? ? ?00000000 00000000 00000000 00000001
? ? ? ? ? ? ?|------自動補充24個0-------| ^^^^^^^^
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 讀取到的數據
? ? ? ? ? ? ?而該2進制對應的整數就是1.
int d = fis.read();//讀取到的就是整數1System.out.println(d);
fos.dat文件中的數據:
? ? ? ? ? ? ?00000001 00000010
? ? ? ? ? ? ? ? ? ? ? ^^^^^^^^
? ? ? ? ? ? ? ? ? ? ?第二次讀取的字節
? ? ? ? ? ? ?當我們第二次調用:
? ? ? ? ? ? ?d = fis.read();//讀取的是文件中第二個字節
? ? ? ? ? ? ?該int值d對應的2進制:
? ? ? ? ? ? ?00000000 00000000 00000000 00000010
? ? ? ? ? ? ?|------自動補充24個0-------| ^^^^^^^^
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 讀取到的數據
? ? ? ? ? ? ?而該2進制對應的整數就是2.
d = fis.read();//2System.out.println(d);
fos.dat文件中的數據:
? ? ? ? ? ? ?00000001 00000010 文件末尾
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?^^^^^^^^
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 沒有第三個字節
? ? ? ? ? ? ?當我們第三次調用:
? ? ? ? ? ? ?d = fis.read();//讀取到文件末尾了!
? ? ? ? ? ? ?該int值d對應的2進制:
? ? ? ? ? ? ?11111111 11111111 11111111 11111111
? ? ? ? ? ? ?該數字是正常讀取1個字節永遠表達不了的值。并且-1的2進制格式好記。因此用它表達讀取到了末尾。
d = fis.read();//-1System.out.println(d);fis.close();
文件復制
利用文件輸入流與輸出流實現文件的復制操作
public class CopyDemo {public static void main(String[] args) throws IOException {//用文件輸入流讀取待復制的文件
// FileInputStream fis = new FileInputStream("image.jpg");FileInputStream fis = new FileInputStream("01.rmvb");//用文件輸出流向復制文件中寫入復制的數據
// FileOutputStream fos = new FileOutputStream("image_cp.jpg");FileOutputStream fos = new FileOutputStream("01_cp.rmvb");/*原文件image.jpg中的數據10100011 00111100 00001111 11110000....^^^^^^^^讀取該字節第一次調用:int d = fis.read();d的2進制:00000000 00000000 00000000 10100011讀到的字節fos向復制的文件image_cp.jpg中寫入字節第一次調用:fos.write(d);作用:將給定的int值d的2進制的"低八位"寫入到文件中d的2進制:00000000 00000000 00000000 10100011寫出字節調用后image_cp.jpg文件數據:10100011*//*循環條件是只要文件沒有讀到末尾就應該復制如何直到讀取到末尾了呢?前提是:要先嘗試讀取一個字節,如果返回值是-1就說明讀到末尾了如果返回值不是-1,則說明讀取到的是一個字節的內容,就要將他寫入到復制文件中*/int d;//先定義一個變量,用于記錄每次讀取到的數據long start = System.currentTimeMillis();//獲取當前系統時間while ((d = fis.read()) != -1) {fos.write(d);}long end = System.currentTimeMillis();System.out.println("復制完畢!耗時:" + (end - start) + "ms");fis.close();fos.close();}
}
塊讀寫的文件復制操作
nt read(byte[] data) 一次性從文件中讀取給定的字節數組總長度的字節量,并存入到該數組中。 返回值為實際讀取到的字節量。若返回值為-1則表示讀取到了文件末尾。
塊寫操作 void write(byte[] data) 一次性將給定的字節數組所有字節寫入到文件中
void write(byte[] data,int offset,int len) 一次性將給定的字節數組從下標offset處開始的連續len個字節寫入文件中里面:
/*** 通過提高每次讀寫的數據,減少讀寫次數可以提高讀寫效率。*/
public class CopyDemo2 {public static void main(String[] args) throws IOException {FileInputStream fis = new FileInputStream("01.rmvb");FileOutputStream fos = new FileOutputStream("01_cp.rmvb");/*塊讀:一次性讀取一組字節塊寫:一次性將寫出一組字節java.io.InputStream上定義了塊讀字節的方法:int read(byte[] data)一次性讀取給定字節數組length個字節并從頭開始裝入到數組中。返回值為實際讀取到的字節量如果返回值為-1則表示流讀取到了末尾。文件流重寫了該方法,作用是塊讀文件里的數據。java.io.OutputStream上定義了塊寫字節的方法:void write(byte[] data)一次性將給定的字節數組中所有的字節寫出。void write(byte[] data,int offset,int len)一次性將給定的字節數組data中從下標offset處開始的連續len個字節寫出。原文件數據(假設文件共6個字節):11110000 00001111 01010101 11111111 00000000 10101010byte[] buf = new byte[4];//創建一個長度為4的字節數組buf默認的樣子(每個元素若以2進制表現):{00000000,00000000,00000000,00000000}int len;//記錄每次實際讀取的字節數當第一次調用:len = fis.read(buf);由于字節數組buf的長度為4.因此可以一次性最多從文件中讀取4個字節并裝入到buf數組中返回值len表示的整數是這次實際讀取到了幾個字節。原文件數據(假設文件共6個字節):11110000 00001111 01010101 11111111 00000000 10101010^^^^^^^^ ^^^^^^^^ ^^^^^^^^ ^^^^^^^^第一次讀取的4個字節buf:{11110000,00001111,01010101,11111111}len:4 表示本次讀取到了4個字節第二次調用:len = fis.read(buf);原文件數據(假設文件共6個字節):11110000 00001111 01010101 11111111 00000000 10101010 文件末尾了^^^^^^^^ ^^^^^^^^ ^^^^^^^^ ^^^^^^^^本次實際只能讀取到2個字節buf:{00000000,10101010,01010101,11111111}|本次新讀的2字節數據| |---上次的舊數據---|len:2表示本次實際只讀取到了2個字節。它的意義就是告訴你buf數組中前幾個字節是本次真實讀取到的數據第三次調用:len = fis.read(buf);原文件數據(假設文件共6個字節):11110000 00001111 01010101 11111111 00000000 10101010 文件末尾了^^^^^^^^ ^^^^^^^^ ^^^^^^^^ ^^^^^^^^buf:{00000000,10101010,01010101,11111111} 沒有任何變化!len:-1 表示本次讀取時已經是文件末尾了!!*//*00000000 8位2進制 1byte 1字節1024byte = 1kb1024kb = 1mb1024mb = 1gb1024gb = 1tb*//*編譯完該句代碼:byte[] buf = new byte[10240];在實際開發中,有時候用一個計算表達式更能表現這個值的含義時,我們不妨使用計算表達式long t = 864000000;long t = 60 * 60 * 24 * 1000;*/byte[] buf = new byte[1024 * 10];//10kbint len;//記錄每次實際讀取到的字節數long start = System.currentTimeMillis();while ((len = fis.read(buf)) != -1) {fos.write(buf, 0, len);}long end = System.currentTimeMillis();System.out.println("復制完畢,耗時:" + (end - start) + "ms");fis.close();fos.close();}
}
寫文本數據
String提供方法: byte[] getBytes(String charsetName) 將當前字符串轉換為一組字節
參數為字符集的名字,常
/*** 使用文件輸出流向文件中寫入文本數據*/
public class WriteStringDemo {public static void main(String[] args) throws IOException {/*1:創建一個文件輸出流2:將寫出的文字先轉換為2進制(一組字節)3:關閉流文件流有兩種創建方式:1:覆蓋模式,對應的構造器:FileOutputStream(String filename)FileOutputStream(File file)所謂覆蓋模式:文件流在創建是若發現該文件已存在,則會將該文件原內容全部刪除。然后在陸續將通過該流寫出的內容保存到文件中。 */FileOutputStream fos = new FileOutputStream("fos.txt",true);String line = "讓我再看你一遍,從南到北。";/*String提供了將內容轉換為一組字節的方法:getBytes()java.nio.charset.StandardCharsets*/byte[] data = line.getBytes(StandardCharsets.UTF_8);fos.write(data);line = "像是北五環路蒙住的雙眼。";data = line.getBytes(StandardCharsets.UTF_8);fos.write(data); System.out.println("寫出完畢!");fos.close();}
}```### 文件輸出流-追加模式重載的構造方法可以將文件輸出流創建為追加模式- FileOutputStream(String path,boolean append)
- FileOutputStream(File file,boolean append)當第二個參數傳入true時,文件流為追加模式,即:指定的文件若存在,則原有數據保留,新寫入的數據會被順序的追加到文件中
用的是UTF-8。 其中中文字3字節表示1個,英文1字節表示1個。