【java学习】java.io.Stream 流

1,基本流

java.io内的流类型都分别继承这四种抽象流类型:InputStream,OutputStream,Reader,Writer。
【java学习】java.io.Stream 流_第1张图片

1)InputStream和OutputStream(字节流)

①InputStream

【java学习】java.io.Stream 流_第2张图片
以字节为单位的输入流的超类,InputStream提供了接口从输入流中读取字节数据。

ByteArrayInputStream(字节数组输入流)

内部缓冲区是一个字节数组,本质是通过字节数组来是实现的。

PipedInputStream(管道输入流)

能够实现多线程间的管道通信。

FilterInputStream(过滤输入流)

是DataInputStream和BufferedInputStream的超类。

DataInputStream(数据输入流)

用来装饰其他输入流,允许应用程序以与机器无关方式从底层输入流中读取基本Java数据类型。

BufferedInputStream(缓冲输入流)

作用是为另一个输入流添加缓冲功能。

FileInputStream(文件输入流)

通常用于对文件进行读取操作。

File(文件和目录路径名的抽象表示形式)

File不仅仅表示文件,也可以表示目录,它的超类是Object。

FileDescriptor(文件描述符)

用来表示开放文件,开放套接字等。

ObjectInputStream(对象输入流)

和ObjectOutputStream一起来对基本数据或对象进行持久存储。

②OutputStream

【java学习】java.io.Stream 流_第3张图片
OutputStream是以字节为单位的输出流的超类,提供了write()函数从输出流中读取字节数据。

ByteArrayOutputStream(字节数组输出流)

写入ByteArrayOutputStream的数据被写入到一个byte数组,缓冲区会随着数据的不断写入而自动增长,可使用toByteArray()和toString()获取数据。

PipedOutputStream(管道输出流)

和PipedInputStream一起使用,能实现多线程间的管道通信。

FilterOutputStream(过滤输出流)

是DataOutputStream,BufferedOutputStream和PrintStream的超类

DataOutputStream(数据输出流)

用来装饰其他的输出流,允许应用程序以与机器无关方式向底层写入基本Java数据类型。

BufferedOutputStream(缓冲输出流)

作用是为另一个输出流添加缓冲功能。

PrintStream(打印输出流)

用来装饰其他输出流,为其他输出流添加功能,方便的打印各种数据值

FileOutputStream(文件输出流)

通常用于向文件进行写入操作。

ObjectOutputStream(对象输出流)

它和ObjectInputStream一起对基本数据或者对象的持久存储。

③对应关系

【java学习】java.io.Stream 流_第4张图片

2)Reader和Writer(字符流)

①Reader

【java学习】java.io.Stream 流_第5张图片
Reader是以字符为单位的输入流的超类,它提供了read()接口来取字符数据。

CharArrayReader (字符数组输入流)

用于读取字符数组,继承于Reader。操作的数据是以字符为单位。

PipedReader (字符类型的管道输入流)

它和PipedWriter一起可以通过管道进行进程间的通讯,在使用管道通信时,必须将PipedWriter和PipedReader配套使用。

FilterReader(字符类型的过滤输入流)

BufferedReader(字符缓冲输入流)

作用是为另一个输入流添加缓冲功能。

InputStreamReader(字节转字符的输入流)

它是字节流通向字符流的桥梁。
构造函数:

InputStreamReader(InputStream in)
          创建一个使用默认字符集的 InputStreamReader。
InputStreamReader(InputStream in, Charset cs)
          创建使用给定字符集的 InputStreamReader。
InputStreamReader(InputStream in, CharsetDecoder dec)
          创建使用给定字符集解码器的 InputStreamReader。可以指定字符编码格式 。
InputStreamReader(InputStream in, String charsetName)
          创建使用指定字符集的 InputStreamReader。 

FileReader(字符类型的文件输入流)

通常用于对文件进行读取操作。

②Writer

【java学习】java.io.Stream 流_第6张图片
Writer是以字符为单位的输出流的超类,它提供了writer()函数,进行对字符的写。

CharArrayWriter(字符数组输出流)

用于读取字符数组,继承于Writer,操作数据的单位是字符。

PipedWriter(字符类型的管道输出流)

它和PipedReader一起是可以通过管道进行线程间的通讯,在使用管道通信时,必须将PipedReader和PipedWriter配套使用。

FilterWriter(字符类型的过滤输出流)

BufferedWriter(字符缓冲输出流)

作用是为另一个输出流添加缓冲功能。

OutStreamWriter(字节转字符的输出流)

是字节通向字符流的桥梁。

FileWriter (字符类型的文件输出流)

File(获取文件或者目录对象)

PrintWriter(字符类型的打印输出)

用来装饰其他输出流,能为其他的输出流添加功能。

③对应关系

【java学习】java.io.Stream 流_第7张图片

3)字节转换为字符流

①框架

【java学习】java.io.Stream 流_第8张图片
(1)FileReader继承于InputStreamReader,而InputStreamReader依赖于InputStream,因为InputStreamReader的构造函数是以InputStream为参数,传人InputStream会在InputStreamReader内部通过转码,将字节转换成字符。
(2)FileWriter继承于OutputStreamWriter,而OutStreamWriter依赖于OutputStream,因为OutputStreamWriter的构造函数是以OutputStream为参数,我们传人OutputStream会在OutputStreamWriter内部通过转码,将字节转换成字符。

②字节和字符的输入流对应关系

【java学习】java.io.Stream 流_第9张图片

③字节和字符的输出流对应关系

【java学习】java.io.Stream 流_第10张图片

2,分类

1)按功能分

①节点流

是可以从一个特定的数据源(节点)读写数据的流(例如文件,内存)。
可以从或向一个特定的地方(节点)读写数据。如FileReader.

节点流分类:
【java学习】java.io.Stream 流_第11张图片

②处理流

是“连接”在已经存在的流(节点流或处理流)之上,通过对数据的处理为程序提供更为强大的读写功能。
是对一个已存在的流的连接和封装,通过所封装的流的功能调用实现数据读写。如BufferedReader.处理流的构造方法总是要带一个其他的流对象做参数。一个流对象经过其他流的多次包装,称为流的链接。

处理流分类:
【java学习】java.io.Stream 流_第12张图片
常用的处理流有:缓冲流,转换流,数据流,对象流,打印流。

i>缓冲流

要套接在相应的字节流之上,对读写的数据提供了缓冲功能,提高了读写的效率,同时也增加了一些更方便方法。
由于带了缓冲功能,所以就写数据的时候需要使用flush方法。

import java.io.*; 
public class TestBufferStream{ 
  public static void main(String[] args){ 
    try{ 
       BufferedWriter bw=new BufferedWriter(new FileWriter("F:\\Java\\IO\\dat.txt"));//在对写文件的字节流上套接上缓冲流 
       BufferedReader br=new BufferedReader(new FileReader("F:\\Java\\IO\\dat.txt"));//在对读文件的字节流上套接上缓冲流 
       String s=null; 
       for(int i=1;i<=100;i++){ 
        s=String.valueOf(Math.random());//通过随机函数给s赋值 
        bw.write(s);          //将s写入到dat.txt文件中 
        bw.newLine();          //写入一个分行符。缓冲流比较好用的方法就是可以写入或读取一行的数据。 
       } 
       bw.flush();            //使内存中的所有数据立刻写出,不再缓冲。 
       while((s=br.readLine())!=null){  //按行读取文件内容 
        System.out.println(s); 
       } 
       bw.close();            //关闭处理流同时关闭里面的节点流。 
       br.close(); 

    } 
    catch(IOException e){ 
       e.printStackTrace(); 
    } 
  } 
} 

ii>转换流

用与字节数据到字符数据之间的转化。InputStreamReader需要和InputStream套接,OutputStreamWriter需要和outputStream套接。

iii>数据流

DataInputStream 和DataOutputStream 提供将基础数据类型写入到文件中,或者读取出来,这个流的用处还是很大的,如果没有这种流的话,有一个long,本身只占8个字节,如果我要写入到文件,需要转成字符串,然后在转成字符数组,那空间会占用很多,但是有了这种流之后就很方便了,直接将这8个字节写到文件就可以了,既节约了内存空间也使程序写起来更加方便简单。但是读取的时候需要注意了,根据读取的数据类型,指针会往下移,所以你读的顺序必须要和写的顺序一致才能完成你正确的需求。否则就相当与把数据拆分了。

