Little BigUs 2022-03-11 13:14 采纳率: 92.7%
浏览 47
已结题

javaIO流太抽象了

感觉JavaIO流好抽象啊,各位有没有什么书籍或者文章能帮助理解IO流的。感谢了Ծ‸ Ծ

  • 写回答

2条回答 默认 最新

  • 远离bug,珍爱头发 2022-03-11 14:17
    关注

    三、I/O

    java.io包中提供了一些接口和类,对文件进行基本操作,包括对文件和目录属性的操作、对文件读写的操作等。

    使用i/o操作文件

    1.File

    1. File对象可以表示文件、目录。可以对文件或目录进行基本操作。
    2. 构造方法:
    方法说明
    File(String pathname)用指定的文件路径构造文件
    File(String dir,String subpath)在指定目录下创建指定文件名的文件,dir:目录路径,subpath:文件名
    File(File parent,String subpath)根据一个文件对象和一个字文件构造文件对象,parent:目录文件,subpath:文件名
    1. 常用方法:
    方法名称说明
    boolean exists( )判断文件或目录是否存在
    boolean isFile( )判断是否是文件
    boolean isDirectory( )判断是否是目录
    String getPath( )返回此对象表示的文件的相对路径名
    String getAbsolutePath( )返回此对象表示的文件的绝对路径名
    String getName( )返回此对象表示的文件或目录的名称
    boolean delete( )删除此对象指定的文件或目录
    boolean createNewFile( )创建名称的空文件,不创建文件夹
    long length()返回文件的长度,单位为字节,如果文件不存在,则返回0L
    String getParent()返回File对象的路径名的上一级,如果没有返回null
    boolean mkdir()创建一个目录,路径名由File对象指定
    boolean mkdirs()创建包括父目录的目录
    1. 使用步骤:
      • 引入File类
      • 构造一个文件对象
      • 利用file类方法进行基本操作
    import java.io.File;
    File file=new File("test.txt");
    file.lastModified();  //获取文件最后修改日期
    

    2.Java流(读写文件)

    流的分类

    1)输入流

    1. 输入数据到内存,有InputStream和Reader作为基类
    2. InputStream常用子类为FileIuputStream,用于向文件写数据,常用方法:
    方法说明
    int read()从输入流读取下一个字节数据
    int read(byte[] b)从输入流中读取数据,并将数据存储在缓冲区数组b中,并返回时机读取的字节数
    int read(byte[] b,int off,int len)从输入流中读取最多len长度的字节,保存到字节数组b中,保存的位置从off开始,返回时机读取字符数
    void close()关闭输入流
    1. Reader类常用子类为BufferedReader,接收Reader对象作为参数,并对其添加字符缓冲器,方法:

    方法说明
    int read()从输入流读取单个字符,返回所读取的字符数据
    int read(byte[] c)从输入流读取最多c.length个字符,保存到字符数组c中,返回实际读取的字符数
    int read(byte[] c,int off,int len)从输入流中读取最多len长度的字节,保存到字节数组c中,保存的位置从off开始,返回时机读取字符数
    void close()关闭输入流

    2)输出流

    1. 从内存中输出数据,由OutputStream和Write作为基类
    2. OutputStream常用子类为FileOutputStream,用于从文件读取数据,常用方法:
    方法描述
    void write(int c)将指定的字节数据写入到输出流中
    void write(byte[] buf)将数组buf中的所有字节写入输出流中
    void write(byte b,int off,int len)将字节数组中从偏移量off开始的长度为len的字节数据输出到输出流中
    void close()关闭输入流
    1. Writer类的常用子类为BufferWriter,用于将数据缓冲到字符输出流.,方法
    方法说明
    void write(String str)将str字符串里包含的字符输出到指定的输出流中
    void write(Stringstr,int off,int len)将str字符串里从off位置开始,长度为len的多个字符输出到输出流中
    void close()关闭输出流
    void flush()刷新输出流

    3.读写文本文件

    1)使用字节流读写文本文件

    1. 使用字节流FileInputStream读文本文件:

      • FileInputStream称为文件输入流,是字节输入流inputStream抽象类的子类,作用是将文件中的数据输入到内存中.

      • 步骤:

        1. 导入相关类
        2. 构造文件输入流对象
        3. 利用文件输入流类的方法读取文本文件的数据
        4. 关闭文件输入流对象
        File file=new File("1.txt") 
        //创建流对象
        FileInputStream fis=new FileInputStream(file);
        int data;
        System.out.println("可读取的字节数:"+fis.available());
        System.out.println("文件内容为:");
        //循环读数据
        while ((data=fis.read())!=-1){
              System.out.println(data+"");
         }
        fis.close();
        
    2. 使用字节流FileOutputStream写文件:

      • FileOutputStream称为文件输出流,是字节输出流OutputStream抽象类的子类,作用是把内存中的数据输出到文件中

      • 步骤:

        1. 引入相关类
        2. 构造文件输出流对象
        3. 利用文件输出流方法写入到文本文件
        4. 关闭文件输出流
         String str="java";
        byte[] b=str.getBytes();//字节数组
        FileOutputStream fos=new FileOutputStream("1.txt",true);
        fos.write(b,0,b.length);
        System.out.println("文件已更新");
        fos.flush();
        fos.close();
        

    2)使用字符流读写文本文件

    1. 使用字符流BufferedReader和FileReader读文本文件

      • BufferedReader和FileReader两个类都是Reader抽象类的子类,可以通过字符流方式读取文件,并使用缓冲区,提高了读文本文件效率

      • 步骤

        1. 引入相关类
        2. 构造一个BufferedReader对象
        3. 利用BufferReader类的方法读取文本文件的数据
        4. 关闭相关流对象
        FileReader fr=new FileReader("1.txt");
        BufferedReader br=new BufferedReader(fr);
        String line=br.readLine();
        while(line!=null){
              System.out.println(line);
               line=br.readLine();
        }
        br.close();
        fr.close();
        
    2. 使用字符流BufferedWriter和FileWriter写文本文件

      • BufferedWriter和FileWriter都是字符输出流Writer抽象类的子类,可以通过字符流的方式并通过缓冲区把数据写入文本文件,提高写文本文件的效率

      • 步骤

        1. 引入相关类
        2. 构造一个BufferedWriter对象
        3. 利用BUfferedWriter类的方法写入文本文件
        4. 相关流对象的清空和关闭
        FileWriter fw=new FileWriter("1.txt",true);
        BufferedWriter bw=new BufferedWriter(fw);
        bw.write("java");
        bw.newLine();
        bw.write("bdqn")
        System.out.println("写入成功!");
        bw.flush();
        bw.close();
        fw.close();
        

    4.读写二进制文件

    1)使用字节流读二进制文件(DataInputStream类)

    • 引入相关类
    • 构造数据输入流对象
    • 利用数据输入流类的方法读取二进制文件中数据
    • 关闭数据输入流

    2)使用字节流写二进制文件(ReadOutputStream类)

    • 引入相关类
    • 构造数据输出流对象
    • 利用数据输出流类的方法把数据写入二进制文件
    • 关闭数据输出流
    //字节流读文件
            FileInputStream fis=new FileInputStream("C:/Users/29616/desktop/1.class");
           //字节流读二进制文件
            DataInputStream dis=new DataInputStream(fis);
            //字节流写文件
            FileOutputStream fos=new FileOutputStream("C:/Users/29616/desktop/2.class");
            //字节流写二进制文件
            DataOutputStream dos=new DataOutputStream(fos);
            int temp;
            while ((temp=dis.read())!=-1){ //读数据
                dos.write(temp);  //把读取数据写入到2.clss中
            }
            System.out.println("读写成功");
            fis.close();
            fos.close();
            dis.close();
            dos.close();
    

    5.重定向标准I/O

    1. 标准输入/输出流: System.in/System.out,主要用于从键盘接收数据和向屏幕输出数据。

    2. System.in方法:

      1. int read():从键盘接收一个字节的数据,返回值是该字节ASCII码
      2. int read(byte[] b),从键盘接收多个字节的数据,保存至b中,返回值是接收字节数据的个数
    3. System.out方法:

      1. print():向屏幕不换行输出数据,参数为任意数据类型
      2. println():向屏幕换行输出数据,参数为任意数据类型
    4. 标准I/O重新定向到其他I/O设备:

      • System.in读取文件中数据,System.out向文件中写入数据
      • 重定向标准输入/输出方法:
      方法说明
      static void setErr(printStream err)重定向标准错误输出流
      static void setIn(InputStream in)重定向标准输入流
      static void setOut(PrintStream out)重定向标准输出流
    //创建PrintStream输出流
    PrintStream ps=new PrintStream(new FileOutputStream("C:/Users/29616/desktop/1.txt"));
    //将标准输出流重定向到文件
    System.setOut(ps);
    //输出内容
    System.out.print("测试,重定向到文件");
    

    6、使用对象流读写对象信息(序列化)

    1)序列化含义和意义

    1. 含义:序列化指将对象的状态存储到特定存储介质的过程(将对象状态转换为可保持或可传输格式的过程)。序列化过程中,会把对象的共有成员、私有成员包括类名,转换为字节流,然后写入数据流,存储到存储介质(通常指文件)中
    2. 意义:将java对象序列化后,可以将其转换为字节序列,可以被保存在磁盘中,也可以借助网络进行传输,同时序列化后的对象保存的是二进制状态,实现了平台无关性(跨平台,反序列化).

    2)序列化保存对象信息

    1. 序列化机制允许将实现了序列化的java对象转换被字节序列,需要借助I/O流实现.
    2. 条件:
      • 实现了java.io.Serializable接口的类的对象才能被序列化(Serializable表示可串行的、可序列化的。String类、包装类、Date类等都实现了此接口)
      • 该类的所有属性必须是可序列化的。如果有一个属性不是可序列化的,则该属性必须注明是短暂的。
    3. 实现序列化步骤:
      1. 创建一个对象输出流(ObjectOutputStream),可以包装一个其他类型的输出流,如文件输出流(FileOutputStream)
      2. 通过对象输出流的writeObject()方法写对象,也就是输出可序列化对象
    4. 属性限制被序列化:出于安全考虑,某些属性应该限制被序列化,使用 transient 修饰

    3)反序列化获取对象信息

    1. 反序列化指从特定存储介质中读取数据并重新构建成对象的过程
    2. 步骤:
      • 创建一个对象输入流(ObjectInputStream),可以包装一个其他类型的输入流,如文件输入流(FileInputStream).
      • 通过对象输入流的readObject()方法读取对象,该方法返回一个Object类型对象,可以进行类型强制转换
    //student类
    public class Student implements Serializable {
        //属性:姓名、年龄、性别
        //省略构造方法和getter、setter方法
    }
    
    //序列化
    ObjectOutputStream oos=null;
            try {
                //创建ObjectOutputStream对象
                oos=new ObjectOutputStream(new FileOutputStream("1.txt"));
                Student stu1=new Student("小薛","男",20);
                Student stu2=new Student("小王","女",21);
                ArrayList<Student> list=new ArrayList<>();
                list.add(stu1);
                list.add(stu2);
                //对象序列化,写入输出流
                oos.writeObject(list);
    
            }catch (IOException ex){
                ex.printStackTrace();
            }finally {
                if(oos!=null){
                    try{
                        oos.close();
                    }catch (IOException e){
                        e.printStackTrace();
                    }
                }
            }
    
    //反序列化
    ObjectInputStream ois=null;
            try {
                //创建ObjectInputStream输入流
                ois=new ObjectInputStream(new FileInputStream("1.txt"));
                //反序列化,进行类型强制转换
                ArrayList<Student> list=(ArrayList<Student>)ois.readObject();
                //输出生成后的对象信息
                for (Student student : list) {
                    System.out.println("姓名:"+student.getName()+"\t性别:"+student.getSex()+"\t年龄:"+student.getAge());
                }
    
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            }
    

    注意: 1. 如果文件中使用序列化机制写入多个对象,反序列化恢复对象时,必须按照写入顺序读取.

    ​ 2. 如果一个可序列化的类,有多个父类(包括直接或间接父类),则这些父类要么是可序列化的,有么有无参构造器,否则会抛出异常

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
    1人已打赏
查看更多回答(1条)

报告相同问题?

问题事件

  • 系统已结题 3月20日
  • 已采纳回答 3月12日
  • 创建了问题 3月11日

悬赏问题

  • ¥15 微信小程序 用oss下载 aliyun-oss-sdk-6.18.0.min client报错
  • ¥15 ArcGIS批量裁剪
  • ¥15 labview程序设计
  • ¥15 为什么在配置Linux系统的时候执行脚本总是出现E: Failed to fetch http:L/cn.archive.ubuntu.com
  • ¥15 Cloudreve保存用户组存储空间大小时报错
  • ¥15 伪标签为什么不能作为弱监督语义分割的结果?
  • ¥15 编一个判断一个区间范围内的数字的个位数的立方和是否等于其本身的程序在输入第1组数据后卡住了(语言-c语言)
  • ¥15 Mac版Fiddler Everywhere4.0.1提示强制更新
  • ¥15 android 集成sentry上报时报错。
  • ¥15 抖音看过的视频,缓存在哪个文件