java IO流总结

来源:互联网 发布:深入理解php原理鸟哥 编辑:程序博客网 时间:2024/05/01 21:13

语法很乱,想到一点加一点。

File类,作为IO流输入输出的基本介质中的一种,在java中封装成类,其中存储着一系列文件信息,getPath()返回此相对路径名的一个路径名字符串。getAbsolutePath() 返回此相对路径名的绝对路径名形式。exists()判断文件是否存在,delete()删除文件,createNewFile()创建,以及一系列对文件属性的getter于setter方法。

 

RandomAccessFile类,支持对随机访问文件的读取和写入。随机访问文件的行为类似存储在文件系统中的一个大型 byte 数组。他里面存在着一个文件指针,该文件指针可以通过getFilePointer 方法读取,并通过seek 方法设置。 构造函数中mode参数通过"rw""r""w"设置。他事先了DataInput和DataOutput接口,也就是于DatainputStream和DataOutputStream现实了相同的接口,所以他拥有了读写数据的功能,从而拥有读写各种数据类型的方法。

 

输入输出流以内存为参照,写入内存便是input输入流,将内存中的数据传递出内存便是output输出流。

 

InputSteam所有字节输入流的抽象类,也可以说将整个字节输出流的类继承层次看做为装饰模式,而inputStream就被看做成为被装饰对象,和所有装饰器一个公共的接口。read()方法读取一个字节,返回讲字节转换成的int类型。read(byte[])方法读取一个字节数组,返回读取到字节数组的长度,read(byte[],int begin,int length)方法,所有read方法重载返回-1则表示读取到流的最后;在输入数据可用不等于-1又检测到流末尾或者抛出异常前,此方法一直阻塞。

while(read()!=-1)

{读写操作;}

 

OutputStream同理,所有字节输出流的抽象类。flush刷新方法,将输出流缓冲区中的数据刷新写入到流中,调用close()方法时会自动调用flush方法以及写入方法,write()相关重载于输入流read方法同理。

 

FileInputStream 从文件系统中的某个文件中获得输入字节,比如MP3文件,视频文件等等,原始的字节流文件。

FileOutputStream 用于写入原始字节的流。

FilterInputStream 相当于IO流中应用装饰模式中充当抽象装饰器,拥有一个protected inputStream in字段,继承自此类的都可看做为具体的包装器,可以为被装饰对象添加一系列额外的功能。

FilterOutputStream同理。

 

BufferedInputStream 提高输入流效率,他的字段中提供了一个缓冲的byte[]数组。在读取或跳过流中的字节时,可根据需要从包含的输入流再次填充该内部缓冲区,一次填充多个字节。mark 操作记录输入流中的某个点,reset操作使得在从包含的输入流中获取新字节之前,再次读取自最后一次mark 操作后读取的所有字节。

 

BufferedOuputStream 该类实现缓冲的输出流。通过设置这种输出流,应用程序就可以将各个字节写入底层输出流中,而不必针对每次字节写入调用底层系统。

 

其它过滤流操作与BufferInputStream和BufferedOuputStream 同理;

 

Reader 字符输入流所有类得抽象类,用于读取字符流;提供一个protected字段Object类型lock字段,用于同步针对此流的操作的对象。为了提高效率,字符流对象可以使用其自身以外的对象来保护重要部分。因此,子类应使用此字段中的对象,而不是this 或者同步的方法

提供read方法,放回单个字符,read(char[]),read(char[],int begin,int length)与字节流read()同理,读取到末尾返回-1。

 

Writer 同reader抽象类,及outputStream相识,就是读取的是字符;

 

 PipedInputStream 管道输入流,管道输入流应该连接到管道输出流;管道输入流提供要写入管道输出流的所有数据字节。通常,数据由某个线程从流对象读取,并由其他线程将其写入到相应的输出流中。这两个对象不建议尝试使用单个线程,因为这样可能死锁线程。管道输入流包含一个缓冲区,可在缓冲区限定的范围内将读操作和写操作分离开。PipedOutputStream同理相反。

 

ObjectInputStream以及ObjectOutputSream序列化以及反序列化,分别与 FileOutputStream 和 FileInputStream 一起使用时,可以为应用程序提供对对象图形的持久存储。ObjectInputStream 用于恢复那些以前序列化的对象。但只有对与实现了Serializable 借口的对象才能进行序列化于反序列化。他们分别使用readObject方法以及writeObject方法对对象实现读取以及写入的操作。

他们分别还实现了DataInput和DataOutput接口,所以也有相应对基本数据类型的读写方法。

 

IntputStreamReader以及OutputStreamWriter 转换流,主要作用用于将字节流转换成为字符流。

还有一点是OutputStreamWriter流的close方法调用前,必须先调用flush刷新方法。所以不管什么输出流,调用前都养成关闭先刷新的习惯吧?

 

 在IO 中涉及到编码转换的流是转换流和打印流。
    但是打印流只有输出。

    在转换流中是可以指定编码表的。
    默认情况下,都是本机默认的码表。GBK.                 这个编码表怎么来的?
    System.getProperty("file.encoding");

    常见码表:
    ASCII:美国标准信息交换码。使用的是1 个字节的7 位来表示该表中的字符。

    ISO8859-1:拉丁码表。使用1 个字节来表示。

    GB2312:简体中文码表。
    GBK:简体中文码表,比GB2312 融入更多的中文文件和符号。

    unicode:国际标准码表。都用两个字节表示一个字符。
    UTF-8:对unicode 进行优化,每一个字节都加入了标识头。

    编码转换:
    字符串 -->字节数组 :编码。通过getBytes(charset);
    字节数组-->字符串 :解码。通过String 类的构造函数完成。String(byte[],charset);

    如果编错了,没救!
    如果编对了,解错了,有可能还有救!

    String s = "你好";
    //编码。
    byte[] b = s.getBytes("GBK");

    //解码。
    String s1 = new String(b,"iso8859-1");
    System.out.println(s1);//????

 

 //想要还原。
 /*

  对s1 先进行一次解码码表的编码。获取原字节数据。
  然后在对原字节数据进行指定编码表的解码。
  */
  byte[] b1 = s1.getBytes("iso8859-1");

  String s2 = new String(b1,"gbk");

  System.out.println(s2);//你好。

  这种情况在tomcat 服务器会出现。
  因为tomcat 服务器默认是iso8859-1 的编码表。
  所以客户端通过浏览器向服务端通过get 提交方式提交中文数据时,
  服务端获取到会使用ISO8859-1 进行中文数据的解码。会出现乱码。
  这时就必须要对获取的数据进行iso8859-1 编码。然后在按照页面指定的编码表进行解
  码即可

  而对于post 提交,这种方法也通用。但是post 有更好的解决方式。
  request.setCharacterEncoding("utf-8");即可。
  所以建立客户端提交使用post 提交方式。