java SE ------ IO基础知识整理

java IO操作主要指使用java进行输入输出操作,以内存为基准,按照数据流动的方向,将流向内存的称为输入流,流出内存的称为输出流。对于输入输出流,又细分为字节输入流,字节输出流,字符输入流,字符输出流。下面笔者将对这些流的基本使用进行介绍,如有错误还请批评指正。

IO流的分类图,左边按字节和字符流划分,右边按输入输出流划分。

在这里插入图片描述

字节输入流(InputStream)

一.基础知识
1.InputStream是一个抽象类,是所有字节输入的父类
2.根类常用的成员方法:
(1)abstract int read() 从输入流中读取数据的下一个字节。
(2)int read(byte[] b) 从输入流中读取一定数量的字节,并将其存储在缓冲区数组 b 中。
(3)void close() 关闭此输入流并释放与该流关联的所有系统资源
3.常用的已实现的子类:
(1)FileInputStream 文件字节输入流。从文件系统中的某个文件中获得输入字节。哪些文件可用取决于主机环境。
(2)BufferedInputStream 字节缓冲输入流

二.使用方法
1.FileInputStream的使用方法

/*
一次读取一个字节

注意事项:
1.构造方法:
  (1)FileInputStream(File file) 过打开一个到实际文件的连接来创建一个 FileInputStream,该文件通过文件系统中的File 对象 file 指定
  (2)FileInputStream(String name) 过打开一个到实际文件的连接来创建一个 FileInputStream,该文件通过文件系统中的路径名 name 指定

2.父类成员方法详细分析
  (1)abstract int read() 返回读取到字节的值,如果读取到文件末尾将会返回-1

*/
public class Main{
   public static void main(String[] args) throws IOException{
       FileInputStream fis = new FileInputStream("参数");
       int len = 0;
       while((len=fis.read())!=-1){
          System.out.println((char)len);
       }
  
       fis.close();
   }
}
/*
一次读取多个字节

注意事项:
1.父类成员方法分析:
  (1)int read(byte[] b) 返回值是读取到的有效字节的个数,并将其存储在缓冲区数组 b 中,若没有可读字节将会返回-1
2.如何将字节数组转化为字符串?
  调用String类的构造方法new String(byte[] bytes, int offset, int length) offset为起始位置,length是为要转化的长度 

*/

public class Main{
   public static void main(String[] args){
      FileInputStream fis = new FileInputStream("参数");
      int len = 0;
      byte[] by = new byte[1024];
 
      while((len=fis.read(by))!=-1){
          System.out.println(new String(by,0,len));
      }
   }
}

三.原理分析
1.一次读取一个字节的原理分析
当程序执行读取文件的代码时,这事当前的程序会将此任务转交给JVM虚拟机,JVM虚拟机再将此任务交给操作系统os,由操作系统完成文件 的读取,然后依次返回.
在这里插入图片描述
2.使用一次读取一个字节数组的数据需要注意的问题
(1)方法int read(byte[] b)的返回值是读取到的有效字节的个数,那么何为有效字节呢?我们列如下例子:
eg:要读取的文本数据为: abcdefg ,规定参与读取的字节数组的大小为2,即byte by[2],请简述其读取过程.
初始 字节数组的内容: 0 0 (为了叙述方便,我们假设字节数组的里存的是真实数据)
第一次读取 字节数组的内容: a b 有效字节个数为2
第二次读取 字节数组的内容: c d 有效字节个数为2
第三次读取 字节数组的内容: e f 有效字节个数为2
第四次读取 字节数组的内容: g f 有效字节个数为1
这也是为什么我们在将字节数组转化为字符数组时更多使用 new String(byte[] bytes, int offset, int length),这样就可以避免重复计入数据 问题。如上例的第四次读取,最后一次由于只读取到一个有效字符g,故只能覆盖数组的第一个值,导致第二个值并没有被覆盖,如果使用new String(byte[] bytes, int offset, int length)输出就只会输出g,而使用 new String(byte[] bytes)则会输出g f,后者显然是错误的.

(2)数组的大小最好为1024的整数倍

字节输出流(OutputStream)

一.基础知识:
1.OutputStream是一个抽象类,是所有字节输出流的父类.
2.根类的常用成员方法:
(1)void close() 关闭此输出流并释放与此流有关的所有系统资源。
(2)void flush() 刷新此输出流并强制写出所有缓冲的输出字节。
(3)void write(byte[] b)将 b.length 个字节从指定的 byte 数组写入此输出流。
(4)void write(byte[] b, int off, int len) 将指定 byte 数组中从偏移量 off 开始的len 个字节写入此输出流。
3.常用的已实现的子类:
(1)FileOutputStream 文件字节输出流,是用于将数据写入 File 或 FileDescriptor 的输出流。
(2)BufferedOutputStream 字节缓冲输出流

二.使用方法
1.FileOutputStream的使用方法

