2017 - 10 -27 IO流 字符流 字符緩衝流

1 轉換流
由於字節流操作中文不是特別方便,所以,java就提供了轉換流
字符流=字節流+編碼表

2 編碼表
編碼表:由現實世界的字符和對應的數值組成的一張表
ASCII碼錶:最高位位符號位,其餘爲數值位
      'a'  97
      'A'  65
      '0'  48

ASCII:美國標準信息交換碼。
用一個字節的7位可以表示。
ISO8859-1:拉丁碼錶。歐洲碼錶,用一個字節的8位表示。
GB2312:中國的中文編碼表。
GBK:中國的中文編碼表升級,融合了更多的中文文字符號。
GB18030:GBK的取代版本
BIG-5碼 :通行於臺灣、香港地區的一個繁體字編碼方案,俗稱“大五碼”。
Unicode:國際標準碼,融合了多種文字。
所有文字都用兩個字節來表示,Java語言使用的就是unicode
UTF-8:最多用三個字節來表示一個字符。(國際化)
UTF-8不同,它定義了一種“區間規則”,這種規則可以和ASCII編碼保持最大程度的兼容:它將Unicode編碼爲00000000-0000007F的字符,用單個字節來表示 它將Unicode編碼爲00000080-000007FF的字符用兩個字節表示? 它將Unicode編碼爲00000800-0000FFFF的字符用3字節表示?

3 String類中的編碼和解碼問題
String(byte[] bytes,String charsetName):通過制定的字符串解碼字節數組
byte[] getBytes(String charsetName):使用制定的字符集合把字符串編碼爲字節數組

編碼:把看得懂的編程看不懂的
String -- byte[]
解碼:把看不懂的編程看的懂得
byte[] -- String

String s = "你好";

//String -- byte[]
byte[] bys = s.getBytes();//{-60,-29,-70,-61}
//byte[] bys = s.getBytes("GBK");//{-60,-29,-70,-61}
byte[] bys = s.getBytes("UTF-8");//{-28,-67,-96,-27,-91,-67}
System.out.println(Arrays.toString(bys));//{-60,-29,-70,-61}

//byte[] -- String
//String ss = new String(bys);//你好
//String ss = new String(bys,"GBK");//你好
//String ss = new String(bys,"UTF-8");//???
System.out.println(ss);

4 轉換流
(1)
OutputStreamWriter(OutputStream out):根據默認編碼把字節流的數據轉換爲字符流
OutputStreamWriter(OutputStream out,String charsetName):根據制定該編碼把字節流數據轉換爲字符流
把字節流轉換爲字符流
字符流=字節流+編碼表
//創建對象
OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("osw.txt"));//指定默認GBK
//寫數據
osw.write("中國");
//釋放資源
osw.close();

(2)
InputStreamWriter(InputStream is):用默認的編碼讀取數據
InputStreamWriter(InputStream is,String charsetName):用指定的編碼讀取數據
//創建對象
InputStreamWriter isr = new InputStreamReader(new FileInputStream("osw.txt"));
//讀取數據
//一次讀取一個字符
int ch = 0;
while((ch = isr.read())!=-1){
    System.out.print((char) ch);
}
//釋放資源
isr.close();

5 字符流
(1) 5種寫數據的方式
OutputStreamWriter
public void write(int c):寫一個字符
public void write(char[] cbuf):寫一個字符數組
public void write(char[] cbuf,int off,int len):寫一個字符數組的一部分
public void write(String str):寫一個字符串
public void write(String str,int off,int len):寫一個字符串的一部分
------------------------------------
面試題:close()和flush()的區別?
A:close()關閉流對象,但是先刷新一次緩衝區,關閉之後,該對象不可以繼續再使用了。
B:flush()s僅僅刷新緩衝區,刷新之後,該對象還可以繼續使用
------------------------------------
//創建對象
OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("osw2.txt"));
//寫數據
//public void write(int c):寫一個字符
//osw.write('a');
//osw.write(97);
//爲什麼數據沒有進去呢?
//原因是:字符=2字節
//文件中數據存儲的基本單位是字節
//void flush()

//public void write(char[] cbuf):是一個字符數組
char[] chs = {'a','b','c','d','e'};
osw.write(chs);

//public void write(char[] cbuf,int off,int len):寫一個字符數組的一部分
osw.write(chs,1,3);

//public void write(String str):寫一個字符串
osw.write("喵喵喵")

//public void write(String str,int off,int len):寫一個字符串的一部分
osw.write("喵喵喵",2,3)

//刷新緩衝區
osw.flush();

//釋放資源
osw.close(); //close的作用是先刷新再釋放

(2) 兩種讀數據的方式
InputStreamWriter
int read():一次讀取一個字符
int read(char[] chs):一次讀取一個字符數組
--------------------------------------------
//創建對象
InputStreamWriter isr = new InputStreamWriter(new FileInputStream("StringDemo.java"));
//一次讀取一個字符
//int ch = 0;
//while((ch = isr.read())!=-1){
//  System.out.print((char)ch);
//}

//一次讀取一個字符數組
char[] chs = new char[1024];
int len =0;
while((len=isr.read(chs))!=-1){
   System.out.print(new String(chs,0,len));
}

6 字符流賦值文本
數據源:
      a.txt -- 讀取數據 -- 字符轉換流 -- InputStreamReader
目的地:
      b.txt -- 寫出數據 -- 字符轉換流 -- OutputStreamWriter

(1) 複製
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
public class CopyFileDemo {
public static void main(String[] args) throws IOException {
// 封裝數據源
InputStreamReader isr = new InputStreamReader(new FileInputStream(
"a.txt"));
// 封裝目的地
OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream(
"b.txt"));

// 讀寫數據
// 方式1
// int ch = 0;
// while ((ch = isr.read()) != -1) {
// osw.write(ch);
// }

// 方式2
char[] chs = new char[1024];
int len = 0;
while ((len = isr.read(chs)) != -1) {
osw.write(chs, 0, len);
// osw.flush();
}

// 釋放資源
osw.close();
isr.close();
}
}

(2) 簡化版
由於我們常見的操作都是使用本地默認編碼,所以,不用指定編碼。
而轉換流的名稱有點長,所以,java就提供了其子類供我們使用、
OutputStreamWriter = FileOutputStream + 編碼表(GBK)
FileWriter = FileOutputStream + 編碼表(GBK)
InputStreamReader = FileInputStream + 編碼表(GBK)
FileReader = FileInputStream + 編碼表(GBK)
------------------------------------------------
需求:把當前項目目錄下的a.txt內容複製到當前項目目錄下的b.txt中
a.txt -- 讀取數據 -- 字符轉換流 -- InputStreamReader -- FileReader
b.txt -- 寫出數據 -- 字符轉換流 -- OutputStreamWriter -- FileWriter
// 封裝數據源
FileReader fr = new FileReader("a.txt");
// 封裝目的地
FileWriter fw = new FileWriter("b.txt");

// 一次一個字符
// int ch = 0;
// while ((ch = fr.read()) != -1) {
// fw.write(ch);
// }

// 一次一個字符數組
char[] chs = new char[1024];
int len = 0;
while ((len = fr.read(chs)) != -1) {
fw.write(chs, 0, len);
fw.flush();
}

// 釋放資源
fw.close();
fr.close();

7 字符緩衝流
BufferredReader:字符緩衝輸入流
BufferredWriter:字符緩衝輸出流
BufferedReader 字符緩衝輸入流
從字符輸入流中讀取文本,緩衝各個字符,從而實現字符、數組和行的高效讀取。 
可以指定緩衝區的大小,或者可使用默認的大小。大多數情況下,默認值就足夠大了。 
// 創建字符緩衝輸入流對象
BufferedReader br = new BufferedReader(new FileReader("bw.txt"));

// 方式1
// int ch = 0;
// while ((ch = br.read()) != -1) {
// System.out.print((char) ch);
// }

// 方式2
char[] chs = new char[1024];
int len = 0;
while ((len = br.read(chs)) != -1) {
System.out.print(new String(chs, 0, len));
}

// 釋放資源
br.close();
-------------------------------------------
BufferedWriter:字符緩衝輸出流
將文本寫入字符輸出流,緩衝各個字符,從而提供單個字符、數組和字符串的高效寫入。 
可以指定緩衝區的大小,或者接受默認的大小。在大多數情況下,默認值就足夠大了。 
// BufferedWriter(Writer out)
// BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(
// new FileOutputStream("bw.txt")));
BufferedWriter bw = new BufferedWriter(new FileWriter("bw.txt"));
bw.write("hello");
bw.write("world");
bw.write("java");
bw.flush();
bw.close();
}

8 字符緩衝流的特殊方法
BufferedReader
 public void newLine():根據系統來決定換行符
BufferedWrite
 public String readLine():一次讀取一行數據
 包含該行內容的字符串,不包含任何終止符,如果已達到末尾,則返回null

   //創建字符流緩衝輸出對象
   BufferedWriter bw = new BufferedWriter(new FileWriter("bw.txt"));
   //換行
   for(int x = ;x<0;x++){
        bw.write("hello"+x);
      //bw.write("\r\n");
        bw.newLine();
   }
   bw.close();

   //創建字符流緩衝輸入對象
   BufferedReader br = new BufferedReader(new FileReader("bw.txt"));
   //public String readLine():一次讀取一行數據
   //String line =br.readLine();
   //System.out.println(line);
   //line = br.readLine();
   //System.out.println(line);
    
   //最終版代碼
     String line =null;
     while((line=br.readLine())!=-1){
           System.out.println(line);
     }
   //釋放資源
     br.close();

9 IO流小結

10 字符流五種複製文本方式
String srcString = "c:\\a.txt";
String destString = "d:\\b.txt";
// method1(srcString, destString);
// method2(srcString, destString);
// method3(srcString, destString);
// method4(srcString, destString);
method5(srcString, destString);
}

     ***推薦使用// 字符緩衝流一次讀寫一行數據
