08 - JavaSE之IO流
IO流
JAVA流式輸入輸出原理:可以想象成一根管道懟到文件上,另一端是我們程序,然后流的輸入輸出都是按照程序本身作為第一人稱說(shuō)明的。比如 input,對(duì)于我們程序來(lái)說(shuō)就是有數(shù)據(jù)輸入我們程序,output就是我們程序輸出數(shù)據(jù)到文件等。對(duì)象不能搞錯(cuò)了,否則就南轅北轍了。
- 通過(guò)不同的角度對(duì)流的輸入輸出功能進(jìn)行分類:
輸入流和輸出流
-
JAVA JDK 所提供的所有流類型位于包 java.io 內(nèi)部,分別繼承自下面四個(gè)抽象流類型:
字節(jié)流 字符流輸入流 InputStream Reader
輸出流 OutputStream Writer
節(jié)點(diǎn)流和處理流
- 節(jié)點(diǎn)流為可以從一個(gè)特定的數(shù)據(jù)源(節(jié)點(diǎn))讀寫(xiě)數(shù)據(jù)(如:文件,內(nèi)存)。
節(jié)點(diǎn)流可以簡(jiǎn)單的理解為:一根管道直接懟到文件上,進(jìn)行數(shù)據(jù)的讀寫(xiě)。
- 處理流是連接在已存在的節(jié)點(diǎn)流或處理流上的,通過(guò)讀數(shù)據(jù)進(jìn)行處理(過(guò)濾等)為程序提供更加強(qiáng)大的讀寫(xiě)功能。
處理流可以簡(jiǎn)單的理解為:套在節(jié)點(diǎn)流管道的管子,可以對(duì)流過(guò)節(jié)點(diǎn)流的數(shù)據(jù)進(jìn)行處理,過(guò)濾等操作。
InputStream 抽象類
- 繼承自 InputStream的流都是用于向程序中輸入數(shù)據(jù),且數(shù)據(jù)的單位為字節(jié)。
- 繼承自 InputStream的類有如下等:(加粗為節(jié)點(diǎn)流,未加粗為處理流)
FileInputStream
PipedInputStream
FilterInputStream
ByteArrayInputStream
SequenceInputStream
StringBufferInputStream
ObjectInputStream
-
InputStream的基本方法
int read() throws IOException
int read(byte[] buffer) throws IOException
int read(byte[] buffer, int offset, int length) throws IOException
void close() throws IOException
OutputStream 抽象類
- 繼承自 OutputStream的流都是用于從程序中輸出數(shù)據(jù),且數(shù)據(jù)的單位為字節(jié)。
- 繼承自 OutputStream的類有如下等:(加粗為節(jié)點(diǎn)流,未加粗為處理流)
FileOutputStream
PipedOutputStream
FilterOutputStream
ByteArrayOutputStream
ObjectOutputStream
-
OutputStream 基本方法
void write(int b) throws IOException
void write(byte[] b) throws IOException
void write(byte[] b, int off, int len) throws IOException
void close() throws IOException
void flush() throws IOException // 在關(guān)閉輸出流之前使用,將輸出緩沖區(qū)的數(shù)據(jù)寫(xiě)到目的地
Reader
- 繼承自 Reader 的流都是用于程序從外部讀入數(shù)據(jù),且數(shù)據(jù)的單位是字符(2個(gè)字節(jié))。
- 如下為繼承自Reader的流。(加粗為節(jié)點(diǎn)流,未加粗為處理流)
BufferedReader
CharArrayReader
InputStreamReader
FilterReader
PipedReader
StringReader
- Reader的基本方法 - 略
Writer
- 繼承自 Writer的流都是用于程序向外部寫(xiě)入數(shù)據(jù),且數(shù)據(jù)的單位是字符(2個(gè)字節(jié))。
- 如下為繼承自Writer的流。(加粗為節(jié)點(diǎn)流,未加粗為處理流)
BufferedWriter
CharArrayWriter
OutputStreamWriter
FilterWriter
PipedWriter
StringWriter
- Writer的基本方法 - 略
節(jié)點(diǎn)流類型
類型 字節(jié)流 字符流
File(文件) FileInputStream / FileOutputStream FileReader / FileWriter
Memory Array ByteArrayInputStream / ByteArrayOutputStream CharArrayReader / CharArrayWriter
Memory String -- StringReader / StringWriter
Pipe(管道) PipedInputStream / PipedOutputStream PipedReader / PipedWriter
舉例1:FileInputStream
import java.io.*; public class Test {public static void main(String[] args) {int b = 0;long num = 0;FileInputStream ln = null;try {ln = new FileInputStream("I:/Java/Demo/test.txt");} catch (FileNotFoundException e) {System.out.println("文件不存在!");System.exit(-1);}try {while ((b=ln.read()) != -1) {System.out.print((char)b);num++;}ln.close();System.out.println();System.out.println("共讀出:" + num + "個(gè)字節(jié)。");} catch (IOException e) {System.out.println("文件讀取失敗!");System.exit(-1);}} }舉例2:FileOutputStream
import java.io.*; public class Test {public static void main(String[] args) {int b = 0;FileInputStream in = null;FileOutputStream out = null;try {in = new FileInputStream("I:/Java/Demo/test.txt");out = new FileOutputStream("I:/Java/Demo/newtest.txt");while((b=in.read()) != -1) {out.write(b);}} catch (FileNotFoundException e) {System.out.println("文件不存在!");System.exit(-1);} catch (IOException e) {System.out.println("文件復(fù)制失敗!");System.exit(-2);}System.out.println("文件復(fù)制成功!");} }處理流類型
處理類型 字節(jié)流 字符流
Buffering BufferedInputStream/BufferedOutputStream BufferedReader/BufferedWriter
Filtering FilterInputStream/FilterOutputStream FilterReader/FilterWriter
Converting between bytes and character -- InputStreamReader/OutputStreamWriter
Object Serialization ObjectInputStream/ObjectOutputStream --
Data conversion DataInputStream/DataOutputStream --
Counting LineNumberInputStream LineNumberReader
Peeking ahead PushbackInputStream PushbackReader
Printing PrintStream PrintWriter
- 緩沖流(以Buffered開(kāi)頭)
緩沖流套接在相應(yīng)的節(jié)點(diǎn)流上,對(duì)讀寫(xiě)的數(shù)據(jù)提供了緩沖的功能,提高了讀寫(xiě)的效率,同時(shí)增加了一些新的方法。
BufferedReader / BufferedWriter / BufferedInputStream / BufferedOutputStream
對(duì)于輸出的緩沖流,寫(xiě)出的數(shù)據(jù)會(huì)先在內(nèi)存中緩存,使用 flush 方法將會(huì)使內(nèi)存中的數(shù)據(jù)立刻寫(xiě)出。
舉例1:
import java.io.*; public class Test {public static void main(String[] args) {int b = 0;FileInputStream in = null;BufferedInputStream bin = null;try {in = new FileInputStream("I:/Java/Demo/test.txt");bin = new BufferedInputStream(in);bin.mark(100);for(int i=0; (i<=10)&&(b=bin.read()) != -1; i++) {System.out.print((char)b);}bin.reset();System.out.println();for(int i=0; (i<=10)&&(b=bin.read()) != -1; i++) {System.out.print((char)b);}} catch (FileNotFoundException e) {System.out.println("文件不存在!");System.exit(-1);} catch (IOException e) {e.printStackTrace();}} }舉例2:
import java.io.*; public class Test {public static void main(String[] args) {String s = null;try {BufferedWriter bw = new BufferedWriter(new FileWriter("I:/Java/Demo/test.txt"));BufferedReader br = new BufferedReader(new FileReader("I:/Java/Demo/test.txt"));for(int i=0; i<100; i++) {s = Double.toString(Math.random());bw.write(s);bw.newLine();}bw.flush();while((s=br.readLine()) != null) {System.out.println(s);}bw.close();br.close();} catch (IOException e) {e.printStackTrace();}} } //0.7365309652822098 //0.577186775602007 //0.11736466966949166 //0.2998096440959087 //0.23859539950503672 //...- 轉(zhuǎn)換流
舉例1:
import java.io.*; public class Test {public static void main(String[] args) {try {OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("I:/Java/Demo/test.txt"));osw.write("1234567890");System.out.println(osw.getEncoding());osw.flush();osw.close();osw = new OutputStreamWriter(new FileOutputStream("I:/Java/Demo/test.txt", true), "ISO8859_1");osw.write("abcdefghijklmn");System.out.println(osw.getEncoding());osw.flush();osw.close();} catch (IOException e) {e.printStackTrace();}} }舉例2:
import java.io.*; public class Test {public static void main(String[] args) {try {String s = null;InputStreamReader isr = new InputStreamReader(System.in);BufferedReader br = new BufferedReader(isr);while((s = br.readLine()) != null) {if(s.equalsIgnoreCase("exit")) {break;}System.out.println(s);}br.close();} catch (IOException e) {e.printStackTrace();}} }- 數(shù)據(jù)流
DataInputStream (InputStream in)
DataOutputStream (OutputStream out)
數(shù)據(jù)流的作用?
比如,我們?nèi)绾未鎯?chǔ)一個(gè)很大的數(shù)到文件?我們之前的方法是將其轉(zhuǎn)換成字符串存儲(chǔ),可不可以直接存儲(chǔ)呢?數(shù)據(jù)流可以。它提供了很多方法用于存儲(chǔ)基礎(chǔ)數(shù)據(jù)類型的數(shù)據(jù),參看 API 文檔。
舉例1:
import java.io.*; public class Test {public static void main(String[] args) {ByteArrayOutputStream baos = new ByteArrayOutputStream(); // 在內(nèi)存自動(dòng)生成一個(gè) Byte[] 數(shù)組DataOutputStream dos = new DataOutputStream(baos);try {dos.writeDouble(Math.random());dos.writeBoolean(true);ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());System.out.println(bais.available());DataInputStream dis = new DataInputStream(bais);System.out.println(dis.readDouble());System.out.println(dis.readBoolean());dos.close();dis.close();} catch (IOException e) {e.printStackTrace();}} }問(wèn)題:我們寫(xiě)一個(gè) double,寫(xiě)一個(gè)boolean寫(xiě)到哪里了呢?
其實(shí),在我們 ByteArrayOutputStream baos = new ByteArrayOutputStream(); 的時(shí)候,就在內(nèi)存中開(kāi)辟了一塊空間,用來(lái)將程序要寫(xiě)入的數(shù)據(jù)寫(xiě)到這片內(nèi)存中。
還有,在讀數(shù)據(jù)的時(shí)候,由于這片內(nèi)存的分配是按照隊(duì)列的方式分配的,所以先寫(xiě)進(jìn)去的數(shù)據(jù)要先讀出來(lái),如果如上面程序那樣,先讀boolean的話,就會(huì)讀取到double 8個(gè)字節(jié)的第一個(gè)字節(jié)上,切記!
- Print 流(打印流)
PrintWriter 和 PrintStream 有自動(dòng) flush 功能。
PrintWriter(PrintWriter out)
PrintWriter(Writer out, boolean autoFlush)
PrintWriter(OutputStream out)
PrintWriter(OutputStream out, boolean autoFlush)
PrintStream(OutputStream out)
PrintStream(OutputStream out, boolean autoFlush)
舉例1:
import java.io.*; public class Test {public static void main(String[] args) {PrintStream ps = null;try {FileOutputStream fos = new FileOutputStream("I:\\Java\\Demo\\test.txt");ps = new PrintStream(fos);if(null != ps) {System.setOut(ps);}for(int i=0; i<60000; i++) {System.out.print((char)i + " ");if(i%50 == 0) {System.out.println();}}} catch (IOException e) {e.printStackTrace();}} }將輸出打印語(yǔ)句重定向到 test.txt 文件中。
舉例2:
import java.io.*;public class Test {public static void main(String[] args) {String filename = args[0];if (filename != null) {list(filename, System.out);}}public static void list(String f, PrintStream fs) {try {String s = null;BufferedReader br = new BufferedReader(new FileReader(f));while ((s = br.readLine()) != null) {fs.println(s);}br.close();} catch (IOException e) {e.printStackTrace();}} }將 args[0] 所寫(xiě)的文件名對(duì)應(yīng)的文件打印到終端。
舉例3:
import java.io.*; import java.util.*;public class Test {public static void main(String[] args) {String s = null;BufferedReader br = new BufferedReader(new InputStreamReader(System.in));try {FileWriter fw = new FileWriter("I:/Java/Demo/log.txt", true);PrintWriter log = new PrintWriter(fw);while((s=br.readLine()) != null) {if(s.equalsIgnoreCase("exit")) {break;}System.out.println(s);log.println("------");log.println(s);log.flush(); // 可以省略}log.println("--- " + new Date() + " ---");log.flush(); // 可以省略log.close();} catch (IOException e) {e.printStackTrace();}} }將從終端輸入的內(nèi)容作為 log 寫(xiě)到 log.txt 文件里面。
- Object 流
Object 流的作用:當(dāng)我們存儲(chǔ)一個(gè)元素的時(shí)候,(比如在畫(huà)圖軟件上畫(huà)了一個(gè)圓)我們的圓有很多屬性,原點(diǎn)位置,半徑大小,顏色,粗細(xì)等,既然每一個(gè)屬性都需要存儲(chǔ),而且這些屬性都在一個(gè) Object 對(duì)象里面,那么我們?yōu)槭裁床恢苯訉?xiě)整個(gè) Object呢?(這叫序列化。)
注意:當(dāng)你 new 一個(gè) Object 的時(shí)候,不單單只有你的屬性,還有一些比如 Object的版本號(hào),this,super 等。
舉例:
import java.io.*; public class Test {public static void main(String[] args) {TmpClass tm = new TmpClass();tm.a =10;tm.d = false;try {FileOutputStream fos = new FileOutputStream("I:/Java/Demo/text.txt");ObjectOutputStream oos = new ObjectOutputStream(fos);oos.writeObject(tm);oos.flush();oos.close();FileInputStream fis = new FileInputStream("I:/Java/Demo/text.txt");ObjectInputStream ois = new ObjectInputStream(fis);TmpClass t = (TmpClass) ois.readObject();System.out.println(t.a + " " + t.b + " " + t.c + " " + t.d);} catch (ClassNotFoundException c) {System.out.println("讀取文件失敗");} catch (IOException e) {e.printStackTrace();}} }class TmpClass implements Serializable {int a = 1;int b = 2;double c = 3.0;boolean d = true; }- Serializable 接口
- tansient關(guān)鍵字
使用方法,修飾成員變量。
class TmpClass implements Serializable {
int a = 1;
int b = 2;
tansient double c = 3.0;
boolean d = true;
}
transient 表示透明的意思,就是說(shuō)在一個(gè)類的對(duì)象序列化的時(shí)候不予考慮,就是將這個(gè)類的對(duì)象寫(xiě)入文件的時(shí)候,不寫(xiě)這個(gè)被transient 修飾的成員變量,那么我們?cè)僮x出來(lái)的時(shí)候就是默認(rèn)值(如上,c 讀出來(lái)的時(shí)候是 0.0)
- externalizable 接口
總結(jié)
- 本章復(fù)習(xí)方法:把所有的名字,關(guān)鍵字寫(xiě)到一張紙上,每天看看想想自己,給朕看半個(gè)時(shí)辰。—— 康熙
總結(jié)
以上是生活随笔為你收集整理的08 - JavaSE之IO流的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: Spring(一)容器
- 下一篇: axios + router4 + mo