一、數據流
1.流
在Java中把不同的數據源與程序之間的數據傳輸都抽象表述爲“流”(stream),以實現相對統一和簡單的輸入/輸出操作方式。傳輸中的數據就像流水一樣,也稱爲數據流。
2 .I/O數據流的分類方式
數據流分爲輸入流和輸出流兩類。輸入流只能讀取不能寫。而輸出流只能寫不能讀。(這裏站在程序的角度來確定出入方向,即將數據從程序外部傳送到程序中謂之“輸入”數據,將程序中的數據傳送到外部謂之“輸出”數據。)
二、字符流
1.字符輸入流Reader
Reader類爲所有面向字符的輸入流的超類,聲明爲java.io中的抽象類。
public int read():讀取一個字符,返回的是讀到的那個字符。如果讀到流的末尾,返回-1。
public int read(char[] cbuf):將讀到的字符存入指定的數組中,返回的是實際讀取的字符數。如果讀到流的末尾,返回-1。
public abstract int read(char[] cbuf,int off,int len):將讀到的字符存入數組的指定位置(off),每次最多讀len個字符,返回實際讀取的字符數。如果讀到流的末尾,返回-1。
close():讀取字符其實用的是window系統的功能,使用完畢後,進行資源的釋放。
2.字符輸出流writer
Weiter類爲所有面向字符的輸出流的超類,聲明爲java.io中的抽象類。
public void write(int c):將一個字符寫入到流中。
public void write(char[]):將數組中的字符依次寫出。
public abstract void write(char[] bcbuf,int off,int len):將數組中下標off開始的len個字符寫出。
public void write(String):將一個字符串寫入到流中。
public abstract void flush():刷新流,將流中的數據刷新到目的地中,流還存在。
public abstreact void close():關閉資源,關閉前會先調用flush,刷新流中的數據去目的地,然後流關閉。
三、FileWriter與FileReader區別與使用實例
FileWriter繼承了 java.io.OutputStreamWriter
FileReader繼承了 java.io.InputStreamReader
package com.zhoum.intelligentler.core;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
public class StreamDemo {
public static boolean fileWrite(String filePath){
try {
FileWriter fw = new FileWriter(filePath);//在filePath路徑下創建相應文件
char ch = '中';
char attr[] = {'a', 'b', 'c'};
fw.write(ch);
fw.write(attr);
fw.write("\t花旗無歡");
fw.write("\t1993-09-11");
fw.write("\t上海");
fw.flush();//只有輸出流需要刷新
fw.close();
return true;
} catch (IOException e) {
e.printStackTrace();
return false;
}
}
public static boolean fileRead(String filePath){
FileReader fr = null;
try {
fr = new FileReader(filePath);
char attr[] = new char[1024];
StringBuffer sb = new StringBuffer();
fr.read(attr);
for(char c : attr){
sb.append(c);
}
System.out.println(sb);
return true;
} catch (FileNotFoundException e) {
e.printStackTrace();
return false;
} catch (IOException e) {
e.printStackTrace();
return false;
} finally {
if (fr != null){
try {
fr.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
public static void main(String[] args) {
String filePath = "E:/test/demo.txt";//在java中,文件路徑在系統中是'\',但在java中爲'/'或'\\'
if (fileWrite(filePath)){
System.out.println("============開始讀取文件=============");
fileRead(filePath);
System.out.println("============結束讀取文件=============");
}
}
}
四、高效的輸入/輸出 BufferedReader與BufferedWriter
BufferedReader in = new BufferedReader(new FileReader(filePath));//讀指定目錄下的文件
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));//讀取控制檯輸入
從字符輸入流中讀取文本,緩衝各個字符,從而實現字符、數組和行的高效讀取。如果沒有緩衝,則每次調用 read() 或 readLine() 都會導致從文件中讀取字節,並將其轉換爲字符後返回,而這是極其低效的。
五、FileInputStream與FileOutputStream和FileWriter與FileReader的區別
1、概念
FileInputStream 用於讀取諸如圖像數據之類的原始字節流。要讀取字符流,請考慮使用 FileReader。
FileOutputStream 用於寫入諸如圖像數據之類的原始字節的流。要寫入字符流,請考慮使用 FileWriter。
2、繼承關係
java.lang.Object
繼承者 java.io.OutputStream
繼承者 java.io.FileOutputStream
java.lang.Object
繼承者 java.io.InputStream
繼承者 java.io.FileInputStream
FileInputStream與FileOutputStream直接繼承了InputStream與OutputStream
java.lang.Object
繼承者 java.io.Reader
繼承者 java.io.InputStreamReader
繼承者 java.io.FileReader
java.lang.Object
繼承者 java.io.Writer
繼承者 java.io.OutputStreamWriter
繼承者 java.io.FileWriter
FileWriter與FileReader還間接繼承了Writer與Reader
六、解決編碼問題
Writer writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(filePath),"GBK"));
Reader reader = new BufferedReader(new InputStreamReader(new FileInputStream(filePath), "GBK"));
FileInputStream(filePath)將指定文件的字節流向字符流的轉換。
InputStreamReader 進行讀取。可以設置編碼。
BufferedReader 設置緩衝區,可以高效輸出。
OutputStreamWriter 與 InputStreamReader是字符流通向字節流的橋樑:可使用指定的 charset 將要寫入流中的字符編碼成字節。
七、對象流 ObjectOutputStream與ObjectInputStream
對象流顧名思義就是在傳輸流中存放的是對象,在存儲的對象類中必須實現Serializable接口。
package com.zhoum.intelligentler.orm;
import java.io.Serializable;
public class User implements Serializable{
/**
*
*/
private static final long serialVersionUID = 1L;
private Integer id;
private String userName;
private String passWord;
private double salary;
public User(Integer id, String userName, String passWord, double salary){
this.id = id;
this.userName = userName;
this.passWord = passWord;
this.salary = salary;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getPassWord() {
return passWord;
}
public void setPassWord(String passWord) {
this.passWord = passWord;
}
public double getSalary() {
return salary;
}
public void setSalary(double salary) {
this.salary = salary;
}
}
對象輸入和輸出流實例
public static void objectWrite(String filePath){
ObjectOutputStream oos = null;
try {
oos = new ObjectOutputStream(new FileOutputStream(filePath));
User user = new User(1, "花旗無歡", "1234656", 8888);
User user2 = new User(2, "程序員", "aaa", 6666);
User[] users = new User[2];
users[0] = user;
users[1] = user2;
oos.writeObject(users);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if(oos!=null){
try {
oos.flush();
oos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
public static void objectRead(String filePath){
ObjectInputStream ois = null;
try {
ois = new ObjectInputStream(new FileInputStream(filePath));
User[] users = (User[]) ois.readObject();
for(User user : users){
System.out.println("id=" + user.getId()
+ " userName=" + user.getUserName()
+ " password=" + user.getPassWord()
+ " salary=" + user.getSalary());
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
} finally {
if(ois != null){
try {
ois.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
運行結果:
id=1 userName=花旗無歡 password=1234656 salary=8888.0
id=2 userName=程序員 password=aaa salary=6666.0