/*
文件字节输出流的使用注意事项
1.构造方法
  (1)FileOutputStream(File file) 创建一个向指定 File 对象表示的文件中写入数据的文件输出流
  (2)FileOutputStream(File file, boolean append) 创建一个向指定 File对象表示的文件中写入数据的文件输出流,可追加写数据
  (3)FileOutputStream(String name) 创建一个向具有指定名称的文件中写入数据的输出文件流,name为文件路径
  (4)FileOutputStream(String name, boolean append) 创建一个向具有指定 name 的文件中写入数据的输出文件流,可追加写数据
  
2.如何利用字节输出流,写入一个字符串?
  利用String类中的getBytes()方法将字符转转化为字节输入,然后调用字节输出流中的write()方法将其写入
*/

public class Main{
    public static void main(String[] args){
         FileOutputStream fos = null;
         try{
            fos = new FileOutputStream("文件的相对路径/绝对路径");
            fos.write(97);  //一次写入一个字节
            
            /*一次写多个数据 void write(byte[] b)将 b.length 个字节从指定的 byte 数组写入此输出流。
            byte[] bt = new byte[]{97,98,99,100};
            fos.write(bt);
            */
            
            /*
            一次写入多个数据 void write(byte[] b, int off, int len) 将指定 byte 数组中从偏移量 off 开始的len 个字节写入此输出流   
            byte[] bt = new byte[]{97,98,99,100};
            fos.write(bt,1,2);
            */
         } catch(FileNotFoundException e){
            e.printStackTrace();
         } catch(IOException e){
            e.printStackTrace();
         } finally{
            if(fos != null){
               try{
                 fos.close();
               }catch(IOException e){
                 e.printStackTrace();
               }
            }
         }
    }
}
/*
FileOutputStream追加写演示代码

注意事项:
1.调用构造方法:FileOutputStream(File file, boolean append) 或 FileOutputStream(String name, boolean append)
  其中若参数append的值为true则允许追加写,为false则不允许追加写
2.如何换行?
  windows:\r\n
  linux:/n
  mac:/r
*/

public class Main{
    public static void main(String[] args){
        FileOutputStream fos = null;
        try{
           fos = new FileOutputStream("问价的相对路径/绝对路径",true); //允许追加写
           fos.write("世界你好!".getBytes());
           fos.write("\r\n".getBytes());
        } catch(FileNotFoundException e){
           e.printStackTrace();
        } catch(IOException e){
           e.printStackTrace();
        } finally{
          if(fos != null){
             try{
               fos.close();
             }catch(IOException e){
               e.printStackTrace();
            }
          }
        }
    }
}

三.常见问题分析
void flush() 和 void close()的区别?
当我们调用write方法写数据时,数据并没有立即写到文件里,而是写在一个叫做"内存缓冲区"的地方.只有当我们调用了flush()刷新方法后,数据才会被写到文件里。需要注意的是,当我们调用close()方法关闭流时,会自动调用flush()刷新方法,所以我们常常不写flush()刷新方法。

字符输入流(Reader)

一.基础知识
1.Reader是一个抽象类,是所有字符输入流的父类
2.根类的常用成员方法:
(1)int read() 取单个字符。
(2)int read(char[] cbuf) 将字符读入数组
(3)abstract void close() 关闭该流并释放与之关联的所有资源
3.常用的已实现的子类:FileReader(FileReader extends InputStreamReader extends Reader),
BufferedReader

二.使用方法
1.FileReader的使用方法

/*
注意事项
1.构造方法:
  (1)FileReader(File file) 在给定从中读取数据的 File 的情况下创建一个新 FileReader
  (2)FileReader(String fileName) 在给定从中读取数据的文件名的情况下创建一个新 FileReader
*/

public class Main{
   public static void main(String[] args) throws IOException{
      FileReader fr = new FileReader("参数");
      int len = 0;
      while((len=fr.read())!=-1){
         System.out.println((char)len);
      }
   }
}

字符输出流(Writer)

一.基础知识
1.Reader是一个抽象类,是所有字符输出流的父类
2.根类的常用成员方法:
(1)abstract void close() 关闭此流,但要先刷新它
(2)abstract void flush() 刷新该流的缓冲
(3)void write(char[] cbuf) 写入字符数组
(4)abstract void write(char[] cbuf, int off, int len) 写入字符数组的某一部分
(5)void write(int c) 写入单个字符
(6)void write(String str) 写入字符串。
(7)void write(String str, int off, int len) 写入字符串的某一部分
3.常用的已实现的子类:FileWriter(FileReader extends OutputStreamWriter extends Writer)
BufferedWriter

二.使用方法
1.FileWriter的使用方法

/*
注意事项:
1.构造方法:
  (1)FileWriter(File file)根据给定的 File 对象构造一个 FileWriter 对象。
  (2)FileWriter(File file, boolean append) 根据给定的 File 对象构造一个 FileWriter 对象。可追加写,true为可追加写。
  (3)FileWriter(String fileName) 根据给定的文件名构造一个 FileWriter 对象。
  (4)FileWriter(String fileName, boolean append) 根据给定的文件名以及指示是否附加写入数据的boolean值来构造FileWriter对象.可追加。

*/

