JavaIO
Java中IO的基本概況,以及在使用過程中涉及到的序列化,同時將Roaringbitmap的序列化以及反序列化做個編寫示例
JAVA中IO流體系
1.四大IO抽象類
一、文件 字節流
讀取和寫入:
利用文件流實現文件的復制
二、文件 字符流
使用FileReader與FileWriter實現文本文件的復制
三、緩沖 字節流: BufferedInputStream 和 BufferedOutputStream 這兩個流是緩沖字節流,通過內部緩存數組來提高操作流的效率
四、緩沖 字符流
字節流在操作時本身不會用到緩沖區(內存),是文件本身直接操作的,
而字符流在操作時使用了緩沖區,通過緩沖區再操作文件
從文件的角度
FileInputStream 通過字節的方式讀取文件,適合讀取所有類型的文件(圖像、視頻、文本文件等)。
Java也提供了 FileReader 專門讀取文本文件。
FileOutputStream 通過字節的方式寫數據到文件中,適合所有類型的文件。
Java也提供了 FileWriter 專門寫入文本文件
2.input stream of bytes
InputStream 和 OutputStream 是字節流的兩個頂層父類,提供了輸入流類和輸出流類的通用API
java.io.DataInput
DataInput 接口用於從二進制流中讀取字節,並重構所有 Java 基本類型數據
DataOutput 接口提供將數據從任何Java基本類型轉換為一系列字節,並將這些字節寫入二進制流
DataInputStream 是數據輸入流。它繼承於FilterInputStream。
public class DataInputStream extends FilterInputStream implements DataInput {}
構造函數 DataInputStream(InputStream in)
public abstract class InputStream implements Closeable {
* @see java.io.BufferedInputStream
* @see java.io.ByteArrayInputStream
* @see java.io.DataInputStream
* @see java.io.FilterInputStream
* @see java.io.InputStream#read()
* @see java.io.OutputStream
* @see java.io.PushbackInputStream
*/
public abstract class OutputStream implements Closeable, Flushable {}
* that writes one byte of output.
* @see java.io.BufferedOutputStream
* @see java.io.ByteArrayOutputStream
* @see java.io.DataOutputStream
* @see java.io.FilterOutputStream
* @see java.io.InputStream
* @see java.io.OutputStream#write(int)
*/
3.a new byte array output stream
ByteArrayOutputStream
outRR.deserialize(new DataInputStream(new ByteArrayInputStream(outBytes)));
inRR.deserialize(new DataInputStream(new ByteArrayInputStream(inBytes)));
outRR.or(inRR);
ByteArrayOutputStream bos = new ByteArrayOutputStream();
outRR.serialize(new DataOutputStream(bos));
result = bos.toByteArray();
ByteArrayOutputStream.toByteArray() 將緩沖區的數據全部獲取出來,返回字節數組,
然后通過string 的方法,使用指定的字符集,通過解碼字節將緩沖區內容轉換為字符串
4. deserialize 和 serialize
序列化和反序列化 將對象轉換成與平台無關的二進制流 序列化機制可以使對象可以脫離程序的運行而對立存在。
如何實現對象的序列化:
Java io 分類方式
根據是否直接處理數據,
Java io又分為節點流和處理流,節點流是真正直接處理數據的;處理流是裝飾加工節點流的
節點流
文件流: FileInputStream FileOutputStrean FileReader,FileWriter,它們都會直接操作文件,直接與 OS 底層交互。因此他們被稱為節點流 ,注意:使用這幾個流的對象之后,需要關閉流對象,因為 java 垃圾回收器不會主動回收。不過在 Java7 之后,可以在 try() 括號中打開流,最后程序會自動關閉流對象,不再需要顯示地 close。
數組流: ByteArrayInputStream ByteArrayOutputStream CharArrayReader,CharArrayWriter,對數組進行處理的節點流。
字符串流: StringReader StringWriter,其中 StringReader 能從 String 中讀取數據並保存到 char 數組。
管道流: PipedInputStream PipedOutputStream PipedReader,PipedWrite,對管道進行處理的節點流。
處理流
處理流 處理流的構造方法總是要帶一個其他的流對象做參數。
處理流是對一個已存在的流的連接和封裝,通過所封裝的流的功能調用實現數據讀寫。如 BufferedReader。
緩沖流 :BufferedImputStrean,BufferedOutputStream,BufferedReader ,BufferedWriter,
需要父類作為參數構造,增加緩沖功能, 避免頻繁讀寫硬盤,可以初始化緩沖數據的大小,由於帶了緩沖功能,所以就寫數據的時候需要使用 flush 方法
ByteArrayInputStream StringBufferInputStream FileInputStream
是三種基本的介質流,它們分別從 Byte 數組、StringBuffer、和本地文件中讀取數據
字節輸入流
BufferedOutputStream (輸入流)、 BufferedInputStream (輸出流)
DataOutputStream (輸入流)、 DataInputStream (輸出流):
數據字節輸入輸出流(高級流),
在用該流進行文件復制時,不支持復制視頻音頻文件,會出現編碼錯誤,只支持普通文件。
InputStream InputStream這個抽象類是所有基於字節的輸入流的超類,抽象了Java的字節輸入模型
PUBLIC class FileInputStream extends InputStream
PUBLIC class FilterInputStream extends InputStream {
PUBLIC class BufferedInputStream extends FilterInputStream {
PUBLIC class DataInputStream extends FilterInputStream implements DataInput {
PUBLIC class ObjectInputStream extends InputStream implements ObjectInput, ObjectStreamConstants
PUBLIC class ByteArrayInputStream extends InputStream {
public class PipedInputStream extends InputStream {
PUBLIC class PushbackInputStream extends FilterInputStream {
PUBLIC class SequenceInputStream extends InputStream {
序列化介質
將對象序列化存儲到本地文件中去,
將對象序列化成byte[]存放到緩存中
序列化到文件
public class JavaSerializableExp {
public static void main(String[] args) {
PairObj obj = new PairObj(200, 2,"mylife");
String fileString = "F:\\sources\\sfm.txt";
try {
//file對應相應的.txt文件
File file = new File(fileString);
//步驟一:創建一個 ObjectOutputStream 輸出流;
//步驟二:調用 ObjectOutputStream 對象的 writeObject 輸出可序列化對象。
//將對象寫入ObjectOutputStream中 , 再轉化到FileOutputStream並輸出到文件中
//通過重寫writeObject與readObject方法,可以自己選擇哪些屬性需要序列化, 哪些屬性不需要
FileOutputStream fos = new FileOutputStream(file);
ObjectOutputStream oos = new ObjectOutputStream(fos);
//obj即對應的對象
oos.writeObject(obj);
oos.flush();
//關閉流,否則再次write時易出現文件空白的情況
oos.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
//反序列化
ObjectInputStream ois = null;
try {
ois = new ObjectInputStream(new FileInputStream(fileString));
PairObj stu2 = (PairObj) ois.readObject();
System.out.println("The same Jvm");
System.out.println(stu2);
System.out.println(stu2.getFirst());
System.out.println(stu2.getSecond());
System.out.println(stu2.getPassword());
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
序列化數組
序列化為數組- 對象p實現序列化接口Serializable
把序列化對象p套一個對象輸出流,對象輸出流再套一個字節數組輸出流。最后轉成對象字節數組
ObjectOutputStream oos=new ObjectOutputSream(new ByteArrayOutputSream());
oos.writeObject(p);
byte[] pBytes=ba.toByteArray();
序列化:
try {
ByteArrayOutputStream obj = new ByteArrayOutputStream();
ObjectOutputStream out = new ObjectOutputStream(obj);
out.writeObject(this);
return obj.toByteArray();
} catch (IOException e) {
e.printStackTrace();
}
反序列化:
ByteArrayInputStream bin = new ByteArrayInputStream((byte[])objs);
try {
ObjectInputStream obin = new ObjectInputStream(bin);
Object obj = obin.readObject();
} catcch(Exception e) {
e.printStackTrace();
}
RoaringBitmap序列化到文件
public class RoaringBitMapSerialize {
public static String fileString = "F:\\sources\\sfm.txt";
public static void main(String[] args) {
//序列化Roaringbitmap數據
RoaringBitmap outRR = RoaringBitmap.bitmapOf(1, 9, 3, 1000);
outRR.add(5);
/**
* 將RoaringBitmap 對象序列化存儲到本地文件中去,
*/
try {
//file對應相應的.txt文件
File file = new File(fileString);
FileOutputStream fos = new FileOutputStream(file);
ObjectOutputStream oos = new ObjectOutputStream(fos);
//obj即對應的對象
outRR.serialize(oos);
oos.flush();
//關閉流,否則再次write時易出現文件空白的情況
oos.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
System.out.println("序列化到文件完成");
RoaringBitmap outRR = new RoaringBitmap();
/**
* 將RoaringBitmap 對象從本地文件中反序列化,
*/
try {
InputStream inputStream = new FileInputStream(fileString);
ObjectInputStream ois = new ObjectInputStream(inputStream);
outRR.deserialize(new DataInputStream(ois));
System.out.println("反序列化到文件完成");
System.out.println(outRR.getCardinality());
// 遍歷放入List中
List<Integer> numbers = new ArrayList<>();
outRR.forEach((IntConsumer) numbers::add);
System.out.println(numbers);
// 遍歷輸出
outRR.forEach((IntConsumer)i -> System.out.println(i));
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
RoaringBitmap序列化到byte[]存放到緩存中
public class RoaringBitmapByteDeserialize {
public static void main(String[] args){
//序列化Roaringbitmap數據
RoaringBitmap outRBM =new RoaringBitmap();
outRBM.add(1);
outRBM.add(3);
outRBM.add(9);
outRBM.add(100);
byte[] pBytes= null;
RoaringBitmap outRR = new RoaringBitmap();
byte[] result= null;
try {
//1.序列化 Roaringbitmap
ByteArrayOutputStream bos = new ByteArrayOutputStream();
outRBM.serialize(new DataOutputStream(bos));
//obj即對應的對象
pBytes = bos.toByteArray();
bos.flush();
//關閉流,否則再次write時易出現文件空白的情況
bos.close();
System.out.println("序列化到ByteArray 緩存完成");
//2.反序列化 Roaringbitmap 並計算結構
outRR.deserialize(new DataInputStream(new ByteArrayInputStream(pBytes)));
outRR.forEach((IntConsumer) i -> System.out.println(i));
outRR.add(50);
//3.序列化的Roaringbitmap進行計算
System.out.println("計算后的數據是");
outRR.forEach((IntConsumer) i -> System.out.println(i));
//序列化 Roaringbitmap
ByteArrayOutputStream nbos = new ByteArrayOutputStream();
outRR.serialize(new DataOutputStream(nbos));
result = nbos.toByteArray();
nbos.flush();
//關閉流,否則再次write時易出現文件空白的情況
nbos.close();
} catch (
FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}