Java基础——IO(流)

来源:互联网 发布:马尔科夫概率矩阵 编辑:程序博客网 时间:2024/06/05 15:39

Ø      java.io 包中定义了多个流类型(类或抽象类)来实

  现输入/输出功能;可以从不同的角度对其进行分类:

    •  按数据流的方向不同可以分为输入流和输出流。(以程序的角度来考虑)
    •  按处理数据单位不同可以分为字节流和字符流。
    •  按照功能不同可以分为节点流和处理流。

节点流和处理流

Ø      节点流为可以从一个特定的数据源(节点)读写数据(如:文件,内存)

Ø      处理流是连接在已存在的流(节点流或处理流)之上,通过对数据的处理为程序提供更为强大的读写功能。

InputStream

Ø      继承自InputSteam的流都是用于向程序中输入数据,且数据的单位为字节(8 bit);下图中深色为节点流,浅色为处理流。

InputStream的基本方法

//读取一个字节并以整数的形式返回(0~255),

//如果返回-1已到输入流的末尾。

int read() throws IOException

 

//读取一系列字节并存储到一个数组buffer

//返回实际读取的字节数,如果读取前已到输入流的末尾返回-1

int read(byte[] buffer) throws IOException

 

//读取length个字节

//并存储到一个字节数组buffer,从off位置开始存,最多len

//返回实际读取的字节数,如果读取前以到输入流的末尾返回-1

int read(byte[] buffer, int off, int len)

                      throws IOException

//关闭流释放内存资源

void close() throws IOException

 

 

OutputStream

继承自OutputSteam的流是用于程序中输入数据,且数据的单位为字节(8 bit);下图中深色为节点流,浅色为处理流

 

OutputStream的基本方法

//向输出流中写入一个字节数据,该字节数据为参数b的低8

void write(int b) throws IOException

 

//将一个字节类型的数组中的数据写入输出流

void write(byte[] b) throws IOException

 

//将一个字节类型的数组中的从指定位置(off)开始的

//len个字节写入到输出流

void write(byte[] b, int off, int len)

                      throws IOException

//关闭流释放内存资源

void close() throws IOException

 

//将输出流中缓冲的数据全部写出到目的地

void flush() throws IOException

 

良好的编程习惯à,flush(),close()

 

Reader

Ø      继承自Reader的流都是用于向程序中输入数据,且数据的单位为字符(16 bit);下图中深色为节点流,浅色的为处理流。

 

为什么要有字符流(两个字节):比如汉字是两个字节的字符,如果只有字节流,那么每次只能读写半个汉子。

 

Reader 的基本方法:

//读取一个字符并以整数的形式返回(0~231-1),

//如果返回-1已到输入流的末尾。

int read() throws IOException

 

//读取一系列字符并存储到一个数组buffer

//返回实际读取的字符数,如果读取前已到输入流的末尾返回-1

int read(char[] cbuf) throws IOException

 

//读取length个字符

//并存储到一个数组buffer,从off位置开始存,最多读取len

//返回实际读取的字符数,如果读取前以到输入流的末尾返回-1

int read(char[] cbuf, int off, int len)

                      throws IOException

//关闭流释放内存资源

void close() throws IOException

 

Writer

Ø      继承自Writer的流都是用于程序中输入数据,且数据的单位为字符(16 bit);下图中深色为节点流,浅色为处理流。

Writer 的基本方法

//向输出流中写入一个字符数据,该字节数据为参数b的低16

void write(int c) throws IOException

//将一个字符类型的数组中的数据写入输出流,

void write(char[] cbuf) throws IOException

//将一个字符类型的数组中的从指定位置(offset)开始的

//length个字符写入到输出流

void write(char[] cbuf, int offset, int length)

                      throws IOException

//将一个字符串中的字符写入到输出流

void write(String string) throws IOException//实际上是调用了String类型的toCharArry方法。

//将一个字符串从offset开始的length个字符写入到输出流

void write(String string, int offset, int length)

                      throws IOException

//关闭流释放内存资源

void close() throws IOException

//将输出流中缓冲的数据全部写出到目的地

void flush() throws IOException

 

节点流类型

 

字符流

字节流

File(文件)

FileReader

FileWriter

FileInputStream

FileOutputStream

