舉例講授Java中的Stream流概念。本站提示廣大學習愛好者:(舉例講授Java中的Stream流概念)文章只能為提供參考,不一定能成為您想要的結果。以下是舉例講授Java中的Stream流概念正文
1、根本的輸出流和輸入流
流是 Java 中最主要的根本概念之一。文件讀寫、收集收發、過程通訊,簡直一切須要輸出輸入的處所,都要用到流。
流是做甚麼用的呢?就是做輸出輸入用的。為何輸出輸入要用“流”這類方法呢?由於法式輸出輸入的根本單元是字節,輸出就是獲得一串字節,輸入就是發送一串字節。然則許多情形下,法式弗成能吸收一切的字節以後再停止處置,而是吸收一點處置一點。比喻你下載魔獸世界,弗成能全體下載到內存裡再保留到硬盤上,而是下載一點就保留一點。這時候,流這類方法就異常合適。
在 Java 中,每一個流都是一個對象。流分為兩種:輸出流(InputStream)和輸入流(OutputStream)。關於輸出流,你只需從流傍邊一直地把字節掏出來就是了;而關於輸入流,你只需把預備好的字節串傳給它就行。
流對象是怎樣取得的呢?分歧的內部體系,獲得流的方法也分歧。例如,文件讀寫就要創立 FileInputStream/FileOutputStream 對象,而收集通訊是經由過程 Socket 對象來獲得輸出輸入流的。普通來講,假如一個類有 getInputStream() 或 getOutputStream() 如許的辦法,就注解它是經由過程流對象來停止輸出輸入的。
InputStream 是輸出流,上面是一個經由過程 InputStream 讀取文件的例子:
import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.io.FileNotFoundException; import java.util.Arrays; /** * 經由過程流讀取文件 */ public class ReadFileDemo { // 法式進口 public static void main(String[] args) { String path = "c:/boot.ini"; File file = new File(path); // 創立輸出流 InputStream is; try { is = new FileInputStream(file); } catch (FileNotFoundException e) { System.err.println("文件 " + path + " 不存在。"); return; } // 開端讀取 byte[] content = new byte[0]; // 保留讀掏出來的文件內容 byte[] buffer = new byte[10240]; // 界說緩存 try { int eachTime = is.read(buffer); // 第一次讀取。假如前往值為 -1 就表現沒有內容可讀了。 while (eachTime != -1) { // 讀掏出來的內容放在 buffer 中,如今將其歸並到 content。 content = concatByteArrays(content, buffer, eachTime); eachTime = is.read(buffer); // 持續讀取 } } catch (IOException e) { System.err.println("讀取文件內容掉敗。"); e.printStackTrace(); } finally { try { is.close(); } catch (IOException e) { // 這裡的異常可以疏忽不處置 } } // 輸入文件內容 String contentStr = new String(content); System.out.println(contentStr); } /** * 歸並兩個字節串 * * @param bytes1 字節串1 * @param bytes2 字節串2 * @param sizeOfBytes2 須要從 bytes2 中掏出的長度 * * @return bytes1 和 bytes2 中的前 sizeOfBytes2 個字節歸並後的成果 */ private static byte[] concatByteArrays(byte[] bytes1, byte[] bytes2, int sizeOfBytes2) { byte[] result = Arrays.copyOf(bytes1, (bytes1.length + sizeOfBytes2)); System.arraycopy(bytes2, 0, result, bytes1.length, sizeOfBytes2); return result; } }
固然寫得很煩瑣,但這確切是 InputStream 的根本用法。留意,這只是一個例子,解釋若何從輸出流中讀取字節串。現實上,Java 供給更簡略的方法來讀取文本文件。今後將會引見。
比擬從流中讀取,應用 OutputStream 輸入則長短常簡略的工作。上面是一個例子:
import java.io.OutputStream; import java.io.FileOutputStream; import java.io.File; import java.io.IOException; import java.util.Date; /** * 將以後日期保留到文件 */ public class SaveFileDemo { public static void main(String[] args) throws IOException { String path = "c:/now.txt"; File file = new File(path); if (!file.exists() && !file.createNewFile()) { System.err.println("沒法創立文件。"); return; } OutputStream os = new FileOutputStream(file); // 創立輸入流(條件是文件存在) os.write(new Date().toString().getBytes()); // 將以後時光寫入文件 os.close(); // 必需封閉流,內容才會寫入文件。 System.out.println("文件寫入完成。"); } }
Java 還供給其它的流操作方法,但它們都是對 InputStream 和 OutputStream 停止擴大或包裝。所以這兩個類是基本,必需要懂得它們的應用。
2、Reader 和 Writer
引見了 InputStream 和 OutputStream,接上去引見 Reader 和 Writer。這兩個類其實就是將 InputStream 和 OutputStream 包裝了一下。不外它們處置的不是字節(byte),而是字符(char)。假如一個流傍邊的內容都是文本,那末用 Reader/Writer 處置起來會簡略些。上面是一個用 Reader 讀取文本文件的例子:
import java.io.FileReader; import java.io.IOException; import java.io.Reader; /** * 讀取文本文件 */ public class ReadTextFileDemo { // 法式進口 public static void main(String[] args) { String path = "c:/boot.ini"; String content = ""; try { Reader reader = new FileReader(path); char[] buffer = new char[10240]; int count; while ((count = reader.read(buffer)) != -1) { content += new String(buffer, 0, count); } } catch (IOException e) { System.err.println("讀取文件掉敗。"); e.printStackTrace(); } System.out.println(content); } }
至於若何用 Writer 將文本內容寫入文件,這裡就不給出例子了,看官本身試著寫一下吧。
下面這個例子,依然不是讀取文本文件最經常使用的方法。Java 供給 BufferedReader,我們平日用它來讀取文本文件。上面是一個例子:
import java.io.BufferedReader; import java.io.FileReader; import java.io.IOException; /** * 用 BufferedReader 讀取文本文件 */ public class ReadTextDemo2 { public static void main(String[] args) { String path = "c:/boot.ini"; String content = ""; try { BufferedReader reader = new BufferedReader(new FileReader(path)); String line; while ((line = reader.readLine()) != null) { content += line + "/n"; } } catch (IOException e) { System.err.println("讀取文件掉敗。"); e.printStackTrace(); } System.out.println(content); } }
3、對象序列化
對象序列化也是流運用的一個主要方面。序列化就是把一個對象轉換成一串字節,既可以保留起來,也能夠傳給別的的 Java 法式應用。ObjectOutputStream 和 ObjectInputStream 就是專門用來停止序列化和反序列化的。上面就是一個簡略的例子:
import java.io.ObjectOutputStream; import java.io.FileOutputStream; import java.io.File; import java.io.IOException; import java.io.Serializable; import java.io.ObjectInputStream; import java.io.FileInputStream; import java.io.EOFException; /** * ObjectOutputStream/ObjectInputStream 示例。 * 這兩個類分離用於序列化和反序列化。 */ public class SerializationDemo { public static void main(String[] args) throws Exception { String path = "c:/persons.data"; File f = new File(path); if (!f.exists()) { f.createNewFile(); } writePersons(path); readPersons(path); } // 從指定的文件中讀取 Person 對象 private static void readPersons(String path) throws IOException, ClassNotFoundException { ObjectInputStream ois = new ObjectInputStream(new FileInputStream(path)); Person p; while (true) { try { p = (Person) ois.readObject(); System.out.println(p); } catch (EOFException e) { break; } } } // 將 Person 對象保留到指定的文件中 private static void writePersons(String path) throws IOException { Person[] persons = new Person[]{ new Person("張三", 23), new Person("李四", 24) }; ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(path)); for (Person person : persons) { oos.writeObject(person); } oos.close(); } /////////////////////////////////////////////////////////// private static class Person implements Serializable { private String name; private int age; public Person() { } 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 + '}'; } } }
這個例子外面看不到字節和字符的讀寫,由於這兩個類都包裝好了。下面只是一個簡略的例子,序列化要寫好的話照樣有很多講求的。想深刻懂得序列化,可以看看這裡。本文只存眷跟流有關的部門。其實序列化用的很少,由於序列化下降了靈巧性,所以可以不消的話普通都不會用。