Java输入输出流(一)——常用的输入输出流
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包含的单词为:
程序运行结果为:
实现押韵处理。
在该程序中数据流的方向如下: