Java的IO流大总结

来源:互联网 发布:mac迅雷2.7.3 编辑:程序博客网 时间:2024/04/28 00:26

Java中的流,可以从不同的角度进行分类。

按照数据流的方向不同可以分为:输入流和输出流
按照处理数据单位不同可以分为:字节流和字符流
按照功能不同可以分为:节点流和处理流

字节流:一次读入或读出是8位二进制(也就是一个字节)
字符流:一次读入或读出是16位二进制(char在Java中是16位的,因为Java用的是Unicode
Stream是字节流,Reader,Writer是字符流。

节点流:直接与数据源相连,读入或读出。
处理流:与节点流一块使用,在节点流或处理流的基础上,再套接一层,套接在其他流上的就是处理流。处理流必定有以流为参数的构造函数,例如:

DataInputStream(InputStream in)  //使用指定的底层 InputStream 创建一个 DataInputStream。

节点流只提供了最基础的读写功能,而处理流则提供了更为丰富的功能,例如读整行,带缓冲区读写等

四个最基本的流

官方提供的所有IO流都继承自以下四个抽象类
IO

InputStream 定义了3个read方法

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

read( ) : 从输入流中读取数据的下一个字节。返回 0 到 255 范围内的 int 字节值。如果因为已经到达流末尾而没有可用的字节,则返回值 -1。
read(byte[]) : 其实就是read(b, 0, b.length) ,所以等同于第三个
read(byte[],int off,int len) : 将输入流中最多 len 个数据字节读入 byte 数组。尝试读取 len 个字节,但读取的字节也可能小于该值。以整数形式返回实际读取的字节数。类 InputStream 的 read(b, off, len) 方法重复调用方法 read()。建议子类提供此方法更为有效的实现。
因此,这里的第二第三个方法并没有真正实现缓冲,缓冲与否要看子类的具体实现

OutputStream 定义了3个write方法另外有一个重要的flush方法

//向输出流写入一个字节。要写入的字节是参数 b 的八个低位。b 的 24 个高位将被忽略。void write(int b);  void write(byte[]);  void write(byte[],int off,int len);  void flush()

三个write与read相对应,不再叙述
flush( ) : java在使用输出流时,都会有一个缓冲区,按一种它认为比较高效的方法来发数据:把要发的数据先放到缓冲区,缓冲区放满以后再一次性发过去,而不是分开一次一次地发.而flush()表示强制将缓冲区中的数据发送出去,不必等到缓冲区满.所以在流close之前应先执行flush


Reader流

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

和InputStream相比,除了参数中byte变为char,每次的读取单位由一个字节变为一个字符之外,其余相同

Writer流

//向输出流写入一个字节。要写入的字节是参数 b 的 16 个低位。b 的 16 个高位将被忽略。void write(int b);  void write(char[]);  void write(char[],int off,int len);  void write(String);  void write(String s,int off,int len); void flush()

与OutputStream同理,只是输出单位从字节变为字符。另外,增加了两个输出String的方法,究其原因是因为String类有toCharArray()方法

具体的IO流

文件流 :FileInputStream,FileReader,File……

FileReader 用于读取字符流,是用来读取字符文件的便捷类,因为字符采用Unicode,因此可以读所有语言的文本,前提是文本编码格式为Unicode(windows默认为ANSI)。要读取原始字节流,例如图像,请考虑使用 FileInputStream。 Out和Writer同理。

缓冲流:BufferedInputStream,BufferReader,Buffe……

buffer流为处理流,为其他流提供缓存以及mark和reset等功能,需要指出的是,BufferReader中有readline方法,可以一次读取一行。BufferWriter中有newline方法,可以写入一个换行

转换流:InputStreamReaderOutputStreamFileWriter

将字节流转换为字符流,并能指定转换时使用的解码方式。在字符流与字节流之间架起了一座桥梁,使原本毫无关联的两种流操作能够进行转化,提高了程序的灵活性。

//指定解码方式示例public static void main(String[] args) throws IOException {          FileInputStream fis = new FileInputStream("F:\\test.txt");        InputStreamReader isr = new InputStreamReader(fis,"gbk");/*关于windows默认的ANSI编码,                不同地区ANSI编码是不一样的, 简体中文对应的是 GBK*/        BufferedReader br = new BufferedReader(isr);        System.out.println(br.readLine());    }


数据流:DataInputStream,DataOutputStream

输入输出基本类型,例如writeInt,readChar,以及一个很有用的方法,readUTF与writeUTF

字节数组流:ByteArrayOutputStream,ByteArrayInputStream

Out : 数据被写入一个自动生成的 byte 数组。缓冲区会随着数据的不断写入而自动增长。可使用 toByteArray() 和 toString() 获取数据。
In :能将一个字节数组当成输入,然后根据需要套接处理流,执行各种操作

打印流(标准输出流):PrintWriter,PrintStream

标准打印的方法将内容打印入指定的设备

public static void main(String[] args) throws IOException {          FileOutputStream fos = new FileOutputStream("F:\\test.txt");        PrintStream ps = new PrintStream(fos);//setOut的参数是printStream类型的,因此把file套接成print        System.setOut(ps);//指定输出到文件test.txt        int a = 5;        double d = 76.78;        /*因为已经setOut了,所以以下全部打印到文件里面*/        System.out.println(a);//运用各式各样的标准输出方式        System.out.println(d);        System.out.printf("int = %d double = %f",a,d);    }

运行之后,文件test.txt里面内容:


Scanner(文本扫描器)

Scanner并不是IO流,但配合IO有实用价值,因此也在此写下。Scanner类提供了丰富的处理文本的方法,例如正则,nextInt(),nextDouble(),我们可以通过System.setIn()设定其指定的读取设备

public static void main(String[] args) throws IOException {          FileInputStream fis = new FileInputStream("F:\\test.txt");        System.setIn(fis);        Scanner sc = new Scanner(System.in);        String s = sc.next();//会从输入流读入一个字符串,以空格或换行符为标志        System.out.println(s);        int a = sc.nextInt();        System.out.println(a);    }


对象流:ObjectInputStream,ObjectOutputStream

能将对象序列化与反序列化的流(Serialization(序列化)是一种将对象以一连串的字节描述的过程;反序列化deserialization是一种将这些字节重建成一个对象的过程。)。被序列化的对象需要实现serializable接口,该接口标记型接口,无需写具体实现

public class Welcome {    public static void main(String[] args) throws IOException, ClassNotFoundException {          T obj = new T();        FileOutputStream fos = new FileOutputStream("F:\\ob.dat");        ObjectOutputStream oos = new ObjectOutputStream(fos);        oos.writeObject(obj);        oos.flush();        oos.close();        FileInputStream fis = new FileInputStream("F:\\ob.dat");        ObjectInputStream ois = new ObjectInputStream(fis);        T another = (T) ois.readObject();        System.out.println(another.a + " " + another.d + " " + another.s);    }  }  class T implements Serializable{    int a = 4;    double d = 7.89;    String s = "咸橙";}


本文大多整理自《马士兵_JavaSE基础第08章_IO》视频教程,感谢马老师的辛勤劳动,无私分享。

虽然涵盖了大部分内容,但是IO流的内容不止这些,因此,未完待续……

0 0
原创粉丝点击