private static void method5(String srcString, String destString)
throws IOException {
BufferedReader br = new BufferedReader(new FileReader(srcString));
BufferedWriter bw = new BufferedWriter(new FileWriter(destString));
String line = null;
while ((line = br.readLine()) != null) {
bw.write(line);
bw.newLine();
bw.flush();
}
bw.close();
br.close();
}

// 字符緩衝流一次讀寫一個字符數組
private static void method4(String srcString, String destString)
throws IOException {
BufferedReader br = new BufferedReader(new FileReader(srcString));
BufferedWriter bw = new BufferedWriter(new FileWriter(destString));
char[] chs = new char[1024];
int len = 0;
while ((len = br.read(chs)) != -1) {
bw.write(chs, 0, len);
}
bw.close();
br.close();
}

// 字符緩衝流一次讀寫一個字符
private static void method3(String srcString, String destString)
throws IOException {
BufferedReader br = new BufferedReader(new FileReader(srcString));
BufferedWriter bw = new BufferedWriter(new FileWriter(destString));
int ch = 0;
while ((ch = br.read()) != -1) {
bw.write(ch);
}
bw.close();
br.close();
}


// 基本字符流一次讀寫一個字符數組
private static void method2(String srcString, String destString)
throws IOException {
FileReader fr = new FileReader(srcString);
FileWriter fw = new FileWriter(destString);
char[] chs = new char[1024];
int len = 0;
while ((len = fr.read(chs)) != -1) {
fw.write(chs, 0, len);
}
fw.close();
fr.close();
}

// 基本字符流一次讀寫一個字符
private static void method1(String srcString, String destString)
throws IOException {
FileReader fr = new FileReader(srcString);
FileWriter fw = new FileWriter(destString);
int ch = 0;
while ((ch = fr.read()) != -1) {
fw.write(ch);
}
fw.close();
fr.close();
}
}

11 複製圖片的四種方式
複製數據,如果我們知道用記事本打開並能夠讀懂,就用字符流,否則用字節流。
所以複製圖片用字節流。
而字節流有4種方式,所以做這個題目我們有4種方式。推薦掌握第4種。
// 使用File對象做爲參數
File srcFile = new File("c:\\a.jpg");
File destFile = new File("d:\\b.jpg");
// method1(srcFile, destFile);
// method2(srcFile, destFile);
// method3(srcFile, destFile);
method4(srcFile, destFile);
}

     ***推薦使用// 字節緩衝流一次讀寫一個字節數組
private static void method4(File srcFile, File destFile) throws IOException {
BufferedInputStream bis = new BufferedInputStream(new FileInputStream(
srcFile));
BufferedOutputStream bos = new BufferedOutputStream(
new FileOutputStream(destFile));
byte[] bys = new byte[1024];
int len = 0;
while ((len = bis.read(bys)) != -1) {
bos.write(bys, 0, len);
}
bos.close();
bis.close();
}

// 字節緩衝流一次讀寫一個字節
private static void method3(File srcFile, File destFile) throws IOException {
BufferedInputStream bis = new BufferedInputStream(new FileInputStream(
srcFile));
BufferedOutputStream bos = new BufferedOutputStream(
new FileOutputStream(destFile));
int by = 0;
while ((by = bis.read()) != -1) {
bos.write(by);
}
bos.close();
bis.close();
}

// 基本字節流一次讀寫一個字節數組
private static void method2(File srcFile, File destFile) throws IOException {
FileInputStream fis = new FileInputStream(srcFile);
FileOutputStream fos = new FileOutputStream(destFile);
byte[] bys = new byte[1024];
int len = 0;
while ((len = fis.read(bys)) != -1) {
fos.write(bys, 0, len);
}
fos.close();
fis.close();
}

// 基本字節流一次讀寫一個字節
private static void method1(File srcFile, File destFile) throws IOException {
FileInputStream fis = new FileInputStream(srcFile);
FileOutputStream fos = new FileOutputStream(destFile);
int by = 0;
while ((by = fis.read()) != -1) {
fos.write(by);
}
fos.close();
fis.close();
}
}

12 集合---文本文件
(1)把集合中的數據存儲到文本文件
    // 封裝數據與(創建集合對象)
ArrayList<String> array = new ArrayList<String>();
array.add("hello");
array.add("world");
array.add("java");
// 封裝目的地
BufferedWriter bw = new BufferedWriter(new FileWriter("a.txt"));
// 遍歷集合
for (String s : array) {
// 寫數據
bw.write(s);
bw.newLine();
bw.flush();
}
// 釋放資源
bw.close();
(2)從文本文件讀取數據到集合中
// 封裝數據源
BufferedReader br = new BufferedReader(new FileReader("b.txt"));
// 封裝目的地(創建集合對象)
ArrayList<String> array = new ArrayList<String>();
// 讀取數據存儲到集合中
String line = null;
while ((line = br.readLine()) != null) {
array.add(line);
}
// 釋放資源
br.close();
// 遍歷集合
for (String s : array) {
System.out.println(s);
      }
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章