1.流的概念:在Java中,流是從源到目的地的字節的有序序列。Java中有兩種基本的流——輸入流(InputStream)和輸出流(OutputStream)。
根據流相對於程序的另一個端點的不同,分為節點流和過濾流。
(1)節點流:以特定源如磁盤文件、內存某區域或者線程之間的管道為端點的構造輸入輸出流,是一種基本的流。
(2)過濾流:以其他已經存在的流為端點構造的輸入輸出流。
根據流中的數據單位分為字節流和字符流。
(1)字節流:流中的數據是以8位字節為單位進行讀寫,以InputStream和OutputStream為基礎類。
(2)字符流:流中的數據是以16為字符為單位進行讀寫,以Reader和Writer為基礎類。
2.字節流
InputStream和OutputStream是字節流的兩個頂層父類,提供了輸入流類和輸出流類的通用API。
2.1 輸入字節流
InputStream基本方法:
(1)基本讀方法;: int read() int read(byte[] b) int read(byte[] b,int off,int len)
(2) 關閉流:void close()
(3) 返回輸入流中還有多少可讀字節 int available()
(4) 跳過指定字節 long skip(long n)
(5) 回讀數據 boolean markSupported() void Mark(int readlimt) void reset()
2.2 輸出字符流
OutputStream基本方法:
(1)基本寫方法:void write(int c) void write(byte[] b) void write(byte[] b,int off,int len)
(2) 關閉流:void close()
(3)q強制輸出:void flush()
3.字符流:
Reader和Writer是字符流的頂層父類,字符流能夠處理Unicode字符集中的所有字符。成員方法和字節流類似。
3.輸入/輸出流的套接
節點流在程序中不是很常見,一般通過過濾流將多個流套接起來,利用各個流的特性共同處理數據。例如下圖:一個文件流為了為了提高效率,套接了緩存流,最后套接了數據流。

