IO概述
分類
IO流根據傳輸方向分爲兩種:輸入流(讀),輸出流(寫)
根據單位:字節流(java.io.InputStream,java.io.OutputStream),字符流(java.io.Reader,java.io.Writer)
上面是InputStream,下面是OutputStream
σ_›σ 原諒我從百度隨便摳的圖☝☝☝
字節流(文本,圖片,音頻,視頻)
在JDK中提供兩個抽象類InputStream,OutputStream作爲字節流的頂級父類。可以把InputStream,OutputStream比作兩根水管。
InputStream輸入管道,源設備—>程序
OutputStream輸出管道,程序—>目標設備
最後一定要關閉管道!!避免浪費資源!!
下面是最完整的寫法:
OutputStream out = null;
try {
out = new FileOutputStream(file);
out.write(content.getBytes());
} catch (IOException e) {
e.printStackTrace();
} finally {//finally一定會執行,所以在這裏關流
try {
if (out != null)
out.close();
} catch (IOException e) {
e.printStackTrace();
} finally {
out = null;//交付給gc
}
}
拷貝文件
public void copy_Paste(String srcPath,String destPath) throws Exception{
FileInputStream fis = new FileInputStream(srcPath);
FileOutputStream fos = new FileOutputStream(destPath);
下面提供4種方法進行拷貝
/**1.一個個字節:效率低**/
int data1 = fis.read();
while(data1!=-1){
fos.write((char)data1);
data1 = fis.read();
}
/**2.用一個數組作爲緩衝**/
byte[] buff = new byte[1024];
int total = fis.read(buff);
while(total!=-1){
fos.write(buff);
total = fis.read(buff);
}
/**3.緩衝流**/
BufferedInputStream bis = new BufferedInputStream(fis);
BufferedOutputStream bos = new BufferedOutputStream(fos);
int data2 = bis.read();
while(data2!=-1){
bos.write(data2);
data2 = bis.read();
/**4.數據輸入輸出流**/
DataInputStream dis = new DataInputStream(fis);//包裝了fis
DataOutputStream dos = new DataOutputStream(fos);
int d = dis.readInt();
dos.writeInt(d);
while(dis.available()>0){
d = dis.readInt();
dos.writeInt(d);
//關流 先關輸入再關輸出,不然水管會爆。。
dis.close();
dos.close();
//由於DataInputStream,DataOutputStream是包裝流
//所以下面兩行可以不用寫
fis.close();
fos.close();
字符流(文本文件)
參考上面第四點
標準輸入輸出流
在System類中定義了三個常量:in,out,err,它們被習慣性地稱爲標準輸入輸出流
常量 | 類型 | 流 | 作用 |
---|---|---|---|
in | InputStream | 標準輸入流 | 默認用於讀取鍵盤輸入的數據 |
out | PrintStream | 標準輸出流 | 默認將數據輸出到命令行窗口 |
err | PrintStream | 標準錯誤流 | 與out類似,通常輸出的是應用程序運行時的錯誤信息 |
File類
File類用於封裝一個路徑
public void copy_Paste(String srcPath,String destPath) {
copy_Paste(new File(srcPath),new File(destPath));
}
亂碼問題
產生原因
字符=字節+編碼
字節是計算機信息技術用於計量存儲容量的一種計量單位,因此字節流也稱爲萬能流 而編碼方式不同,可能導致字符和字節的換算方式不同,可能1字符=2字節,也可能1字符=3字節
編碼是將數據轉化爲二進制的過程,解碼則是編碼的逆過程 因此,亂碼問題都出現在解碼過程中
注意:下圖字符集中只有GBK可以對漢字進行編碼(以GB開頭的編碼方式都包含中文字符)
再比如:”中文”二字的GBK的字節流爲d6 d0 ce c4,如果用utf-8(不支持中文)去解碼,勢必會亂碼。
解決方法
- 指定read,write編碼
InputStreamReader(InputStream in, CharsetDecoder dec)
創建使用給定字符集解碼器的 InputStreamReader。OutputStreamWriter(OutputStream out, CharsetEncoder enc)
創建使用給定字符集編碼器的 OutputStreamWriter。
- 重新編碼,怎麼來怎麼回
String(byte[] bytes, Charset charset)
通過使用指定的 charset 解碼指定的 byte 數組,構造一個新的 String。