IO 記憶體流和列印流操作 字元編碼 電腦中所有的信息組成都是二進位數據,所有能夠描述的中文文字都是經過處理後的結果;所有的語言文字都會使用編碼來進行描述,例如:ASCII碼 常見編碼 GBK/GB2312: 中文的國標編碼 GBK包含有簡體中文與繁體中文兩種,而GB2312只包含簡體中文 ISO ...
IO 記憶體流和列印流操作
字元編碼
- 電腦中所有的信息組成都是二進位數據,所有能夠描述的中文文字都是經過處理後的結果;所有的語言文字都會使用編碼來進行描述,例如:ASCII碼
常見編碼
GBK/GB2312:
- 中文的國標編碼
- GBK包含有簡體中文與繁體中文兩種,而GB2312只包含簡體中文
ISO-8859-1:
- 國際編碼
- 可以描述任何的文字信息
UNICODE:
- 十六進位編碼
- 任何文字信息都用十六進位表示,會導致無用數據過多
UTF-8:*
- 融合ISO8859-1和UNICODE兩種編碼的特點
字元亂碼
本質:
- 編碼與解碼的字元集不統一
列出系統的所有環境變數
public class TestDemo {
public static void main(String [] args) throws IOException {
System.getProperties().list(System.out);
}
}
- 輸出結果
file.encoding=UTF-8
代表系統環境預設的字元集編碼為:UTF-8
public class TestDemo {
public static void main(String [] args) throws IOException {
File file = new File("F:" + File.separator +
"demo" + File.separator +
"demo.txt");
OutputStream out = new FileOutputStream(file);
out.write("華為".getBytes());// getBytes() > 無轉碼
out.close();
}
}
上述是以預設的系統編碼方式進行輸出
華為
可以看出來,利用系統預設的編碼方式(不轉碼)編碼輸出,在用系統的編碼方式解碼,不會出現亂碼現象
public class TestDemo {
public static void main(String [] args) throws IOException {
File file = new File("F:" + File.separator +
"demo" + File.separator +
"demo.txt");
OutputStream out = new FileOutputStream(file);
out.write("華為".getBytes("ISO8859-1"));// getBytes() > 無轉碼
out.close();
}
}
我們利用getBytes()方法將進行轉碼為ISO8859-1編碼方式輸出
??
由結果看出,系統使用GB2312進行解碼,而文件是使用ISO8859-1進行編碼,編碼和解碼的字元集不同由此導致了 亂碼現象 的出現
記憶體操作流
- 在不產生新文件的情況下;利用記憶體流來實現輸入與輸出的操作
位元組記憶體流:
public class ByteArrayInputStream
extends InputStream
public class ByteArrayOutputStream
extends OutputStream
ByteArrayInputStream
- 構造方法
public ByteArrayInputStream(byte [] buf)
將要操作的數據設置到記憶體輸入流
ByteArrayOutputStream
- 構造方法
public ByteArrayOutputStream()
記憶體輸出流(輸出數據 )
toByteArray()*
public byte [] toByteArray()
- 將所有保存在記憶體中的位元組數據變為位元組數組存在
- 將兩個文件利用 toByteArray() 進行合併輸出*
public class TestDemo {
public static void main(String [] args) throws IOException {
File fileA = new File("F:" + File.separator + "demo" + File.separator + "demo.txt");
File fileB = new File("F:" + File.separator + "demo" + File.separator + "data.txt");
InputStream inA = new FileInputStream(fileA);
InputStream inB = new FileInputStream(fileB);
ByteArrayOutputStream output = new ByteArrayOutputStream();
int temp = 0 ;
while((temp = inA.read()) != -1) { //讀取A數據
output.write(temp);
}
while((temp = inB.read()) != -1) { //讀取B數據
output.write(temp);
}
// 讀取A,B文件結束後,將記憶體中的所有位元組數據轉為位元組數組
byte [] data = output.toByteArray();
inA.close();
inB.close();
output.close();
System.out.println(new String(data));
}
}
實例
public class TestDemo {
public static void main(String [] args) throws IOException {
String str = "Hello,World!";
InputStream in = new ByteArrayInputStream(str.getBytes());
// 將所有要讀取的數據設置大記憶體輸入流中
OutputStream out = new ByteArrayOutputStream();
// 記憶體輸出流
int temp = 0 ;// 讀取到的每一個位元組數據
while ((temp = in.read()) != -1) { // 每次讀取一個位元組數據
out.write(Character.toUpperCase(temp));//位元組輸出流
// temp數據轉大寫並輸出到記憶體輸出流當中
}
System.out.println(out);
in.close();
out.close();
}
}
字元記憶體流:
public class CharArrayReader
extends Reader
public class CharArrayWriter
extends Writer
列印流
接觸列印流
如果使用OutputStream,輸出String字元串數據,就需要將String變為位元組數組輸出getBytes(),同理boolean也需要變為Byte數據輸出……
package helloworld;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
class PrintUtil {
private OutputStream out; // 輸出依靠 OutputSteam類
public PrintUtil(OutputStream out) {
this.out = out ; //確定OutputStream的對象是File……或者ByteArray……
}
public void print(int x) throws IOException {
this.print(String.valueOf(x));//將x轉為String型
}
public void print(String x) throws IOException {
this.out.write(x.getBytes());
}
public void print(double x) throws IOException {
this.print(String.valueOf(x));//將x轉為String型
}
public void println(int x) throws IOException {
this.println(String.valueOf(x));
}
public void println(String x) throws IOException {
this.print(x.concat("\r\n"));
//在String字元串結尾添加字元[concat()]
}
public void println(double x) throws IOException {
this.println(String.valueOf(x));
}
public void close() throws IOException {//關閉輸出流
this.out.close();
}
}
public class TestDemo {
public static void main(String [] args) throws IOException {
// 調用PrintUtil類的構造方法,實例化對象
PrintUtil pu = new PrintUtil(
new FileOutputStream(
new File("F:"
+ File.separator + "demo"
+ File.separator + "demo.txt")));
pu.print("Hello,");
pu.println("World!");
pu.println(1+1);
pu.println(1.1+1.1);
pu.close();
}
}
PrintUtil類,則是為了方便列印而設計的一個工具類,在類中,我們通過調用print方法,可以將當前的數據轉為String後在轉為Byte型數據,可以方便我們的數據輸出;避免我們在代碼編寫過程中浪費時間來設計數據類型轉換為Byte位元組輸出。
列印流
- 為瞭解決上述的數據輸出時的功能不足問題,java.io包提供了一套專門用於輸出數據的類:PrintStream(列印位元組流) 和 PrintWriter(列印字元流)
PrintStream:位元組列印流
- 繼承結構
java.lang.Object
java.io.OutputStream
java.io.FileOutputStream
java.io.PrintStream
- 構造方法
PrintStream(OutputStream out)
在PrintStream類中提供了一系列和上述 PrintUtil 類相似的print()、println()方法;這些方法都可支持各種數據類型的輸出,同理:使用了PrintStream,那麼就可以不用去使用write()位元組流輸出方法了。
PrintStream類的實現本質上是基於OutputStream類實現的;這類的設計在Java中稱為 裝飾設計模式 相當於將一個功能不足的操作類,通過某些類的包裝實現成功能健全的更好的操作類。
- 實現 PrintStream
public class TestDemo {
public static void main(String [] args) throws IOException {
// 調用PrintStream類的構造方法,實例化對象
PrintStream pu = new PrintStream(
new FileOutputStream(
new File("F:"
+ File.separator + "demo"
+ File.separator + "demo.txt")));
pu.print("Hello,");
pu.println("World!");
pu.println(1+1);
pu.println(1.1+1.1);
pu.close();
}
}
將PrintUtil類刪除,使用PrintStream類代替,可以看出操作方法如出一轍。