緩沖流
緩沖流也稱為高效流、或者高級流。之前學習的字節流也可以稱為原始流。
作用:緩沖流自帶緩沖區,可以提高原始字節流、字符流讀取數據的性能。
形象舉例:倘若我們將對文件的輸入和輸出操作想象為運輸水的過程的話,在最初的時候,水(數據)是直接對接水管進行運輸,而緩沖流的不同之處在于水不需要對接水管,僅需要和水管前的水缸進行對接,這么做可以提高了運輸的效率。
緩沖流分為兩種,一種是字節緩沖流,另一種則是字符緩沖流。分別是BufferedInputStream(字節緩沖輸入流)、BufferedOuputStream(字節緩沖輸出流)、BufferedReader(字符緩沖輸入流)、BufferedWriter(字符緩沖輸出流)。
字節緩沖流
字節緩沖輸入流:BufferedInputStream,提高字節輸入流讀取數據的性能,讀寫功能上并無變化
字節緩沖輸出流:BufferedOutputStream, 提高字節輸出流讀取數據的性能,讀寫功能上并無變化
構造器
說明
public BufferedInputStream(InputStream is)
可以把低級的字節輸入流包裝成一個高級的字節緩沖輸入流管道,從而提高字節輸入流讀數據的性能
public BufferedOutputStream(OutputStream os)
可以把低級的字節輸出流包裝成一個高級的字節緩沖輸出流管道,從而提高寫數據的性能
InputStream is = new FileInputStream("File//data.txt");
InputStream bis = new BufferedInputStream(is);
OutputStream os = new FileOutputStream("File//data01.txt");
OutputStream bos = new BufferedOutputStream(os);
int len;
byte []buffer = new byte[1024];
while ((len = bis.read(buffer))!=-1){
bos.write(buffer,0,len);
bos.flush();
通過字節緩沖流實現將一個文件中的內容復制在另一個文件之中。
字符緩沖流
字符緩沖輸入流:BufferedReader,提高字符輸入流讀取數據的性能,除此之外多了按照行讀取數據的功能
構造器
說明
public BufferedReader(Reader r)
可以把低級的字符輸入流包裝成一個高級的緩沖字符輸入流管道,從而提高字符輸入流讀數據的性能
方法
說明
public String readLine()
讀取一行數據返回,如果讀取沒有完畢,無行可讀取返回null
Reader r = new FileReader("File//data.txt");
BufferedReader br = new BufferedReader(r);//由于是子類獨有的功能,所有不能使用多態創建
String s;
byte []buffer = new byte[1024];
while ((s = br.readLine())!=null){
System.out.println(s);
}
//正常情況下會將文件中的數據依次輸出;
Reader r = new FileReader("File//data.txt");
BufferedReader br = new BufferedReader(r);
br.readLine();
br.readLine();
//若文件中的數據不足兩行:
//kdirvingJamesJame
//null
字符緩沖輸出流:BufferedWriter,提高字符輸出流寫取數據的性能,除此之外多了換行功能
構造器
說明
public BufferedWriter(Writer w)
可以把低級的字符輸出流包裝成一個高級的緩沖字符輸出流管道,從而提高字符輸出流寫數據的性能
方法
說明
public void newLine()
執行操作
Writer w = new FileWriter("File//data.txt",true);
BufferedWriter bw = new BufferedWriter(w);//由于是子類獨有的功能,所有不能使用多態創建
bw.write("石原里美");
bw.newLine();
bw.write("工藤靜香");
bw.newLine();
bw.flush();
需要留意的地方是,在寫文件的時候如果想要對文件進行追加操作,需要對Writer的對象設置true,而不是BufferedWriter的對象。
轉換流
在學習轉換流之前,我們應該要了解的是如果代碼編碼和文件編碼如果不一致。使用字符流直接讀取會造成亂碼,因此我們需要代碼編碼和文件編碼一致,才能保證不會亂碼,而轉換流的出現就是為了能夠避免這種事情的發生的。
字符輸入轉換流
首先是對于亂碼的問題提供一個簡單的思路:
1、使用字符輸入轉換流;
2、可以提取文件(不同的編碼)的原始字節流,原始字節不會存在問題;
3、將字節流以指定編碼轉換成字符輸入流,這樣字符輸入流中的字符就不會亂碼了。
字符輸入轉換流:InputStreamReader,可以把原始字節流按照指定編碼轉換成字符輸入流
構造器
說明
public InputStreamReader(InputStream is)
可以把原始的字節流按照代碼默認編碼轉換成字符輸入流。幾乎不用
public InputStreamReader(InputStream is,String charset)
可以把原始的字節流按照指定指定編碼轉換成字符輸入流,這樣字符流中的字符就不亂碼了
InputStream is = new FileInputStream("File//data.txt");
InputStreamReader isr = new InputStreamReader(is);
InputStreamReader isr = new InputStreamReader(is,"GBK");
在以上代碼中,已知將data.txt文件的編碼格式設置為GBK,而代碼編碼是utf-8,所以需要通過轉換流將編碼變為一致。而一種構造器默認utf-8,顯然是不行的,第二種則是可以指定編碼,將原始的字節輸入流轉換為字符輸入流,并以GBK的形似進行讀取。
字符輸出轉換流
字符輸出轉換流:OutputStreamWriter,可以把字節輸出流按照指定編碼轉換成字符輸出流
構造器
說明
public OutputStreamWriter(OutputStream os)
可以把原始的字節輸出流按照代碼默認編碼轉換成字符輸出流,幾乎不用
public OutputStreamWriter(OutputStream os,String charset)
可以把原始的字節輸出流按照指定的編碼轉換成字符輸出流
首先我們應該知道字符輸出轉換流是為了應對哪些現實中的事情:假如你的客戶智能編碼為GBK的文件,那么你給他傳過去一個utf-8的文件的話,文件是會亂碼的,那么這個時候就需要我們傳過去一個編碼為GBK的文件。
OutputStream os = new FileOutputStream("File//data.txt");
Writer osw = new OutputStreamWriter(os);
Writer osw = new OutputStreamWriter(os,"GBK");
在以上代碼中,第一種是默認utf-8的,所以是幾乎不用的,而第二種則是可以指定客戶需要的編碼文件格式。
序列化和反序列化
對象序列化
對象字節輸出流,ObjectOutputStream
作用:以內存為基準,把內存中的對象存儲到磁盤文件中去,稱為對象序列化
構造器
說明
public ObjectOutputStream(OutputStream os)
把低級字節輸出流包裝成高級的對象字節輸出流
首先是簡單的創建了一個學生類Student,需要注意的是Java規定對象序列化的時候,類需要實現Serializable接口。
public class Student implements Serializable {
private String name;
private int age;
private String number;
private String classroom;
}
接下來則是實現對象的序列化的操作:
Student s = new Student("石原里美",18,"001","智能一班");
OutputStream os = new FileOutputStream("File//data.txt");
ObjectOutputStream oos = new ObjectOutputStream(os);
oos.writeObject(s);
oos.close();
另外如果不希望對象中的某個數據不參與序列化,則可以通過transient對其進行修飾,如“private transient String name”,執行該操作之后,對其進行反序列化的時候該數據會顯示null。
對象反序列化
對象字節輸入流,ObjectInputStream
作用:以內存為基準,把存儲到磁盤文件中去的對象數據恢復成內存中的對象,稱為對象反序列化
構造器
說明
public ObjectInputStream(InputStream is)
把低級字節輸入流包裝成高級的對象字節輸入流
方法名稱
說明
public Object readObject()
把存儲到磁盤文件中去的對象數據恢復成內存中的對象返回
InputStream is = new FileInputStream("File//data.txt");
ObjectInputStream ois = new ObjectInputStream(is);
Object s = ois.readObject();
System.out.println(s);
//輸出結果:
//Student{name='石原里美', age=18, number='001', classroom='智能一班'}
另外還有一個知識點,在定義類的時候,可以定義一個版本序列號,而在反序列號的時候,其序列號必須一致才可以正常的讀取,如“private static final long serialVersionUID = 1;”
若在第一次序列化之后,將類中的版本序列號更改,在沒有作第二次重新序列化之前,反序列化會出現報錯的情況。
打印流
作用:打印流可以實現方便、高效的打印數據到文件中去。一般指PrintStream,WriteStream兩個類
可以實現打印什么數據就是什么數據,例如打印整數97,寫出去就是97,打印boolean的true,寫出去就是true
構造器
說明
public PrintStream(OutputStream os)
打印流直接通向字節輸出流管道
public PrintStream(File f)
打印流直接通向文件對象
public PrintStream(String filepath)
打印流直接通向文件路徑
方法名稱
說明
public void print(Xxx xx)
打印任意類型的數據出去
//三種構造器的使用
PrintStream ps = new PrintStream("File//data01.txt");
PrintStream ps1 = new PrintStream(new File("File//data.txt"));
PrintStream ps2 = new PrintStream(new FileOutputStream(new File("File//data.txt")));
ps.print(11);
ps.print("凱里·歐文");
PrintStream和WriterStream的區別:
打印數據功能上是一模一樣,都是使用方便,性能高效
PrintStream繼承字節輸出流OutputStream,支持寫字節數據的方法
PrintWriter繼承字符輸出流Writer,支持寫字符出去
Properties
作用:Properties代表的是一個屬性文件可以把自己對象中的鍵值對信息存入到一個屬性文件中去
屬性文件:后綴是.properties結尾的文件,里面的內容都是key=value,后續做系統配置信息的
構造器
說明
void load (InputStream is)
從輸入字節流讀取屬性列表(鍵值對)
void load (Reader r)
從輸入字符流讀取屬性列表(鍵值對)
void store (OutputStream os,String comments)
將此屬性列表(鍵值對)寫入此Properties中,以適合于使用load(InputStream)方法的格式輸出字節流
void store(Writer w,String comments)
將此屬性列表(鍵值對)寫入此Properties中,以適合于使用load(reader)方法的格式輸出字符流
public Object setProperty(String key,String value)
保存鍵值對(put)
public String getProperty(String key)
使用此屬性列表中指定的鍵搜索屬性值(get)
public Set<String> stringPropertyNames()
所有鍵的名稱的集合(keySet())
Properties properties = new Properties();
properties.setProperty("石原里美","18");
properties.setProperty("工藤靜香","19");
properties.setProperty("朱茵","20");
System.out.println(properties);
//第一個參數是文件存儲路徑,第二個是對文件的注釋
properties.store(new FileWriter("File//Baby.properties"),"這些都是絕世美女,不接受反駁哈哈哈");
Properties properties = new Properties();
properties.load(new FileReader("File//Baby.properties"));
System.out.println(properties);
//輸出結果:
//{"石原里美"=18,"工藤靜香"=19,"朱茵"=20}
本站文章版權歸原作者及原出處所有 。內容為作者個人觀點, 并不代表本站贊同其觀點和對其真實性負責,本站只提供參考并不構成任何投資及應用建議。本站是一個個人學習交流的平臺,網站上部分文章為轉載,并不用于任何商業目的,我們已經盡可能的對作者和來源進行了通告,但是能力有限或疏忽,造成漏登,請及時聯系我們,我們將根據著作權人的要求,立即更正或者刪除有關內容。本站擁有對此聲明的最終解釋權。