【字節流】
OutputStream() 所有字節輸出流的超類
| --- FileOutputStream
| --- BufferedOutputStream 字節輸出流緩衝流
InputStream() 所有字節輸入流的超類
| --- FileInputStream
| --- BufferedInputStream 字節輸入流緩衝流
【開發常用的編碼表】 GBK 、UTF-8 、ISO-8859-1
【編碼和解碼】
把字符轉爲字節: 編碼 。"abc".getBytes() byte[]
把字節轉爲字符: 解碼。 byte[] ={97,98,99} new String(b)
如果編碼解碼的過程中使用了不同的編碼方式,就會出現亂碼現象。
GBK 編碼中,中文字符佔 2 個字節,英文字符佔 1 個字節。
UTF-8 編碼中,中文字符佔 3 個字節,英文字符佔 1 個字節。
String str1 = "中文";
byte[] bytes = str1.getBytes("UTF-8");
String str2 = new String(bytes, "UTF-8");
System.out.println(str2);
【字節輸出流OutputStream】抽象類
/*
* OutputStream(抽象類)
* 字節輸出流: java.io.OutputStream 所有字節輸出流的超類
* 作用:從java程序,寫出文件
* 字節:每次只操作文件中一個字節,可以寫任意文件
*
* write(int b) 將指定的字節寫入輸出流
* write(byte[] b) 寫將b.length個字節從指定的byte數組中寫入輸出流
* write(byte[],int off , int len) 將指定byte數組中從偏移量off開始的len個字節寫入次輸出流
* close() 關閉此輸出流,並釋放與之有關的所有系統資源
*
* 注意:流對象操作文件時,自己不做,所有操作依賴於系統資源
*/
【FileOutputStream類】文件寫入、續寫、換行
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
/*
* A. FileoutputStream 寫入數據文件
* 構造方法: 參數(File 封裝文件) (String 字符串的文件名)
*
* 流對象使用步驟:
* 1. 創建流子類的對象,綁定數據目的
* 2. 調用流對象的方法write寫
* 3. 釋放資源close
*
* 注意:流對象的構造方法,可以創建文件,如果文件存在直接覆蓋
*
* B. 文件的續寫和換行
*/
public class FileOutputStreamDemo1 {
public static void main(String[] args) throws IOException {
function_2();
}
//A. 寫入數據
public static void function_1() throws IOException{
FileOutputStream fos = new FileOutputStream("E:\\workspace\\Demo\\ab.txt");
// 流對象的方法write寫數據 寫入一個字節
// 1. 寫入文件是字母 d
fos.write(100);
// 寫入100
fos.write(49);
fos.write(48);
fos.write(48);
// 2. 寫字節數組 a b c d
byte[] bytes = {97,98,99,100};
fos.write(bytes);
// 寫字節數組額一部分 a b
fos.write(bytes,0,2);
// 寫入字節數組的簡便方式 寫入"Hello World" ,getBytes()將字符串轉爲字節
fos.write(" Hello World".getBytes());
// 關閉資源
fos.close();
}
//B. 文件的續寫和換行
// 1. 續寫:在FileOutputStream構造方法的第二個參數加入 true
// 2. 換行:寫入換行,符號換行 \r\n 可以寫在上一行的末尾 或 下一行的開頭
public static void function_2() throws IOException{
File file = new File("E:\\workspace\\Demo\\ab1.txt");
FileOutputStream fos = new FileOutputStream(file,true);
fos.write("Hello\r\n".getBytes());
fos.write("World".getBytes());
fos.close();
}
/* 打印輸出:
Hello
World
*/
}
【IO中的異常處理】
import java.io.FileOutputStream;
import java.io.IOException;
/*
* IO流的異常處理 try catch finally
*/
public class FileOutputStreamIOEDemo1 {
public static void main(String[] args) {
// 1.保證流對象 fos 變量 作用域足夠
FileOutputStream fos = null;
// try 外邊聲明變量,try內建立對象
try{
fos = new FileOutputStream("E:\\workspace\\Demo\\ab2.txt");
fos.write(100);
}catch(IOException ex){
System.out.println(ex.getMessage());
throw new RuntimeException("文件寫入失敗,重試");
}finally{
try{
//2. 若創建流對象失敗,即fos==null,不需要close
if(fos != null)
fos.close();
}catch(IOException ex){
throw new RuntimeException("關閉資源失敗");
}
}
}
}
【字節輸入流InputStream】超類
/*
* InputStream 所有字節輸入流的超類
* 作用:讀取任意文件,每次只讀取一個字節
* 讀取方法:
* int read() 讀取一個字節
* int read(byte[] b) 讀取一定量的字節,存儲到數組中
*/
【字節輸入流FileInputStream】
import java.io.FileInputStream;
import java.io.IOException;
/*
* FileInputStream 讀取文件
* 構造方法:爲這個流對象綁定數據源
* 參數(File 類型對象) (String 對象)
*
* 輸入流讀取文件的步驟:
* 1. 創建字節輸入流的子類對象
* 2. 調用讀取方法read 讀取
* 3. 關閉資源
*
* read()方法,read()執行一次,就會自動讀取下一字節
* 返回的是讀取到的字節,讀取到結尾後返回 -1
*/
public class FileInputDemo1 {
public static void main(String[] args) throws IOException {
FileInputStream fos = new FileInputStream("E:\\workspace\\Demo\\ab.txt"); // 文件中元素爲ABC
// 使用循環方法讀取文件一個字節,循環結束條件read()方法返回 -1
int len = 0;
while((len=fos.read()) != -1){
//System.out.println(len); // 65 66 67
System.out.print((char)len); // A B C
}
/* 注意
while(fos.read() != -1){
System.out.println(fos.read()); // 66 -1
}
*/
/*
// 獲取一個字節,調用方法read,返回int
int i = fos.read();
System.out.println(i); // 獲取的是65 但真實文件中是 A
i = fos.read();
System.out.println(i); // 獲取的是66 但真實文件中是 B
i = fos.read();
System.out.println(i); // 獲取的是67 但真實文件中是 C
i = fos.read();
System.out.println(i); // 文件中沒有元素,返回 -1
*/
// 關閉資源
fos.close();
}
}
import java.io.FileInputStream;
import java.io.IOException;
/*
* FileInputStream 讀取文件
* 讀取方法 int read(byte[] b)
* 參數:數組b起緩衝作用,提高效率
* 返回值int: 表示讀取到多少個有效的字節數
*/
public class FileInputDemo2 {
public static void main(String[] args) throws IOException {
FileInputStream fos = new FileInputStream("E:\\workspace\\Demo\\ab.txt"); // 文件中元素爲ABCDE
// 創建字節數組
byte[] b = new byte[2];
int len = 0;
// 使用循環讀取一個文件
while((len = fos.read(b)) != -1){
System.out.print(new String(b,0,len)); // ABCDE
}
// 關閉資源
fos.close();
}
}
/*
int len = fos.read(b);
System.out.println( new String(b)); // AB
System.out.println(len); // 2
len = fos.read(b);
System.out.println(new String(b)); // CD
System.out.println(len); // 2
len = fos.read(b);
System.out.println(new String(b)); // E
System.out.println(len); //
len = fos.read(b);
System.out.println(new String(b)); // E
System.out.println(len); //
*/
【字節流複製文件】效率最快的方法
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
/*
* 將數據源:E:\\workspace\\Demo\\a\\jdk+api+1.8_China.zip
* 複製到:E:\\workspace\\Demo\\b\\jdk+api+1.8_China.zip
*/
public class Copy {
public static void main(String[] args) {
// 定義兩個流對象變量
FileInputStream fis = null;
FileOutputStream fos = null;
try{
// 建立2個流對象,綁定數據源 和 數據目的
fis = new FileInputStream("E:\\workspace\\Demo\\a\\jdk+api+1.8_China.zip");
fos = new FileOutputStream("E:\\workspace\\Demo\\b\\jdk+api+1.8_China.zip");
// 採用數組緩存提高效率
byte[] b = new byte[1024];
int len = 0;
while((len = fis.read(b)) != -1){
fos.write(b,0,len);
}
}catch(IOException ex){
System.out.println(ex);
throw new RuntimeException("文件複製失敗");
}finally{
try{
if(fos != null)
fos.close();
}catch(IOException ex){
throw new RuntimeException("資源釋放失敗");
}finally{
try{
if(fis != null)
fis.close();
}catch(IOException ex){
throw new RuntimeException("資源釋放失敗");
}
}
}
}
}