Memory Array

CharArrayReader

CharArrayWriter

ByteArrayInputStream

ByteArrayOutputStream

Memory String

StringReader

StringWriter

Pipe(管道)

PipedReader

PipedWriter

PipedInputStream

PipedOutputStream

 

 

 

EG1

 

publicclass TestFileInputStream {    /**    * @param args    */   publicstaticvoid main(String[] args) {      // TODO Auto-generated method stub            long num = 0;//用来统计读取的字节数。      int i=0;//    FileInputStream in = null;      FileReader in = null;      String path = "E:\\练习\\java\\Workspaces\\Test\\src\\com\\ui\\IO\\TestFileInputStream.java";      try {//       in = new FileInputStream(path);         in = new FileReader(path);      } catch (FileNotFoundException e) {         // TODO Auto-generated catch block         System.out.println("找不到指定文件");         System.exit(-1);      }            try {         while((i=in.read())!=-1){            System.out.print((char)i);//将i转换为char类型            num++;         }         in.close();//关闭流         System.out.println("共读取了"+num+"个字节!");      } catch (IOException e) {         // TODO Auto-generated catch block         System.out.println("文件读取错误!");         System.exit(-1);      }    } }


Eg2

publicclass TestFileOutputStream {    /**    * @param args    */   publicstaticvoid main(String[] args) {      // TODO Auto-generated method stub      int i = 0;      FileInputStream in = null;      FileOutputStream out = null;      String path = "E:\\练习\\java\\Workspaces\\Test\\src\\com\\ui\\IO\\TestFileInputStream.java";      String path2 = "E:\\练习\\java\\Workspaces\\Test\\src\\com\\ui\\IO\\TestFileInputStream2.java";      try {         in = new FileInputStream(path);         out = new FileOutputStream(path2);          while ((i = in.read()) != -1) {            out.write((char) i);//将从in中读取到的字节写入到out所指定的文件中         }         in.close();         out.close();      } catch (FileNotFoundException e) {         // TODO Auto-generated catch block         System.out.println("找不到指定文件!");         System.exit(-1);      } catch (IOException e) {         // TODO Auto-generated catch block         System.out.println("文件复制错误!");         System.exit(-1);      }   System.out.println("文件复制成功!");    }}

处理流类型:

 

处理类型

字符流

字节流

Buffering

BufferedReader

BufferedWriter

BufferedInputStream

BufferedOutputStream

Filtering

FilterReader

FilterWriter

FilterInputStream

FilterOutputStream

Converting between bytes and character

InputStreamReader

OutputStreamWriter

 䦋㌌㏒㧀좈琰茞Ü

Object Serialization

ObjectInputStream

ObjectOutputStream

Data conversion

DataInputStream

DataOutputStream

Counting

LineNumberReader

LineNumberInputStream

Peeking ahead

PusbackReader

PushbackInputStream

Printing

PrintWriter

PrintStream

 

缓冲流

Ø       缓冲流要套接在相应的节点流之上,对读写的数据提供了缓冲的功能,提高了读写的效率,同时增加了一些新的方法。

Ø       J2SDK提供了四种缓存流,其常用的构造方法为:

BufferedReader(Reader in)

BufferedReader(Reader in,int sz) //sz为自定义缓存区的大小

BufferedWriter(Writer out)

BufferedWriter(Writer out,int sz)

BufferedInputStream(InputStream in)

BufferedInputStream(InputStream in,int size)

BufferedOutputStream(OutputStream out)

BufferedOutputStream(OutputStream out,int size)

 

l       BufferedReader提供了readLine方法用于读取一行字符串(以\r\n分隔)。

l       BufferedWriter提供了newLine用于写入一个行分隔符。

l       对于输出的缓冲流,写出的数据会先在内存中缓存,使用flush方法将会使内存中的数据立刻写出。

 

Eg

publicclass TestBufferedInputStream {    /**    * @param args    */   publicstaticvoid main(String[] args) {      // TODO Auto-generated method stub      FileInputStream in = null;      BufferedInputStream bis = null;      String path = "E:\\练习\\java\\Workspaces\\Test\\src\\com\\ui\\IO\\TestFileInputStream.java";      try {         in = new FileInputStream(path);         bis = new BufferedInputStream(in);         int c = 0;         System.out.println((char)bis.read());         System.out.println((char)bis.read());         bis.mark(100);//标记,从in的第100个字节开始读。         for(int i=0;i<=10&&(c=bis.read())!=-1;i++){            System.out.print((char)c+" ");         }         System.out.println();         bis.reset();//重新回到标记处。         for(int i=0;i<=10&&(c=bis.read())!=-1;i++){            System.out.print((char)c+" ");         }         bis.close();      } catch (FileNotFoundException e) {         // TODO Auto-generated catch block         e.printStackTrace();      } catch (IOException e) {         // TODO Auto-generated catch block         e.printStackTrace();      }   }} 
Eg2
publicclass TestBufferedWriter {    /**    * @param args    */   publicstaticvoid main(String[] args) {      // TODO Auto-generated method stub      try {         BufferedWriter bw=new BufferedWriter(new FileWriter("E:\\练习\\java\\Workspaces\\Test\\src\\com\\ui\\IO\\dat.text"));         BufferedReader br=new BufferedReader(new FileReader("E:\\练习\\java\\Workspaces\\Test\\src\\com\\ui\\IO\\dat.text"));         String s;         for(int i=0;i<=100;i++){            s=String.valueOf(Math.random());//产生0-1之间的100个随即数。            bw.write(s);//将随即数写入到文件中。            bw.newLine();//每写入一个数就会换一行。         }         bw.flush();//清空缓存。         while((s=br.readLine())!=null){            System.out.println(s);         }         bw.close();         br.close();      } catch (IOException e) {         // TODO Auto-generated catch block         e.printStackTrace();      }   }}

转换流

l       InputStreamReaderOutputStreamWriter用与字节数据到字符数据之间的转换。

l       InputStreamReader 需要和 InputStream “套接

l       OutpStreamWriter 需要和 OutputStream “套接

l       转换流在构造时可以指定其编码集合,例如:

InputStreamReader isr = new InputStreamReader(System.in, “ISO8859_1”)

Eg1

publicclass TestTrasForm1 {    /**    * @param args    */   publicstaticvoid main(String[] args) {      // TODO Auto-generated method stub      try {         OutputStreamWriter osw=new OutputStreamWriter(                new FileOutputStream("E:\\练习\\java\\Workspaces\\Test\\src\\com\\ui\\IO\\dat.text"));         osw.write("你好");         System.out.println(osw.getEncoding());         osw.close();         osw=new OutputStreamWriter(                //参数true表示在源文件的末尾添加,不会覆盖原来的文件里面的内容。                new FileOutputStream("E:\\练习\\java\\Workspaces\\Test\\src\\com\\ui\\IO\\dat.text",true),"ISO8859_1");         osw.write("nihao");         System.out.println(osw.getEncoding());         osw.close();      } catch (IOException e) {         // TODO Auto-generated catch block         e.printStackTrace();      }   }}


 

Eg2

publicclass TestTransForm2 {   /**    * @param args    */   publicstaticvoid main(String[] args) {      // TODO Auto-generated method stub      InputStreamReader isr=new InputStreamReader(System.in);//阻塞式方法,程序既不会停止也不会往前执行,会停在这里等待输入。      BufferedReader br=new BufferedReader(isr);//为什么还要套用一层BufferedReader?readLine方法。       String s=null;      try {         s=br.readLine();         while(s!=null){            //如果输入的字符等于exit(忽略大小写)则程序推出。            if(s.equalsIgnoreCase("exit")){                break;            }            System.out.println(s.toUpperCase());            s=br.readLine();         }         br.close();      } catch (IOException e) {         // TODO Auto-generated catch block         e.printStackTrace();      }   }}

数据流&ByteArrayInputStream&ByteArrayOutputStream

l       DataInputStream DataOutputStream分别继承自InputSteam OutputStream,它属于处理流,需要分别套接InputStreamOutputStream类型的节点流上。

l       DataInputStreamDataOutputStream提供了可以存取与机器无关的Java原始类型数据(如:intdouble等)的方法。

l       DataInputStreamDataOutputStream的构造方法为:

§         DataInputStream ( InputStream in )

§         DataOutputStream ( OutputStream out )

Eg

publicclass TestDataStream {    /**    * @param args    */   publicstaticvoid main(String[] args) {      // TODO Auto-generated method stub      ByteArrayOutputStream baos=new ByteArrayOutputStream();      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) {         // TODO Auto-generated catch block         e.printStackTrace();      }   }}

 

Print 流

l       PrintWriter和PrintStream 都属于输出流,分别针对与字符和字节。

l       PrintWriter和PrintStream提供了重载的print

l          Println方法用于多种数据类型的输出。

l       PrintWriter和PrintStream的输出操作不会抛出异常,用户通过检测错误状态获取错误信息。

l       PrintWriter和PrintStream有自动flush功能。

 

PrintWriter(Writer out)

PrintWriter(Writer out,boolean autoFlush)

PrintWriter(OutputStream out)

PrintWriter(OutputStream out,boolean autoFlush)

PrintStream(OutputStream out)

PrintStream(OutputStream out,booleanautoFlush)

 

Eg1

publicclass TestPrintStream1 {    /**    * @param args    */   publicstaticvoid main(String[] args) {      // TODO Auto-generated method stub      PrintStream ps = null;      try {         FileOutputStream fos = new FileOutputStream(                "E:\\练习\\java\\Workspaces\\Test\\src\\com\\ui\\IO\\dat.text");         ps = new PrintStream(fos);      } catch (FileNotFoundException e) {         // TODO Auto-generated catch block         e.printStackTrace();      }      if(ps!=null){         System.setOut(ps);//重新分配“标准”输出流。输出到ps指定的文件中而不是控制台。      }      int ln=0;      for(char i=0;i<=10000;i++){         System.out.print(i+" ");         ln++;         if(ln==100){            System.out.println();            ln=0;         }      }   }}

 

Eg2

 

publicclass TestPrintStream2 {    /**    * @param args    */   publicstaticvoid main(String[] args) {      // TODO Auto-generated method stub      String s=null;      BufferedReader br = new BufferedReader(new InputStreamReader(System.in));      try {         FileWriter fw = new FileWriter(                "E:\\练习\\java\\Workspaces\\Test\\src\\com\\ui\\IO\\logfile.log",true);         PrintWriter logPW=new PrintWriter(fw);         while((s=br.readLine())!=null){            if(s.equalsIgnoreCase("exit")){                break;            }            System.out.println(s.toUpperCase());            logPW.println("------");            logPW.println(s);            logPW.flush();//可以自动的flush 可以不写。         }         logPW.println("======"+new Date()+"======");         logPW.flush();         logPW.close();      } catch (IOException e) {         // TODO Auto-generated catch block         e.printStackTrace();      }   }}

 

Object

 

³     直接将Object写入或读出

²     transient关键字

²     serializable接口//如果想把某个类的对象序列化必须实现这个接口

²     Externalizable 接口

±     void writeExternal(ObjectOutput out) throws IOException

±     void readExternal(ObjectInput in) throws IOException, ClassNotFoundException

 

Eg

publicclass TestObjectIO {    /**    * @param args    */   publicstaticvoid main(String[] args) {      // TODO Auto-generated method stub      T t=new T();      t.k=8;      try {         FileOutputStream fos = new FileOutputStream("E:\\练习\\java\\Workspaces\\Test\\src\\com\\ui\\IO\\test.dat");         ObjectOutputStream oos=new ObjectOutputStream(fos);         oos.writeObject(t);         oos.flush();         oos.close();                  FileInputStream fis=new FileInputStream("E:\\练习\\java\\Workspaces\\Test\\src\\com\\ui\\IO\\test.dat");         ObjectInputStream ois=new ObjectInputStream(fis);         T tRead=(T)ois.readObject();         System.out.println(tRead.i+" "+tRead.j+" "+tRead.d+" "+tRead.k);      } catch (Exception e) {         // TODO Auto-generated catch block         e.printStackTrace();      }         } }//Serializable接口表示可以被序列化的,该接口没有任何方法。用来标记表示这个类的对象可以序列化class T implements Serializable{   inti=10;   intj=9;   doubled=2.5;   transientintk=2;//transient关键字表示透明的,在序列化的时候不予考虑,即为变量类型默认的值。}


参考资料:尚学堂。。。。。。 





 


原创粉丝点击