資料開發_Java中IO序列化以及RoaringBitmap序列化
阿新 • • 發佈:2020-11-19
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();
}
}
}