import java.io.*; 
public class TestDataStream{ 
   public static void main(String[] args){ 
     ByteArrayOutputStream baos=new ByteArrayOutputStream();  //建一个节点流。 
     DataOutputStream dos=new DataOutputStream(baos);     //在节点流上接一根数据流“管道”                  try{ 
       dos.writeDouble(Math.random());            //double型 ,占8个字节  
       dos.writeBoolean(true);                //boolean型,占一个字节 
       ByteArrayInputStream bais=new ByteArrayInputStream(baos.toByteArray());  
       System.out.println(bais.available());         //输出流中总的可用字节数--9 
       DataInputStream dis=new DataInputStream(bais);    //同样在输出流的外面接上数据流“管道” 
       System.out.println(dis.readDouble());         //直接读出double型的数 
       System.out.println(dis.readBoolean());        //直接读出boolean型 
       dos.close(); 
       dis.close(); 
     }catch(IOException e){ 
       e.printStackTrace(); 
     } 

   } 
} 

iv>对象流

java.io中专门提供用于打印的流,这类流在写入的时候有自动flush的功能,所以不需要每打印一个东西都flush一次。

import java.io.*; 
public class TestPrintStream1{ 
    public static void main(String[] args){ 
      PrintStream ps=null; 
      try{ 
       FileOutputStream fos=new FileOutputStream("F:\\Java\\IO\\log.dat");//创建输出流,指定输出地点 
       ps=new PrintStream(fos);                      //在流外面包装打印流 
      }catch(IOException e){ 
       e.printStackTrace(); 
      } 
      if(ps!=null){ 
       System.setOut(ps);                         //将系统的打印设置成打印流ps 
      } 
      int ln=0; 
      for(char c=0;c<=60000;c++){ 
        System.out.print(c+" ");                     //不在打印到dos窗口,输出流直接打印到指定文件中 
        if(ln++>=100){ 
           System.out.println();ln=0; 
        } 
      } 
    } 
} 

v>打印流

2)按流的方向不同

①输入流

②输出流

3)按处理数据单位不同

①字节流(8位)

②字符流(16位)

3,文件的读写

package task_scheduling;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.UnsupportedEncodingException;

public class FileUtil {

    /**
     * 读文件 返回字符串
     * @param url
     *            文件地址,如:"/sdcard/test.txt"
     * @return
     * @throws IOException 
     */
    public static String readFile(String url) throws IOException {
        // 读取
        String str = ""; // 读取到的内容
        File urlFile = new File(url);
        InputStreamReader isr = new InputStreamReader(new FileInputStream(urlFile), "UTF-8");
        BufferedReader br = new BufferedReader(isr);

        String mimeTypeLine = null;
        while ((mimeTypeLine = br.readLine()) != null) {
            str = str + mimeTypeLine;
        }
        System.out.println("FileUtil读取内容:" + str);
        return str;
    }
    /**
     * 写文件,成功返回true
     * @param filePath 文件地址
     * @param sourceString 待写入字符串
     * @return
     */
    public static boolean writeFile(String filePath, String sourceString){
        //写入
        try{
            System.out.println("写入文件信息:" + sourceString);
            byte[] sourceByte = sourceString.getBytes();  
            if(null != sourceByte){  
                    File file = new File(filePath);     //文件路径(路径+文件名)  
                    if (!file.exists()) {   //文件不存在则创建文件,先创建目录  

                        file.createNewFile();  
                    }  
                    FileOutputStream outStream = new FileOutputStream(file);    //文件输出流用于将数据写入文件  
                    outStream.write(sourceByte);  
                    outStream.close();  //关闭文件输出流  
            }  
        }catch(Exception e){
            System.out.println("写入失败");
            return false;
        }
        System.out.println("写入成功");
        return true;
    }
}

你可能感兴趣的:(java学习)