第17 章 : IO操作深入
80 字元編碼常用的編碼
1、GBK/GB2312 國标編碼, GB2312簡體中文,GBK包含簡體和繁體
2、ISO8859-1 國際通用編碼,描述所有字母
3、UNICODE 16進制存儲,描述所有問題
4、UTF 象形文字部分使用16進制,普通字母采用ISO8859-1,主要使用UTF-8
列出本機屬性
System.getProperties().list(System.out);
項目中出現亂碼問題就是編碼和解碼标準不統一
81 記憶體操作流
檔案操作流 以檔案為操作終端,InputStream、OutputStream
記憶體操作流
1、位元組記憶體操作流 ByteArrayOutputStream ByteArrayInputStream
2、字元記憶體操作流 CharArrayWriter CharArrayReader
繼承關系
OutputStream
-FileOutputStream
-ByteArrayOutputStream
InputStream
-FileInputStream
-ByteArrayInputStream
Writer
-OutputStreamWriter
-FileWriter
-CharArrayWriter
Reader
-InputStreamReader
-FileReader
-CharArrayReader
示例:利用記憶體流小寫轉大寫操作
import java.io.*;
class Demo{
public static void main(String[] args) throws IOException {
String message = "hello java";
// 将資料儲存到記憶體流中
InputStream input = new ByteArrayInputStream(message.getBytes());
OutputStream output = new ByteArrayOutputStream();
int data = 0;
// 每次讀取一個資料
while ((data = input.read())!=-1){
output.write(Character.toUpperCase(data));
}
System.out.println(output);
// HELLO JAVA
output.close();
input.close();
}
}
82 管道流
發送資訊 <- 管道 -> 接收資訊
位元組管道流 PipedInputStream, PipedOutputStream
字元管道流 PipedReader, PipedWriter
InputStream
-PipedInputStream
OutputStream
-PipedOutputStream
Reader
-PipedReader
Writer
-PipedWriter
管道發送接收資料
import java.io.*;
class Sender implements Runnable {
private PipedOutputStream output;
public Sender() {
this.output = new PipedOutputStream();
}
@Override
public void run() {
try {
this.output.write("你好".getBytes());
} catch (IOException e) {
e.printStackTrace();
}
try {
this.output.close();
} catch (IOException e) {
e.printStackTrace();
}
}
public PipedOutputStream getOutput() {
return this.output;
}
}
class Receiver implements Runnable {
private PipedInputStream input;
public Receiver() {
this.input = new PipedInputStream();
}
@Override
public void run() {
try {
byte[] data = new byte[1024];
int len = this.input.read(data);
System.out.println(new String(data, 0, len));
// 你好
} catch (IOException e) {
e.printStackTrace();
}
try {
this.input.close();
} catch (IOException e) {
e.printStackTrace();
}
}
public PipedInputStream getInput() {
return this.input;
}
}
class Demo {
public static void main(String[] args) throws IOException {
Sender sender = new Sender();
Receiver receiver = new Receiver();
// 管道連接配接
sender.getOutput().connect(receiver.getInput());
new Thread(sender).start();
new Thread(receiver).start();
}
}
83 RandomAccessFile
随機讀取類,可以移動檔案指針
public RandomAccessFile(String name, String mode)
import java.io.*;
class Demo {
public static void main(String[] args) throws IOException {
// 寫入
RandomAccessFile writer = new RandomAccessFile("demo.txt", "rw");
writer.write("你好世界".getBytes());
writer.close();
// 讀取
RandomAccessFile reader = new RandomAccessFile("demo.txt", "rw");
String line;
while ((line = reader.readLine()) != null) {
System.out.println(line);
}
writer.close();
}
}
第18 章 : 輸入與輸出支援
84 列印流
設計思想:裝飾設計模式
為OutputStream 類實作一層包裝
PrintStream
PrintWriter
OutputStream
-FilterOutputStream
-PrintStream
Writer
-PrintWriter
import java.io.*;
class Demo {
public static void main(String[] args) throws IOException {
PrintWriter writer = new PrintWriter(new FileWriter("demo.txt"));
// 換行輸出
writer.println("你好");
// 格式化輸出
writer.printf("姓名 %s, 年齡: %s", "小強", 23);
writer.close();
}
}
隻要是檔案内容輸出時都使用列印流
85 System類對IO的支援
System是系統類
1、标準輸出(顯示器)
2、錯誤輸出
3、标準輸入(鍵盤)
public final class System {
public final static InputStream in = null;
public final static PrintStream out = null; // 黑色字型
public final static PrintStream err = null; // 紅色字型
}
修改輸出位置
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintStream;
class Demo {
public static void main(String[] args) throws IOException {
System.setErr(new PrintStream(new FileOutputStream(new File("demo.txt"))));
System.err.println("你好");
}
}
接收鍵盤輸入(一般不用此方法)
import java.io.IOException;
import java.io.InputStream;
class Demo {
public static void main(String[] args) throws IOException {
InputStream input = System.in;
System.out.println("請輸入姓名:");
byte[] data = new byte[1024];
int len = input.read(data);
System.err.println(new String(data, 0, len));
}
}
86 BufferedReader緩沖輸入流
JDK < 1.5
緩沖字元輸入流
Reader
-BufferedReader
代碼示例
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
class Demo {
public static void main(String[] args) throws IOException {
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
System.out.println("請輸入:");
String msg = reader.readLine();
System.out.println(msg);
}
}
87 Scanner掃描流
JDK > 1.5
替代BufferedReader
構造函數
判斷是否有資料 public boolean hasNext()
讀取資料 public String next()
設定分隔符
import java.io.IOException;
import java.util.Scanner;
class Demo {
public static void main(String[] args) throws IOException {
Scanner scanner = new Scanner(System.in);
System.out.println("請輸入年齡:");
if(scanner.hasNextInt()){
int age = scanner.nextInt();
System.out.println("您輸入的年齡是:" + age);
} else{
System.out.println("輸入不正确");
}
scanner.close();
}
}
可以結合正則進行判斷驗證
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Scanner;
class Demo {
public static void main(String[] args) throws ParseException {
Scanner scanner = new Scanner(System.in);
System.out.println("請輸入生日:");
if (scanner.hasNext("\\d{4}-\\d{2}-\\d{2}")) {
String msg = scanner.next("\\d{4}-\\d{2}-\\d{2}");
System.out.println("您輸入的年齡是:" + new SimpleDateFormat("yyyy-MM-dd").parse(msg));
} else {
System.out.println("輸入不正确");
}
scanner.close();
}
}
讀取檔案
import java.io.File;
import java.io.FileNotFoundException;
import java.util.Scanner;
class Demo {
public static void main(String[] args) throws FileNotFoundException {
Scanner scanner = new Scanner(new File("demo.txt"));
// 設定換行分隔符
// scanner.useDelimiter("\n");
while (scanner.hasNext()) {
System.out.println(scanner.next());
}
scanner.close();
}
}
開發中:
輸出使用PrintWriter列印流
輸入使用Scanner掃描流
第19 章 : 對象序列化
88 對象序列化基本概念
對象序列化:
将記憶體中儲存的對象以二進制資料的形式處理,
實作對象的儲存或者網絡傳輸
儲存到檔案
堆記憶體 - 二進制轉換 -> 儲存到資料庫
發送到伺服器
要序列化的對象必須實作java.io.Serializable 接口
沒有任何方法,隻是描述一種能力
示例
import java.io.Serializable;
class Person implements Serializable {
private String name;
private int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
}
89 序列化與反序列化處理
InputStream(ObjectInput, ObjectStreamConstants)
-ObjectInputStream
OutputStream(ObjectOutput, ObjectStreamConstants)
-ObjectOutputStream
import java.io.*;
class Person implements Serializable {
private String name;
private int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
}
class Demo {
private static final File SAVE_FILE = new File("demo.person");
public static void main(String[] args) throws IOException, ClassNotFoundException {
Person person = new Person("Tom", 23);
// saveObject(person);
System.out.println(loadObject());
// Person@15aeb7ab
}
// 序列化
public static void saveObject(Object obj) throws IOException {
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(SAVE_FILE));
oos.writeObject(obj);
oos.close();
}
// 反序列化
public static Object loadObject() throws IOException, ClassNotFoundException {
ObjectInputStream ois = new ObjectInputStream(new FileInputStream(SAVE_FILE));
Object obj = ois.readObject();
ois.close();
return obj;
}
}
實際開發中不直接操作ObjectInputStream、ObjectOutputStream
90 transient關鍵字
表示進行序列化處理時,不處理被transient關鍵字修飾的字段
不常用,知道即可
IO繼承體系整合
// 位元組流:
OutputStream(Closeable, Flushable)
-FileOutputStream
-ByteArrayOutputStream
-PipedOutputStream
-FilterOutputStream
-PrintStream
-ObjectOutputStream
InputStream(Closeable)
-FileInputStream
-ByteArrayInputStream
-PipedInputStream
-ObjectInputStream
// 字元流:
Writer(Appendable, Closeable, Flushable)
-OutputStreamWriter
-FileWriter
-CharArrayWriter
-PipedReader
-PrintWriter
-BufferedWriter
Reader(Readable, Closeable)
-InputStreamReader
-FileReader
-CharArrayReader
-PipedWriter
-BufferedReader