public class Main{
    public static void main(String[] args) throws IOException{
        FileWriter fw = new FileWriter("参数");
        fw.write("世界你好!");
        fw.close();
    }
}

在了解了基本的四个流之后,jdk为我们提供了更强大的流----高效读写缓冲流,它是对4个基本流的增强,同样也是4个流,字节缓冲输入流,字节缓冲输出流,字符缓冲输入流,字符缓冲输出流。
缓冲流的原理图(以输入流为例)。
在这里插入图片描述

字节缓冲输入流(BufferedInputStream)

一.基础知识
1.BufferedInputStream extends FilterInputStream extends InputStream
2.构造方法:
(1)BufferedInputStream(InputStream in) 创建一个 BufferedInputStream 并保存其参数,即输入流 in,以便将来使用。
(2)BufferedInputStream(InputStream in, int size) 创建具有指定缓冲区大小的 BufferedInputStream 并保存其参数,即输入流
in,以便将来使用
3.常用的成员方法:
(1) void close() 关闭此输入流并释放与该流关联的所有系统资源
(2) int read(byte[] b, int off, int len) 从此字节输入流中给定偏移量处开始将各字节读取到指定的 byte 数组中
(3))继承自父类的方法
4.使用步骤:
(1)创建一个字节输入流对象 FileInputStream
(2)创建一个字节缓冲流对象BufferedInputStream
(3)read()方法读数据
(4)关闭流

二.代码演示

/*
字节输入流
*/

public class Main{
    public static void main(String[] args) throws IOException{
        FileInputStream fis = new FileInputStream("参数");
        BufferedInputStream bis = new BufferedInputStream(fis);
        int len = bis.read();
        System.out.println((char)len);
    }
}

字节缓冲输出流(BufferedOutputStream)

一.基础知识
1.BufferedOutputStream extends FilterOutputStream extends OutputStream
2.构造方法:
(1)BufferedOutputStream(OutputStream out) 创建一个新的缓冲输出流,以将数据写入指定的底层输出流
(2)BufferedOutputStream(OutputStream out, int size) 创建一个新的缓冲输出流,以将具有指定缓冲区大小的数据写入指定的底层输出流
3.常用的成员方法:
(1)void flush() 刷新此缓冲的输出流
(2)void write(byte[] b, int off, int len) 将指定 byte 数组中从偏移量 off 开始的 len 个字节写入此缓冲的输出流
(3)void write(int b) 将指定的字节写入此缓冲的输出流
(4)继承自父类的方法
4.使用步骤:
(1)创建一个字节输出流对象FileOutputStream
(2)创建一个字节缓冲输出流对象BufferedOutputStream
(3)write方法写数据
(4)关闭流

二.代码演示

/*
字符缓冲输出流
*/

public class Main{
    public static void main(String[] args) throws IOException{
         FileOutputStream fos = new FileOutputStream("参数");
         BufferedOutputStream bos = new BufferedOutputStream(fos);
         bos.write("世界你好".getBytes());        
         bos.close();
         fos.close();
    }
}

字符缓冲输入流(BufferedReader)

一.基础知识
1.BufferedReader extends Reader
2.构造方法:
(1)BufferedReader(Reader in) 创建一个使用默认大小输入缓冲区的缓冲字符输入流
(2)BufferedReader(Reader in, int sz) 创建一个使用指定大小输入缓冲区的缓冲字符输入流
3.常用的成员方法
(1) String readLine() 读取一个文本行
读取一个文本行。通过下列字符之一即可认为某行已终止:换行 (’\n’)、回车 (’\r’) 或回车后直接跟着换行
包含该行内容的字符串,不包含任何行终止符,如果已到达流末尾,则返回 null
(2)继承自父类的成员方法

二.代码演示

/*
代码演示
*/

public class Main{
   public static void main(String[] args) throws IOException{
       FileReader fr = new FileReader("参数");
       BufferedReader br = new BufferedReader(fr);
       
       String str = null;
       while((str=br.readLine()) != null){
           System.out.println(str);
       }
   }
}

字符缓冲输出流(BufferedWriter)

一.基础知识
1.BufferedWriter extends Writer
2.构造方法:
(1)BufferedWriter(Writer out) 创建一个使用默认大小输出缓冲区的缓冲字符输出流
(2)BufferedWriter(Writer out, int sz) 创建一个使用给定大小输出缓冲区的新缓冲字符输出流
3.常用成员方法
(1)void newLine() 写入一个行分隔符
(2)继承自父类的成员方法

二.代码演示

/*
字符缓冲输出流
*/
public class Main{
   public static void main(String[] args) throws IOException{
       FileWriter fw = new FileWriter("参数");
       BufferedWriter bw = new BufferedWriter(fw);
       bw.write("世界你好!");
       bw.newLine();  //换行
       bw.close();
   }
}

以上即是对javaSE中IO流的简单概述

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值