io流复习

Posted ycl学java

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了io流复习相关的知识,希望对你有一定的参考价值。

前置知识:

 序列化和反序列化

  1.序列化就是在保存数据时, 保存数据的值和数据类型
  2.反序列化就是在恢复数据时, 恢复数据的值和数据类型
  3.需要让某个对象支持序列化机制,则必须让其类是可序列化的,为了让某个类是可序列化的,该
     类必须实现如下两个接口之一:
     Serializable //这是一个标记接口,没有方法
     Externalizable //该接口有方法需要实现,因此我们一般实现上面的Serializable接口

 节点流和处理流

           节点流和处理流的区别和联系
   1.节点流是底层流/低级流,直接跟数据源相接。
   2.处理流(包装流)包装节点流,既可以消除不同节点流的实现差异,也可以提供更方便的方法来完成输入输出。
   3.处理流(也叫包装流)对节点流进行包装,使用了修饰器设计模式,不会直接与数据源相连[模拟修饰器设计模式]
    

   处理流的功能主要体现在以下两个方面:
   1.性能的提高:主要以增加缓冲的方式来提高输入输出的效率。
   2.操作的便捷:处理流可能提供了- -系列便捷的方法来一次输入输出大批量的数据,使用更加灵活方便

   常见的处理流BufferedReader和BufferedWriter

   在关闭处理流时,只关闭外层流即可

一、字节流

字节流通常用来处理二进制文件,视频,音频,图片  

1、inputStream

  1.1、FileInputStream

/**
 * FileInputStream使用(文件-->程序)
 */
public class FileInputStream_ 
    public static void main(String[] args) 
      //  readFile01();
        readFile02();
    

    //单个字节的读取,效率比较低
   public static void readFile01()
        String filePath="D://a.txt";
       int readData=0;
       FileInputStream fileInputStream=null;
       try 
           //创建FileInputStream对象,用于读取 文件
           fileInputStream = new FileInputStream(filePath);
           //一个字节一个字节的读,读取的数据存储在readData里,如果返回-1,则代表读取完毕
           while ((readData = fileInputStream.read())!=-1)
               System.out.print((char) readData);//转成char输出
           
        catch (IOException e) 
           e.printStackTrace();
       finally 
           //关闭文件流释放资源
           try 
               fileInputStream.close();
            catch (IOException e) 
               e.printStackTrace();
           
       
   

    public static void readFile02()
        String filePath="D://a.txt";
        int readLen=0;
        FileInputStream fileInputStream=null;
        //添加一个Byte容量设置为10数组
        byte[] bytes = new byte[9];
        try 
            //创建FileInputStream对象,用于读取文件
            fileInputStream = new FileInputStream(filePath);
            //从该输入流读取最多10个字节的数据到字节数组。
            //如果返回-1,则代表读取完毕
            //如果读取正常返回实际读取的字节数
            while ((readLen=fileInputStream.read(bytes))!=-1)
                System.out.print(new String(bytes,0,readLen));
            
         catch (IOException e) 
            e.printStackTrace();
        finally 
            //关闭文件流释放资源
            try 
                fileInputStream.close();
             catch (IOException e) 
                e.printStackTrace();
            
        
    

   1.2、ObjectInputStream(对象反序列化)

    注意先进行 ObjectOutputStream 序列化到 D:\\a.dat 文件中 然后才进行的反序列化

public class ObjectInputStream_ 
    public static void main(String[] args) throws IOException, ClassNotFoundException 
        //指定反序列化的文件
        String filePath="D:\\\\a.dat";

        ObjectInputStream objectInputStream = new ObjectInputStream(new FileInputStream(filePath));

        //读取
        //反序列的顺序需要和保存的数据的顺序一致,否则会出现异常
        System.out.println(objectInputStream.readInt());
        System.out.println(objectInputStream.readBoolean());
        System.out.println(objectInputStream.readChar());
        System.out.println(objectInputStream.readDouble());
        System.out.println(objectInputStream.readUTF());
        Object dog = objectInputStream.readObject();
        System.out.println("运行类型:"+dog.getClass());
        System.out.println("dog信息:"+dog);//底层 Object-->Dog

        //关闭外层流即可
        objectInputStream.close();
    

可以看到输出:

2、OutputStream

  2.1、FileOutputStream

