位元組流(以位元組為單位)
- 當不同的介質之間有資料互動的時候,JAVA就使用流來實作,
- 資料源可以是檔案,還可以是資料庫,網路甚至是其他的程式
- 輸入流: InputStream 輸出流:OutputStream
位元組輸入輸出流
-
檔案輸出流(FileOutputStream)
-
OutputStream是位元組輸出流,同時也是抽象類,只提供方法宣告,不提供方法的具體實作,
-
FileOutputStream 是OutputStream子類
-
將資料從記憶體寫入到硬碟
import java.io.FileOutputStream; import java.io.IOException; public class FileOutputStream01 { public static void main(String[] args) throws IOException { //創建一個FileOutputStream物件,構造方法傳入寫入資料的檔案 FileOutputStream fos = new FileOutputStream("IOAndProperties\\src\\OutputStream\\a.txt"); //呼叫FileOutputStream物件中的方法write,將資料寫入檔案 fos.write(2333); //釋放資源,流的使用會占用資源,使用完要將記憶體清空,提高程式效率 fos.close(); } } -
檔案中一次寫入多個位元組:
write(byte[] b):如果寫入的第一個位元組是正數(0-127),顯示時會查詢ASCII表;如果寫入的第一個位元組是負數,那么第一個位元組和第二個位元組會組成中文顯示,查詢系統默認碼表(GBK)
write(byte[] b, int off, int len):int off:陣列b開始的索引;int len:寫入幾個位元組 -
檔案續寫:使用
FileOutputStream中兩個引數的構造方法FileOutputStream(String name, boolean append):append是續寫開關,當為true時繼續在檔案末尾追加寫資料,當為false時創建新檔案覆寫原檔案
-
-
檔案輸入流(FileInputStream)
-
InputStream是位元組輸出流,同時也是抽象類,只提供方法宣告,不提供方法的具體實作,
-
FileInputStream 是InputStream子類
-
將資料從硬碟寫入到記憶體
import java.io.FileInputStream; import java.io.IOException; public class FileInputStream01 { public static void main(String[] args) throws IOException { //創建FileInputStream物件 FileInputStream fis = new FileInputStream("IOAndProperties\\src\\OutputStream\\b.txt"); //呼叫read方法,讀取檔案中的一個位元組并回傳,讀取到檔案的末尾回傳-1 int read = 0; while ((read= fis.read()) != -1) { System.out.println(read); } //釋放資源 fis.close(); } } -
檔案中一次讀取多個位元組:
read(byte[] b): 從輸入流讀取一定數量的位元組,并將其存盤在緩沖區陣列b中
-
-
復制檔案(一讀一寫)
package InputStream; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; public class CopyFile { public static void main(String[] args) throws IOException { long start = System.currentTimeMillis(); FileOutputStream fos = new FileOutputStream("IOAndProperties\\src\\OutputStream\\copy.jpg"); FileInputStream fis = new FileInputStream("D:\\1.jpg"); //使用陣列緩沖區讀取多個位元組寫入多個位元組 byte[] bytes = new byte[1024]; int read = 0; while ((read = fis.read(bytes)) != -1){ fos.write(bytes, 0, read); } //釋放資源,先關寫入再關讀取 fos.close(); fis.close(); long end = System.currentTimeMillis(); System.out.println("復制完成,用時:"+(end-start)+"ms"); } }
字符流(以字符為單位)
- 當使用位元組流讀取文本,遇到中文時可能不會顯示完整字符,因為中文可能占用多個位元組存盤
- Java提供的字符流專門用于字符的形式讀取和寫入資料,專門用于處理文本檔案
- Reader是字符輸入流最頂層的父類,是一個抽象類
- Writer是字符輸出流最頂層的父類,是一個抽象類
字符輸入輸出流
-
檔案字符輸入流(FileReader)
-
FileReader 是Reader子類
-
將硬碟檔案中的資料以字符的方式讀取到記憶體中
import java.io.FileReader; import java.io.IOException; public class FileReaderDemo { public static void main(String[] args) throws IOException { //創建FileReader物件,構造方法中系結資料源 FileReader fr = new FileReader("IOAndProperties\\src\\OutputStream\\b.txt"); //int read():讀取單個字符并回傳 //int read(char[] cbuf):一次讀取多個字符,并將陣列存盤陣列中 char[] cbuf = new char[1024]; int len = 0; while ((len = fr.read(cbuf)) != -1){ System.out.println(new String(cbuf, 0, len)); } //釋放資源 fr.close(); } }
-
-
檔案字符輸出流(FileWriter)
-
FileWriter 是Writer子類
-
將記憶體中的資料以字符的方式寫入檔案中
-
需要將記憶體緩沖區中的資料重繪到檔案中
import java.io.FileWriter; import java.io.IOException; public class FileWriterDemo { public static void main(String[] args) throws IOException { //創建FileWriter物件,構造方法中系結資料目的地 FileWriter fw = new FileWriter("IOAndProperties\\src\\ReaderAndWriter\\c.txt"); //呼叫write方法把資料寫入記憶體緩沖區(字符轉換為位元組的程序) //void write(int c):寫入單個字符 //void write(char[] cbuf, int off, int len):一次寫入多個字符 //void write(String str):寫入字串 //void write(String str, int off, int len):寫入字串一部分 char[] cbuf = {'你', '好', 'c', 'd'}; String str = "陰陽師"; fw.write(cbuf, 0, 3); fw.write(str, 0, 3); //使用FileWriter中的方法flush,把記憶體緩沖區中的資料重繪到檔案中 fw.flush(); //釋放資源(也會先把記憶體緩沖區中的資料重繪到檔案中) fw.close(); } }flush和close方法的區別:flush重繪緩沖區,流物件可以繼續使用;close先重繪緩沖區,然后通知系統釋放資源,流物件不可以再被使用了
-
檔案續寫:使用
FileWriter中兩個引數的構造方法FileWriter(String name, boolean append):append是續寫開關,當為true時繼續在檔案末尾追加寫資料,當為false時創建新檔案覆寫原檔案
-
Properties集合
-
Properties集合是一個雙列集合,key和value都默認是字串
-
Properties類表示了一個持久屬性集,Properties可保存在流中也可從流中加載
-
Properties集合中的
store方法把集合中的臨時資料持久化寫入到硬碟中保存傳入位元組輸入流則不能保存中文,傳入字符輸入流則可以保存中文
-
Properties集合中的
load方法把硬碟中保存的檔案(鍵值對)讀取到集合中使用傳入位元組輸入流則不能讀取中文,傳入字符輸入流則可以讀取中文
import java.io.FileWriter; import java.io.IOException; import java.util.Properties; //使用properties中的store方法將臨時資料寫入硬碟中存盤 public class Properties01 { public static void main(String[] args) throws IOException { //創建properties集合物件添加資料 Properties date = new Properties(); //創建位元組/字符輸出流物件 FileWriter fw = new FileWriter("IOAndProperties\\src\\properties\\pro.txt"); //往集合中添加資料 date.setProperty("追月神","打火"); date.setProperty("八岐大蛇","輸出大佬"); date.setProperty("山兔","拉條"); date.setProperty("日和坊","奶媽"); //使用store方法往硬碟中存盤資料,comments為注釋,不能使用中文,一般用空字串 date.store(fw, "save date"); fw.close(); } }import java.io.FileReader; import java.io.IOException; import java.util.Properties; import java.util.Set; //使用properties中的load方法讀取硬碟中的鍵值對資料 //存盤鍵值對資料的檔案中,鍵值默認連接符可以是=,空格 //存盤鍵值對資料的檔案中,使用#進行注釋,被注釋的鍵值對將不被讀取 public class PropertiesLoad { public static void main(String[] args) throws IOException { //創建Properties集合物件 Properties date = new Properties(); //使用load方法讀取保存鍵值對資料的檔案 date.load(new FileReader("IOAndProperties\\src\\properties\\pro.txt")); //遍歷Properties集合 Set<String> set = date.stringPropertyNames();//將讀取的key存入Set集合中 for (String key : set) { String value = https://www.cnblogs.com/geqianLee/p/date.getProperty(key);//根據key讀取value System.out.println(key+" "+value); } } }
緩沖流
位元組流和字符流的弊端,在每一次讀寫的時候,都會訪問硬碟, 如果讀寫的頻率比較高的時候,其性能表現不佳,為了解決以上弊端,采用緩沖流, 緩沖流在讀取的時候,會一次性讀較多的資料到快取中,以后每一次的讀取,都是在快取中訪問,直到快取中的資料讀取完畢,再到硬碟中讀取,
-
位元組緩沖流:
BufferedInputStream、BufferedOutputStream -
字符緩沖流:
BufferedReader、BufferedWriter -
基本原理:創建流物件時,會創建一個內置的默認大小的緩沖區陣列,通過緩沖區讀寫,減少系統IO次數,提高讀寫效率
位元組緩沖流
import java.io.BufferedOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;
//位元組緩沖輸出流
public class BufferedOutputStream01 {
public static void main(String[] args) throws IOException {
//創建一個FileOutputStream物件,構造方法傳入寫入資料的檔案
FileOutputStream fos = new FileOutputStream("IOAndProperties\\src\\OutputStream\\a.txt");
//創建BufferedOutputStream物件,構造方法中傳遞FileOutputStream物件
BufferedOutputStream buff = new BufferedOutputStream(fos);
//使用BufferedOutputStream中的write方法,將資料寫入記憶體緩沖區
String str = "你好";
buff.write(str.getBytes());
//使用BufferedOutputStream中的flush方法將內部緩沖區的資料重繪到檔案中
buff.flush();
//釋放資源(會先呼叫flush,上一步可省)
buff.close();
}
}
import java.io.BufferedInputStream;
import java.io.FileInputStream;
import java.io.IOException;
//位元組緩沖輸入流
public class BufferedInputStream01 {
public static void main(String[] args) throws IOException {
//創建一個FileInputStream物件,構造方法傳入寫入資料的檔案
FileInputStream fis = new FileInputStream("IOAndProperties\\src\\OutputStream\\a.txt");
//創建BufferedInputStream物件,構造方法中傳遞FileInputStream物件
BufferedInputStream buff = new BufferedInputStream(fis);
//使用BufferedOutputStream中的read方法,讀取物件
int len = 0;
byte[] cbuf = new byte[1024];
while ((len = buff.read(cbuf)) !=-1){
System.out.println(new String(cbuf, 0, len));
}
//釋放資源
buff.close();
}
}
字符緩沖流
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
//字符緩沖輸出流
public class BufferedWriterDemo {
public static void main(String[] args) throws IOException {
//創建字符緩沖輸出流物件
BufferedWriter bw = new BufferedWriter(new FileWriter("IOAndProperties\\src\\ReaderAndWriter\\c.txt"));
//呼叫write方法寫入資料
bw.write("陰陽師你好");
//重繪緩沖區,釋放資源
bw.flush();
bw.close();
}
}
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
//字符緩沖輸入流
public class BufferedReaderDemo {
public static void main(String[] args) throws IOException {
//創建字符緩沖輸入流物件
BufferedReader br = new BufferedReader(new FileReader("IOAndProperties\\src\\ReaderAndWriter\\c.txt"));
//使用read或readline讀取資料,readline每次只讀取一行
String str;
while ((str = br.readLine()) != null){
System.out.println(str);
}
//釋放資源
br.close();
}
}
序列化和反序列化
-
物件流指的是可以直接把一個物件以流的形式傳輸給其他的介質,比如硬碟,
-
一個物件以流的形式寫入檔案進行保存,叫做序列化,
-
把檔案保存的物件以流的形式讀取出來,叫做反序列化,
-
該物件所對應的類,必須實作Serializable介面
Serializable介面也叫標記型介面,要進行序列化和反序列化的類必須實作Serializable介面,給該類添加一個標記,當進行序列化和反序列化時,就會檢測類上是否有這個標記,有標記就可以序列化和反序列化,沒有就會拋出NotSerializableException例外
-
被static(靜態關鍵字)和transient(瞬態關鍵字)修飾的成員變數不能被序列化
import java.io.Serializable;
public class Person implements Serializable {
//自定義一個序列版本號,
// 添加新的屬性時重新編譯,可以直接反序列化,不會拋出例外
//該序列號即為默認的序列號
static final long serialVersionUID = 2L;
private String name;
private int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
//序列化
public class ObjectOutputStream01 {
public static void main(String[] args) throws IOException {
//創建ObjectOutputStream物件,構造方法中傳遞位元組輸出流
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("IOAndProperties\\src\\ObjectStream\\person.txt"));
//利用writeObject方法寫入Person物件
oos.writeObject(new Person("angel", 18));
//釋放資源
oos.close();
}
}
import java.io.FileInputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
//反序列化
public class ObjectInputStream01 {
public static void main(String[] args) throws IOException, ClassNotFoundException {
//創建ObjectInputStream物件,構造方法傳入位元組輸入流
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("IOAndProperties\\src\\ObjectStream\\person.txt"));
//使用readObject方法讀取保存物件的檔案
Object o = ois.readObject();
//釋放資源
ois.close();
System.out.println(o.toString());
}
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/139919.html
標籤:Java
上一篇:JAVA動態代理
下一篇:面向物件的由來
