zoukankan      html  css  js  c++  java
  • Java IO总结

    一、概要

      Java I/O主要包括如下几个层次,包含三个部分:

    • 流式部分――IO的主体部分;
    • 非流式部分――主要包含一些辅助流式部分的类,如:File类、RandomAccessFile类和FileDescriptor等类;
    • 其他类--文件读取部分的与安全相关的类,如:SerializablePermission类,以及与本地操作系统相关的文件系统的类,如:FileSystem类和Win32FileSystem类和WinNTFileSystem类。

      主要的类如下:

    • File(文件特征与管理):用于文件或者目录的描述信息,例如生成新目录,修改文件名,删除文件,判断文件所在路径等。
    • InputStream(二进制格式操作):抽象类,基于字节的输入操作,是所有输入流的父类。定义了所有输入流都具有的共同特征。
    • OutputStream(二进制格式操作):抽象类。基于字节的输出操作。是所有输出流的父类。定义了所有输出流都具有的共同特征。
    • Reader(文件格式操作):抽象类,基于字符的输入操作。
    • Writer(文件格式操作):抽象类,基于字符的输出操作。
    • RandomAccessFile(随机文件操作):一个独立的类,直接继承至Object.它的功能丰富,可以从文件的任意位置进行存取(输入输出)操作

       Java中IO流的体系结构如图:

        

      Java流类的类结构图:

        

    二、字节流

    2.1 输入字节流 InputStream

      基本输入字节流:

       装饰输入字节流:

       InputStream中的三个基本的读方法

      • abstract int read() :读取一个字节数据,并返回读到的数据,如果返回-1,表示读到了输入流的末尾。
      • int  read(byte[] b) :将数据读入一个字节数组,同时返回实际读取的字节数。如果返回-1,表示读到了输入流的末尾。
      • int  read(byte[] b, int off, int len) :将数据读入一个字节数组,同时返回实际读取的字节数。如果返回-1,表示读到了输入流的末尾。off指定在数组b中存放数据的起始偏移位置;len指定读取的最大字节数。

        流结束的判断:方法read()的返回值为-1时;readLine()的返回值为null时。
      

      其它方法

      • long skip(long n):在输入流中跳过n个字节,并返回实际跳过的字节数。
      • int available() :返回在不发生阻塞的情况下,可读取的字节数。
      • void close() :关闭输入流,释放和这个流相关的系统资源。
      • void mark(int readlimit) :在输入流的当前位置放置一个标记,如果读取的字节数多于readlimit设置的值,则流忽略这个标记。
      • void reset() :返回到上一个标记。
      • boolean markSupported() :测试当前流是否支持mark和reset方法。如果支持,返回true,否则返回false。
     2.2 输出字节流 OutputStream

       基本输出字节流:

      装饰输出字节流:

      OutputStream中的三个基本的读方法

      • abstract void write(int b):往输出流中写入一个字节。
      • void write(byte[] b) :往输出流中写入数组b中的所有字节。
      • void write(byte[] b, int off, int len) :往输出流中写入数组b中从偏移量off开始的len个字节的数据。

      其它方法

      • void flush() :刷新输出流,强制缓冲区中的输出字节被写出。
      • void close() :关闭输出流,释放和这个流相关的系统资源。

    三、字符流  

     3.1 输入字符流 Reader

       

      在上面的继承关系图中可以看出:

      • Reader是所有的输入字符流的父类,它是一个抽象类。
      • CharReader、StringReader是两种基本的介质流,它们分别将Char数组、String中读取数据。PipedReader是从与其它线程共用的管道中读取数据。
      • BufferedReader很明显就是一个装饰器,它和其子类负责装饰其它Reader对象。
      • FilterReader是所有自定义具体装饰流的父类,其子类PushbackReader对Reader对象进行装饰,会增加一个行号。
      • InputStreamReader是一个连接字节流和字符流的桥梁,它将字节流转变为字符流。FileReader可以说是一个达到此功能、常用的工具类,在其源代码中明显使用了将FileInputStream转变为Reader的方法。我们可以从这个类中得到一定的技巧。Reader中各个类的用途和使用方法基本和InputStream中的类使用一致。后面会有Reader与InputStream的对应关系。

       主要方法:

      • public int read() throws IOException; //读取一个字符,返回值为读取的字符 
      • public int read(char cbuf[]) throws IOException; /*读取一系列字符到数组cbuf[]中,返回值为实际读取的字符的数量*/ 
      • public abstract int read(char cbuf[],int off,int len) throws IOException; /*读取len个字符,从数组cbuf[]的下标off处开始存放,返回值为实际读取的字符数量,该方法必须由子类实现*/ 

      3.2 输出字符流 Writer

       

      在上面的关系图中可以看出:

      • Writer是所有的输出字符流的父类,它是一个抽象类。
      • CharArrayWriter、StringWriter是两种基本的介质流,它们分别向Char数组、String中写入数据。PipedWriter是向与其它线程共用的管道中写入数据,
      • BufferedWriter是一个装饰器为Writer提供缓冲功能。
      • PrintWriter和PrintStream极其类似,功能和使用也非常相似。
      • OutputStreamWriter是OutputStream到Writer转换的桥梁,它的子类FileWriter其实就是一个实现此功能的具体类(具体可以研究一SourceCode)。功能和使用和OutputStream极其类似.

       主要方法:

      • public void write(int c) throws IOException; //将整型值c的低16位写入输出流
      • public void write(char cbuf[]) throws IOException; //将字符数组cbuf[]写入输出流
      • public abstract void write(char cbuf[],int off,int len) throws IOException; //将字符数组cbuf[]中的从索引为off的位置处开始的len个字符写入输出流
      • public void write(String str) throws IOException; //将字符串str中的字符写入输出流
      • public void write(String str,int off,int len) throws IOException; //将字符串str 中从索引off开始处的len个字符写入输出流 

    四、字符流和字节流的转换

      OutputStreamWriter(OutStreamout):将字节流以字符流输出。  字符到字节的桥梁

      InputStreamReader(InputStream in):将字节流以字符流输入。  字节到字符的桥梁

    BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(new File("D:/1.jpg")),"utf-8"));

    五、非流式文件类--File类

       File类是对文件系统中文件以及文件夹进行封装的对象,可以通过对象的思想来操作文件和文件夹。File类保存文件或目录的各种元数据信息,包括文件名、文件长度、最后修改时间、是否可读、获取当前文件的路径名,判断指定文件是否存在、获得当前目录中的文件列表,创建、删除文件和目录等方法。 

      构造函数:

    • File (String   pathname)   
      • 例:File  f1=new File("FileTest1.txt"); //创建文件对象f1,f1所指的文件是在当前目录下创建的FileTest1.txt
    • File (String  parent  ,  String child)
      • 例:File f2=new  File(“D:\dir1","FileTest2.txt") ;//  注意:D:\dir1目录事先必须存在,否则异常
    • File (File    parent  , String child)
      • 例:File  f4=new File("\dir3");  File  f5=new File(f4,"FileTest5.txt");  //在如果 \dir3目录不存在使用f4.mkdir()先创建

      一个对应于某磁盘文件或目录的File对象一经创建, 就可以通过调用它的方法来获得文件或目录的属性。   

        1)public boolean exists( ) 判断文件或目录是否存在
           2)public boolean isFile( ) 判断是文件还是目录 
           3)public boolean isDirectory( ) 判断是文件还是目录
           4)public String getName( ) 返回文件名或目录名
           5)public String getPath( ) 返回文件或目录的路径。
           6)public long length( ) 获取文件的长度 
           7)public String[ ] list ( ) 将目录中所有文件名保存在字符串数组中返回。 

           File类中还定义了一些对文件或目录进行管理、操作的方法,常用的方法有:
           1) public boolean renameTo( File newFile );    重命名文件
           2) public void delete( );   删除文件
           3) public boolean mkdir( ); 创建目录

     六、RandomAccessFile类

      文件的分隔与合并,随机访问文件。

     

      1.    该对象只能操作文件,所以构造函数接收两种类型的参数:a.字符串文件路径;b.File对象。

     

      2.    该对象既可以对文件进行读操作,也能进行写操作,在进行对象实例化时可指定操作模式(r,rw)

     1 public static void main(String[] args)
     2     {
     3         try
     4         {
     5             insert("d:/out.txt",5,"插入的内容");
     6         }
     7         catch (IOException e)
     8         {
     9             e.printStackTrace();
    10         }
    11     }
    12     
    13     private static void insert(String fileName,long pos,String content) throws IOException
    14     {
    15         //创建临时空文件
    16         File tempFile = File.createTempFile("temp",null);
    17         //在虚拟机终止时,请求删除此抽象路径名表示的文件或目录
    18         tempFile.deleteOnExit();
    19         FileOutputStream fos = new FileOutputStream(tempFile);
    20         
    21         RandomAccessFile raf = new RandomAccessFile(fileName,"rw");
    22         raf.seek(pos);
    23         byte[] buffer = new byte[4];
    24         int num = 0;
    25         while(-1 != (num = raf.read(buffer)))
    26         {
    27             fos.write(buffer,0,num);
    28         }
    29         raf.seek(pos);
    30         raf.write(content.getBytes());
    31         FileInputStream fis = new FileInputStream(tempFile);
    32         while(-1 != (num = fis.read(buffer)))
    33         {
    34             raf.write(buffer,0,num);
    35         }
    36     }
    指定位置插入内容

    七、System类对IO的支持

      针对一些频繁的设备交互,Java语言系统预定了3个可以直接使用的流对象,分别是:

       System.in(标准输入),通常代表键盘输入。其数据类型为InputStream

       System.out(标准输出):通常写往显示器。其数据类型为PrintStream

       System.err(标准错误输出):通常写往显示器。其数据类型为PrintStream

     

  • 相关阅读:
    springboot整合邮件发送(163邮箱发送为例)
    MySQL 容器修改配置文件后无法启动问题(终极解决办法)
    SQLyog无操作一段时间后重新操作会卡死问题(解决办法)
    Linux中配置端口转发(反向代理)
    SpringBoot之整合Quartz调度框架-基于Spring Boot2.0.2版本
    shell脚本报错:-bash: xxx: /bin/sh^M: bad interpreter: No such file or directory
    用xshell连接linux服务器失败 Could not connect to '112.74.73.194' (port 22): Connection failed.
    GooglePlay的多apk命令行安装
    trojan阉割备份
    网易云音乐本地数据库的歌单列表导出,一个不丢,支持1000首以上
  • 原文地址:https://www.cnblogs.com/erbing/p/10040281.html
Copyright © 2011-2022 走看看