public class FileOutputStream_ 
    public static void main(String[] args) 
            writeFile();
    
    /**
     * 使用FileOutputStream将数据写入文件中
     * 如果数据不存在,则自动创建该文件
     */
    public static void writeFile()
        String filePath="D:\\\\a.txt";
        FileOutputStream fileOutputStream=null;
        try 
            //得到FileOutputStream对象
            //1、这种创建方式,写入的内容是覆盖原来的文件中的内容
            //2、在构造器中添加 true 为追加填写
            fileOutputStream = new FileOutputStream(filePath,true);

            //写入一个字节
            // fileOutputStream.write(\'a\');   fileOutputStream.write(97);

            //写入字符串   str.getBytes()字符串转为字节数组
            String str="hollow";
            //fileOutputStream.write(str.getBytes());

            //也可以指定字节数组中的起始位置,末尾位置
            fileOutputStream.write(str.getBytes(),0,str.length());
         catch (IOException e) 
            e.printStackTrace();
        finally 
            try 
                fileOutputStream.close();
             catch (IOException e) 
                e.printStackTrace();
            
        
    

   2.2、ObjectOutputStream(对象序列化)  

/**
 * ObjectOutputStream的使用,完成数据的序列化
 */
public class ObjectOutputStream_ 
    public static void main(String[] args) throws Exception 
        //序列化后,保存的格式,不是纯文本,而是按照他的格式来保存
        String filePath = "D:\\\\a.dat";
        ObjectOutputStream objectOutputStream = new ObjectOutputStream(new FileOutputStream(filePath));

        //序列化数据到 D:\\a.bat
        objectOutputStream.write(100);//int-->Integer(实现了Serializable)
        objectOutputStream.writeBoolean(true);//boolean-->Boolean(实现了Serializable)
        objectOutputStream.writeChar(\'a\');//chat-->Character(实现了Serializable)
        objectOutputStream.writeDouble(1.1);//double-->Double(实现了Serializable)
        objectOutputStream.writeUTF("阿龙学习");//String

        //保存一个对象
        objectOutputStream.writeObject(new Dog("旺财",5));
        objectOutputStream.close();
        System.out.println("序列化数据保存完毕");
    

//lombok插件
@Data
@AllArgsConstructor
@NoArgsConstructor
//要实现Serializable接口才能够进行序列化
class Dog implements Serializable 
    private String name;
    private int age;

   2.3、PrintStream(字节打印流)  

/**
 * PrintStream字节打印流
 */
public class PrintStream_ 
    public static void main(String[] args) throws IOException 
        // System.out 就是 PrintStream
        PrintStream out = System.out;
        //在默认情况下,默认打印的是标准输出(即 显示器)
        out.println("你好");
        //因为底层使用的是write,所以可以直接调用write进行打印/输出
        out.write("hello,你好!".getBytes(StandardCharsets.UTF_8));
        //关闭流。
        out.close();
        //我们可以修改打印输出流的位置/设备
        //修改成"D:\\\\a.txt"
        //这句话将会输出到D:\\a.txt
        System.setOut(new PrintStream("D:\\\\a.txt"));
        System.out.println("这句话将会输出到D:\\\\a.txt");
    

 

二、字符流

  通常用来处理文本文件,更高效。

1、Reader

   1.1、FileReader 

public class FileReader_ 
    public static void main(String[] args) 
        String filePath="d:\\\\a.txt";
        FileReader fileReader=null;
        int data= 0;
        char[] chars = new char[10];
        //1、创建FileReader对象
        try 
            fileReader = new FileReader(filePath);
            //循环读取,使用read(chars),返回的是实际读取到的字符数
            //如果返回-1则表示读到文件结尾
           while ((data = fileReader.read(chars))!=-1)
               System.out.print(new String(chars,0,data));
           
         catch (IOException e) 
            e.printStackTrace();
        finally 
            try 
                fileReader.close();
             catch (IOException e) 
                e.printStackTrace();
            
        
    

  1.2、BufferedReader         

    BufferedReader类中,有属性Reader,即可以封装一个节点流,该节点流可以是任意的,只要是Reader子类 (BufferedWriter也是一样的操作)

    

public class BufferedReader_ 
    public static void main(String[] args) throws Exception   //异常也可以try catch
        String filePath = "D:\\\\a.txt";

        //创建bufferedReader
        BufferedReader bufferedReader = new BufferedReader(new FileReader(filePath));
        //读取
        String line;//按行读取,效率高
        //1.bufferedReader.readLine() 按行读取文件
        //2.当返回为空时,表示文件读取完毕。
         while ((line = bufferedReader.readLine())!=null)
             System.out.println(line);
         
         //关闭流,只需要关闭外层的流,即bufferedReader,因为底层会自动的去关闭节点流 FileReader
         bufferedReader.close();
    

  1.3、InputStreamReader(转换流,并可以指定编码格式读取)

/**
 * InputStreamReader  转换流解决中文乱码问题
 * 将字节流 FileInputStream 转换成字符流 InputStreamReader, 指定编码 gbk/utf-8
 */
public class InputStreamReader_ 
    public static void main(String[] args) throws IOException 
        String filePath = "D:\\\\a.txt";
        //把 new FileInputStream(filePath) 转成 InputStreamReader 同时指定了编码 utf-8
        InputStreamReader inputStreamReader = new InputStreamReader(new FileInputStream(filePath), StandardCharsets.UTF_8);
        //把 InputStreamReader 传入 BufferedReader
        BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
        String readLine;
        while(( readLine = bufferedReader.readLine())!=null)
            System.out.println(readLine);
        
        bufferedReader.close();
    

2、Writer

  2.1、FileWriter

             注意:FileWriter使用后,必须要关闭(close)或刷新(flush)流, 否则写入不到指定的文件!

public class FileWriter_ 
    public static void main(String[] args) 
        String filePath="D:\\\\a.txt";
        FileWriter fileWriter=null;
        String str="哈哈哈哈哈哈哈哈哈";
        try 
            fileWriter = new FileWriter(filePath,true);//true为追加,不写则覆盖
            //fileWriter.write(str);
            fileWriter.write(str,0,2);//指定str的某一部分
         catch (IOException e) 
            e.printStackTrace();
        finally 
            try 
                fileWriter.close();
             catch (IOException e) 
                e.printStackTrace();
            
        
    

  2.2、BufferedWriter

public class BufferedWriter_ 
    public static void main(String[] args) throws IOException 
        String filePath="D:\\\\a.txt";
        //创建BufferedWriter
        BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter(filePath,true));//追加要在节点流中进行设置
        bufferedWriter.write("红红火火恍恍惚惚红红火火恍恍惚惚吼吼吼1");
        //插入一个换行
        bufferedWriter.newLine();
        bufferedWriter.write("红红火火恍恍惚惚红红火火恍恍惚惚吼吼吼2");
        //插入一个换行
        bufferedWriter.newLine();
        bufferedWriter.write("红红火火恍恍惚惚红红火火恍恍惚惚吼吼吼3");

        //关闭外层流即可
        bufferedWriter.close();
    

  2.3、OutputStreamWriter(转换流,并可以指定编码格式写入)

/**
 * 将字节流FileOutputStream包装成(转换成)字符流OutputStreamWriter,
 * 对文件进行写入(按照gbk格式,可以指定其他,比如utf-8/utf8)
 */
public class InputStreamWriter_ 
    public static void main(String[] args) throws IOException //异常直接进行的抛出,也可以try catch
        String filePath = "D:\\\\a.txt";
        OutputStreamWriter outputStreamWriter = new OutputStreamWriter(new FileOutputStream(filePath), "gbk");
        outputStreamWriter.write("gbk格式的编码");
        //关闭流
        outputStreamWriter.close();
    

  2.4、PrintWriter(字符打印流)

public class PrintWriter_ 
    public static void main(String[] args) throws IOException 
        //创建PrintWriter对象
        PrintWriter printWriter = new PrintWriter(new FileWriter("D:\\\\a.txt"));
        //将会打印到 D:\\a.txt
        printWriter.println("哈喽你好 ");
        printWriter.close(); //flush + 关闭流
    

 

三、Properties类 

  load:加载配置文件的键值对到Properties对象
  list:将数据显示到指定设备
  getProperty(key):根据键获取值
  setProperty(key,value):设置键值对到Properties对象
  store:将Properties中的键值对存储到配置文件,在idea中,保存信息到配置文件,如果
  含有中文,会存储为unicode码

  1、Properties读取数据   

public class Properties_read 
    public static void main(String[] args) throws IOException 
        //使用Properties读取ycl.properties文件
        Properties properties = new Properties();
        //加载指定的配置文件
        properties.load(new FileReader("src/main/resources/ycl.properties"));
        //键值对显示到控制台
        properties.list(System.out);
        //根据key 获取对应的值
        String id = properties.getProperty("id");
        System.out.println("id是:"+id);
    

  2、Properties写入数据

public class Properties_writer 
    public static void main(String[] args) throws IOException 
        //使用Properties类, 创建配置文件,修改配置文件内容
        Properties properties = new Properties();

        //设置内容
     //如果该文件没有对应的key,就是创建
     //如果该文件有对应的key,就是修改 properties.setProperty("charset","utf-8"); properties.setProperty("username","小刚");//中文保存的是unicode码 properties.setProperty("pwd","123567894"); //将k-v 存储至文件 properties.store(new FileOutputStream("D:\\\\a.data"),null); System.out.println("保存成功");

 

  

 

四、copy练习

  1、字节流copy练习

 

public class FileCopy 
    public static void main(String[] args) 
            copy();
    
    public static void copy()
        String resourcePath="D:\\\\壁纸\\\\1.jpg";
        String targetPath="D:\\\\壁纸\\\\3.jpg";
        FileInputStream fileInputStream=null;
        FileOutputStream fileOutputStream=null;
        int readLen=0;
        try 
            fileInputStream = new FileInputStream(resourcePath);
            fileOutputStream=new FileOutputStream(targetPath);
            //定义一个数组提高效率
            byte[] bytes = new byte[1024];
            while ((readLen=fileInputStream.read(bytes))!=-1)
                //边读边写
                fileOutputStream.write(bytes,0,readLen);//必须用这个参数,否则出现文件损失
            
            System.out.println("copy完成");
         catch (IOException e) 
            e.printStackTrace();
        finally 
            try 
                fileInputStream.close();
                fileOutputStream.close();
             catch (IOException e) 
                e.printStackTrace();
            
        
    

   2、缓冲字符流copy文本练习

    BufferedReader和BufferedWriter 是按照字符操作的,不要去操作二进制文件(声音、视频、doc、pdf、图片等等),拷贝后的文件可能会造成文件损坏

public class Buffered_copy 
    public static void main(String[] args) 
        //源文件路径
        String resourcePath = "D:\\\\a.txt";
        //目标文件的路径
        String targetPath = "D:\\\\b.txt";
        BufferedReader bufferedReader = null;
        BufferedWriter bufferedWriter = null;
        try 
            //创建bufferedReader、bufferedWriter
            bufferedReader = new BufferedReader(new FileReader(resourcePath));
            bufferedWriter = new BufferedWriter(new FileWriter(targetPath,true));//true表示追加写入
            String line;
            //readLine() 读取一行内容,但是没有换行
            while ((line = bufferedReader.readLine()) != null) 
                //每读取一行就写入
                bufferedWriter.write(line);
                //插入换行
                bufferedWriter.newLine();
            
         catch (IOException e) 
            e.printStackTrace();
        finally 
            try 
                //关闭流
                if (bufferedReader!=null)
                    bufferedReader.close();
                
                if (bufferedWriter!=null)
                    bufferedWriter.close();
                
             catch (IOException e) 
                e.printStackTrace();
            
        
    

   3、缓冲字节流copy二进制文件(copy文本文件一样可以) 

/**
 * BufferedInputStream、BufferedOutputStream的使用
 */
public class Buffered_copy02 
    public static void main(String[] args) 
        String resourcePath = "D:\\\\壁纸\\\\2.jpg";
        String targetPath = "D:\\\\壁纸\\\\4.jpg";
        BufferedInputStream bufferedInputStream = null;
        BufferedOutputStream bufferedOutputStream = null;
        try 
            //创建对象
            bufferedInputStream = new BufferedInputStream(new FileInputStream(resourcePath));
            bufferedOutputStream = new BufferedOutputStream(new FileOutputStream(targetPath));
            int readLen;
            byte[] buf = new byte[1024];
            //返回读取到的长度,当返回-1时,就表示文件读取完毕
            while ((readLen = bufferedInputStream.read(buf))!=-1)
                bufferedOutputStream.write(buf,0,readLen);
            
         catch (IOException e) 
            e.printStackTrace();
        finally 
            try 
                //关闭外层处理流即可,底层会自动关闭节点流
                if (bufferedInputStream != null) 
                    bufferedInputStream.close();
                
                if (bufferedOutputStream!=null)
                    bufferedOutputStream.close();
                
             catch (IOException e) 
                e.printStackTrace();
            
        
    

 

   

以上是关于io流复习的主要内容,如果未能解决你的问题,请参考以下文章

IO 复习字节流字符流拷贝文件

java IO复习笔记

JAVA基础复习- 字符流FileWriter

JavaSE复习File类与IO流

JAVA基础复习一 字节输入输出流整合(实现图片复制)

java基础复习