目錄
節點流和處理流的總述
位元組緩沖流
字符緩沖流
轉換流
資料流
物件流
列印流
節點流和處理流的總述
- 節點流:可以從或向一個特定的地方(節點)讀寫資料,如FileReader.
- 處理流:是對一個已存在的流的連接和封裝,通過所封裝的流的功能呼叫實作資料讀寫,所有處理流的最底層都是節點流,一個流物件經過其他流的多次包裝,稱為流的鏈接,
JAVA常用的節點流:
- 文 件 FileInputStream / FileOutputStrean / FileReader / FileWriter 檔案進行處理的節點流,
- 字串 StringReader / StringWriter 對字串進行處理的節點流,
- 數 組 ByteArrayInputStream / ByteArrayOutputStream / CharArrayReader / CharArrayWriter 對陣列進行處理的節點流(對應的是記憶體中的一個陣列),
- 管 道 PipedInputStream / PipedOutputStream / PipedReader / PipedWriter對管道進行處理的節點流,
常用處理流(關閉處理流使用關閉里面的節點流)
- 緩沖流:BufferedInputStrean / BufferedOutputStream / BufferedReader / BufferedWriter -Buffered 增加緩沖功能,避免頻繁讀寫硬碟,
- 轉換流:InputStreamReader / OutputStreamReader -實作位元組流和字符流之間的轉換,
- 資料流:DataInputStream / DataOutputStream -提供將基礎資料型別寫入到檔案/記憶體陣列中,或者讀取,保留了資料和資料型別,
- 物件流:ObjectInputStream / ObjectOutputStream -除了能處理基本資料和字串外,還包括各種物件,用法類似資料流,
流的關閉順序:
- 一般情況下是:先打開的后關閉,后打開的先關閉
- 對于有依賴關系的流:如果流a依賴流b,應該先關閉流a,再關閉流b,例如,處理流a依賴節點流b,應該先關閉處理流a,再關閉節點流b
- 可以只關閉處理流,不用關閉節點流,因為處理流關閉的時候,會呼叫其處理的節點流的關閉方法,
位元組緩沖流
位元組緩沖流可以提高讀寫操作的效率,可以減少硬碟的讀寫時間,默認的緩沖區大小是8K,
import java.io.*;
// 檔案位元組輸入流,加入快取流
public class BufferedTest01 {
public static void main(String[] args) {
File src = new File("D:/Java/IO/abc.txt");
BufferedInputStream is = null;
try{
is = new BufferedInputStream(new FileInputStream(src)); //把選擇的節點流放入處理流
byte[] flush = new byte[1024]; //緩沖容器,常用1024
int len = -1; //接受長度
while((len=is.read(flush))!=-1){
// 位元組陣列—》字串
String str = new String(flush,0,len);
System.out.println(str);
}
} catch(IOException e){
e.printStackTrace();
} finally {
try{
if(null!=is){
is.close();
}
}catch (IOException e){
e.printStackTrace();
}
}
}
}
字符緩沖流
import java.io.*;
public class BufferedTest02 {
public static void main(String[] args) {
File src = new File("D:/Java/IO/abc.txt");
BufferedReader reader = null;
try{
reader = new BufferedReader(new FileReader(src));
// 分行讀取
String line = null;
while((line=reader.readLine())!=null){
System.out.println(line);
}
}catch(IOException e){
e.printStackTrace();
}finally{
try{
if(null!=reader){
reader.close();
}
}catch(IOException e){
e.printStackTrace();
}
}
}
}
轉換流
InputStreamReader:從位元組流轉換為字符流,讀取位元組,使用指定的charset將其解碼為字符,為了效率,通常會包裝在BufferedReader里面,
OutputStreamReader:從字符流轉換為位元組流,為了效率,通常會包裝在BufferedWriter里面,
import java.io.*;
/*
* 轉換流
* 1. 以字符流的形式操作位元組流(純文本)
* 2,指定字符集
* */
public class ConverTest {
public static void main(String[] args) {
// 操作System.in 和 System.out
BufferedReader reader = null;
BufferedWriter writer = null;
try{
reader = new BufferedReader(new InputStreamReader(System.in,"UTF-8"));
writer = new BufferedWriter(new OutputStreamWriter(System.out));
// 回圈獲取鍵盤的輸入(exit退出),輸出此內容
String msg = "";
while(!msg.equals("exit")){
msg = reader.readLine();
writer.write(msg);
writer.newLine();
writer.flush(); //如果不強制重繪,那么只有當快取滿了,才會寫出,
};
}catch(IOException e){
e.printStackTrace();
}finally {
try{
if(null!=writer){
writer.close();
}
}catch(IOException e){
e.printStackTrace();
}
try{
if(null!=reader){
reader.close();
}
}catch(IOException e){
e.printStackTrace();
}
}
}
運行效果:
資料流
資料流提供將基礎資料型別寫入到檔案/記憶體陣列中,或者讀取,保留了資料和資料型別
import java.io.*;
/*
* 資料流:
* 1.寫出后讀取
* 2.讀取的順序與寫出保持一致
* DataOutputStream/DataInputStream
* */
public class DataTest {
public static void main(String[] args) throws IOException {
// 寫出
ByteArrayOutputStream baos = new ByteArrayOutputStream();
DataOutputStream dos = new DataOutputStream(new BufferedOutputStream(baos));
// 操作資料型別+資料
dos.writeUTF("編碼創世界");
dos.writeBoolean(true);
dos.writeInt(18);
dos.flush();
byte[] datas = baos.toByteArray();
System.out.println(datas.length);
//讀取
DataInputStream dis = new DataInputStream(new BufferedInputStream(new ByteArrayInputStream(datas)));
//讀取順序與寫出一致,順序不一致會出現錯誤
String msg = dis.readUTF();
boolean flag = dis.readBoolean();
int age = dis.readInt();
System.out.println(flag);
System.out.println(msg);
}
}
運行結果:
物件流
物件流除了能處理基本資料和字串外,還包括各種物件,用法類似資料流,將物件轉換成二進制資料流,
通過ObjectOutputStream,Object轉換為Stream of bytes,稱為序列化;反過來的程序,稱為反序列化,
注:只有有標識的物件,才可以序列化,
如果序列化的 JDK 版本和反序列化的 JDK 版本不統一,則可能造成例外,因此在序列化操作中引入了一個serialVersionUID 的常量來驗證版本的一致性,
import java.io.*;
import java.util.Date;
/*
* 物件流
* 1.寫出后讀取
* 2.讀寫順序一致
* 3.不是所有的物件都可以序列化,物件需要有Serializable介面
* */
public class ObjectTest {
public static void main(String[] args) throws IOException, ClassNotFoundException {
// 寫出
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream dos = new ObjectOutputStream(new BufferedOutputStream(baos));
// 操作資料型別+資料
dos.writeUTF("編碼創世界");
dos.writeBoolean(true);
dos.writeInt(18);
//加入物件
dos.writeObject("哈哈哈哈哈");
dos.writeObject(new Date());
dos.flush();
byte[] datas = baos.toByteArray();
//讀取
ObjectInputStream ois = new ObjectInputStream(new BufferedInputStream(new ByteArrayInputStream(datas)));
//讀取順序與寫出一致,順序不一致會出現錯誤
String msg = ois.readUTF();
boolean flag = ois.readBoolean();
int age = ois.readInt();
System.out.println(flag);
System.out.println(msg);
System.out.println(age);
Object str = ois.readObject();
Object date = ois.readObject();
//需要手動強制轉換類的型別
if(str instanceof String){ //如果是其實體
String strObj = (String)str;
System.out.println(strObj);
}
if(date instanceof Date){ //如果是其實體
Date dateObj = (Date)date;
System.out.println(dateObj);
}
}
}
運行結果:
補充小知識點:
transient表示該資料不需要序列化 ![]()
列印流
PrintStream,作用可以簡化代碼
import java.io.BufferedOutputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.PrintStream;
//PrintStream使用類似PrintWriter
public class PrintTest01 {
public static void main(String[] args) throws FileNotFoundException {
PrintStream ps = System.out;
ps.println("列印流");
ps.println(true);
//自動列印到檔案中
ps = new PrintStream(new BufferedOutputStream(new FileOutputStream("print.txt")));
ps.println(123456);
ps.flush();
ps.close();
//重定向輸出端
System.setOut(ps);
System.out.println("change");
}
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/242468.html
標籤:其他