4、常見的輸入輸出流
4.1 文件流:文件流屬於節點流,包括FileInputStream和FileOutputStream類以及Reader和Writer類。這些類都是對文件系統中的文件進行讀寫。文件流的創建是調用相應的構造方法,並經常以字符串形式的文件名或者一個File類的對象為參數,例如:
public FileInputStream(String name); public FileInputStream(File file);
例子:使用文件流實現文件的復制。
(1)通過文件字節流實現:
package ch07;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
public class CopyBytes {
public static void main(String[] args) throws IOException {
//create two File class object
// File inputFile=new File("E:\\workspace\\tmpfile\\farrago.txt");
// File outputFile=new File("E:\\workspace\\tmpfile\\outagainb.txt");
//create file input/output byteStream
FileInputStream inputStream=new FileInputStream(new File("E:\\workspace\\tmpfile\\farrago.txt")); //attention:throw exception
FileOutputStream outputStream=new FileOutputStream(new File("E:\\workspace\\tmpfile\\outagainb.txt"));
int c;
while((c=inputStream.read())!=-1){
outputStream.write(c);
System.out.println(c);
}
inputStream.close();
outputStream.close();
System.out.println("done! the file is in E:\\workspace\\tmpfile\\outagainb.txt");
}
}
(2)使用文件字符流實現
package ch07;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
public class Copy {
public static void main(String[] args) throws IOException{
//創建文件字符輸入/輸出流
FileReader in =new FileReader("E:\\workspace\\tmpfile\\farrago.doc");
FileWriter out=new FileWriter("E:\\workspace\\tmpfile\\outagainb.doc");
int c;
while((c=in.read())!=-1){
System.out.println(c);
out.write(c);
}
in.close();
out.close();
}
}
運行時需要在指定目錄下存在farrago.doc,程序運行后會在相同的目錄下生成outagainb.doc。里面內容和farrago.doc一樣。
4.2 緩沖流
緩沖流BufferedInputStream和BufferedOutputStream類和BufferedReader和BufferedWriter類。這種流把數據從原始流成塊讀入或者積累到一個大數據快的時候在成批寫出。BufferedOutputStream和BufferedWrite僅僅在緩沖區滿或者調用flush()時候才把數據寫到目的地。
構造方法:
public BufferedInputStream(InputStream in) public BufferedInputStream(InputStream in,int size)
4.3 管道流
管道流可以實現線程之間的數據的直接傳輸。
(1)管道流模型:
PipedReader/PipedInputStream實現管道的輸入流,而PipedWriter和PipedOutputStream實現輸出流。
(2)管道流的創建:
管道流的創建是將管道輸入流和管道輸出流進行掛連。構造方法有下面兩種方式:
PipedInputStream pInputStream=new PipedInputStream(); PipedOutputStream pOutputStream=new PipedOutputStream(pInputStream); 或者 PipedInputStream pInputStream=new PipedInputStream(); PipedOutputStream pOutputStream=new PipedOutputStream(); pInputStream.connect(pOutputStream); pOutputStream.connect(pInputStream);
(3)管道流實例:單詞處理程序。從文件中讀入單詞,將每個單詞逆序,然后按照逆序排列,最后將逆序還原輸出。
RhymingWords.java:包括main(),reverse()和sort()方法。在main()中調用reverse()和sort()對單詞進行處理,然后處理結果顯示
package ch07;
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.PipedReader;
import java.io.PipedWriter;
import java.io.PrintWriter;
import java.io.Reader;
import ch07.ReverseThread;
import ch07.SortThread;
public class RhymingWords {
public static void main(String[] args) throws IOException {
String pathname="E:\\workspace\\tmpfile\\words.txt";
FileReader words=new FileReader(pathname);
//進行單詞的逆序 排序在逆序還原
Reader rhymedWords=reverse(sort(reverse(words)));
//將處理后的單詞列表輸出顯示
BufferedReader in=new BufferedReader(rhymedWords);
String input;
while((input=in.readLine())!=null)
System.out.println(input);
in.close();
}
//創建管道,創建並且啟動單詞逆序線程
public static Reader reverse(Reader source) throws IOException{
BufferedReader in =new BufferedReader(source);
PipedWriter pipeOut=new PipedWriter();
PipedReader pipeIn=new PipedReader(pipeOut);
PrintWriter out=new PrintWriter(pipeOut);
new ReverseThread(out, in).start();
return pipeIn;
}
public static Reader sort(Reader source) throws IOException{
BufferedReader in=new BufferedReader(source);
PipedWriter pipeOut=new PipedWriter();
PipedReader pipeIn=new PipedReader(pipeOut);
PrintWriter out=new PrintWriter(pipeOut);
new SortThread(out, in).start();
return pipeIn;
}
}
ReverseThread.java:執行逆序的線程類
package ch07;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.PrintWriter;
public class ReverseThread extends Thread {
private PrintWriter out=null;
private BufferedReader in=null;
public ReverseThread(PrintWriter out,BufferedReader in){
this.out=out;
this.in=in;
}
//逆序線程的線程體
public void run(){
if(out!=null && in!=null){
try{
String input;
while((input=in.readLine())!=null){
out.println(reverseIt(input));
out.flush();
}
out.close();
}catch (IOException e) {
System.out.println("ReverseThread run "+e);
// TODO: handle exception
}
}
}
//實現單詞逆序算法
private String reverseIt(String rawWord){
int i,len=rawWord.length();
StringBuffer dest=new StringBuffer(len);
for(i=(len-1);i>=0;i--){
dest.append(rawWord.charAt(i));
}
return dest.toString();
}
}
SortThread.java:執行排序的線程類
package ch07;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.PrintWriter;
public class SortThread extends Thread{
private PrintWriter out=null;
private BufferedReader in=null;
public SortThread(PrintWriter out,BufferedReader in){
this.in=in;
this.out=out;
}
//排序線程的線程體
public void run(){
int MAXWORDS=50;
if(out!=null &&in!=null){
try{
String[] listOfWords=new String[MAXWORDS];
int numWords=0;
while((listOfWords[numWords]=in.readLine())!=null){
numWords++;
}
quickSort(listOfWords,0,numWords-1);
for(int i=0;i<numWords;i++)
out.println(listOfWords[i]);
out.close();
}catch (IOException e) {
// TODO: handle exception
System.out.println("SortThread run:"+e);
}
}
}
//實現快速排序
private static void quickSort(String[] a,int lo0,int hi0){
int lo=lo0;
int hi=hi0;
if(lo>=hi)
return;
String mid=a[(lo+hi)/2];
while(lo<hi){
while(lo<hi&&a[lo].compareTo(mid)<0)
lo++;
while(lo<hi&&a[hi].compareTo(mid)>0)
hi--;
if(lo<hi){
String temp=a[lo];
a[lo]=a[hi];
a[hi]=temp;
lo++;
hi--;
}
}
if(hi<lo){
int temp=hi;
hi=lo;
lo=temp;
}
quickSort(a, lo0, lo);
quickSort(a, lo==lo0?lo+1:lo, hi0);
}
}
在本例中words.txt包含的單詞為:
程序運行結果為:

實現押韻處理。
在該程序中數據流的方向如下:

