13.IO流

一、file类
1.文件、目录
文件:内存中存放的数据爱计算机关机后就会消失,要长久地保存数据,就要使用硬盘光盘,U盘等设备,为了便于数据的管理和索引,引入了“文件”的概念,操作系统已文件为单位管理磁盘中的数据。
文件夹(目录):成千上万个文件夹为了方便使用和索引,引入了树形目录的机制,可以吧文件放在不同的文件夹中。
2.在Java程序中操纵文件/目录
盘符上的文件目录将各种信息进行了封装,封装成了一个对象,对象属于File类的对象,就可以对这个对象获取各种信息,还可以对文件进行创建,删除。
3.File类对文件的操作
创建对象

    public static void main(String[] args) throws IOException {
        //将文件封装为一个file类的对象
        File f=new File("d:\\test.txt");
        File f2=new File("d:/test.txt");
        //File.separator属性帮助我们获取当前操作系统的路径拼接符
        File f3=new File("d:mycode"+File.separator+"test.txt")}

常用方法

//常用方法
        System.out.println("文件是否可读:"+f.canRead());
        System.out.println("文件是否可写"+f.canWrite());
        System.out.println("文件的名字"+f.getName());
        System.out.println("上级目录"+f.getParent());
        System.out.println("是否是一个目录"+f.isDirectory());
        System.out.println("是否是一个文件"+f.isFile());
        System.out.println("是否隐藏"+f.isHidden());
        System.out.println("文件的大小"+f.length());
        System.out.println("是否存在"+f.exists());
        /*if(f.exists()){//存在就删除
            f.delete();
        }else{//不存在就创建这个文件
                f.createNewFile();
        }
         */

路径相关

        System.out.println(f=f2);//比较俩个对象的地址
        System.out.println(f.equals(f2));//比较俩个对象的路径是否相同

        File f4=new File("demo.txt");
        if(!f4.exists()){
            f4.createNewFile();
        }
        //绝对路径指的是精确的完整的
        //相对位置指的是得相对于mai法存在的盘符下的
        System.out.println("绝对n方路径;"+f4.getAbsolutePath());
        System.out.println("相对路径:"+f4.getPath());
        System.out.println("to.String"+f4.toString());

4.File类对目录的操作
基本方法

File f1=new File("D:\\mycode\\IDEA-workspace");
        System.out.println(f1.exists());
        System.out.println(f1.getPath());
        System.out.println(f1.canWrite());
        System.out.println(f1.canRead());
        System.out.println(f1.isFile());
        System.out.println(f1.isDirectory());
        System.out.println(f1.isHidden());

        System.out.println(f1.toString());
        System.out.println(f1.getAbsolutePath());
        System.out.println(f1.getPath());

与目录有关的方法

//与目录相关的方法
        File f2=new File("d:\\A\\b\\c");
        //创建目录
        /*f2.mkdir();//创建单层目录
         */
        f2.mkdirs();//创建多层目录

        //删除目录
        f2.delete();//删除低一层目录,且内容是空的,有内容不会删除

        //查看
        String[] list = f1.list();//文件夹下的目录
        for(String s:list){
            System.out.println(s);
        }
        File[] files = f1.listFiles();
        for(File file:files){
            System.out.println(file.getName()+","+file.getAbsolutePath());
        }

二、IO流
File类:封装文件\目录的各种信息,对文件\目录进行操作,但不能获取文件\目录中的内容
IO:用于处理设备之间的数据传输
1.FileReader读取文件内容
创建一个file对象

        //文件---->程序
        //创建一个file对象
        File f=new File("d:\\test.txt");

创建一个FileReader流的作用

 FileReader fr=new FileReader(f);

读取

        /*int read = fr.read();
        System.out.println(read);
         */
        int n=fr.read();
        while(n!=-1){
            System.out.print((char) n);
            n=fr.read();
        }

关闭流
流,数据库,网络资源,jvm不会自动关闭,需要手动关闭

 fr.close();

快速读取

        //读取
       //引入快递员
        char[] ch=new char[5];
        int len = fr.read(ch);//一次读取五个,返回值是数组中的有效长度
        while(len!=-1){
            /*for (int i = 0; i <ch.length ; i++) {
                System.out.println(ch[i]);
            }
             */
            String str=new String(ch,0,len);
            System.out.print(str);
            len=fr.read(ch);
        }

2.FileWriter写出数据操作

        //1.有一个目标文件
        File f=new File("d://demo.text");
        //新建一个字符流
        FileWriter fw=new FileWriter(f);
        //输入
        String str="hello,java";
        for (int i = 0; i <str.length() ; i++) {
            fw.write(str.charAt(i)); 
        }
        //关闭流
        fw.close();
    }
       char[] chars = str.toCharArray();//转换为数组写出
        fw.write(chars);

FileWriter fw=new FileWriter(f):默认覆盖
FileWriter fw=new FileWriter(f,false):默认覆盖
FileWriter fw=new FileWriter(f,true):追加
3.文件复制
原文件

       //1.原文件
        File f1=new File("d:\\text.txt");

目标文件

        //2.目标文件
        File f2=new File("d:\\demo.txt");

读入

        //3.输入的对象
        FileReader fd=new FileReader(f1);

读出

       //4.输出对象
        FileWriter fw=new FileWriter(f2);

复制

        //5.开始写入
        //方式一
        /*int read = fd.read();
        while (read!=-1){
            //一次读一个
            fw.write(read);
            read=fd.read();

        }
         */
        //方式二 缓冲数组一次读五个
       /* char[] chars = new char[5];
        int len = fd.read(chars);
        while (len!=-1){
            fw.write(chars,0,len);//将缓冲数组中的有效长度读出
            len=fd.read(chars);
        }
        */
        //方式三:缓冲数组转换成字符
        char[] chars = new char[5];
        int len=fd.read(chars);//每次读入5个
        while (len!=-1){
            String s=new String(chars,0,len);//转为字符串输出
            fw.write(s);
            len=fd.read(chars);
        }

关闭流

        //关闭流,倒着关闭
        fw.close();
        fd.close();

4.利用try-catch-finally处理异常机制(实际上更多使用)

    public static void main(String[] args)  {
        //1.原文件
        File f1=new File("d:\\text.txt");
        //2.目标文件
        File f2=new File("d:\\demo.txt");
        //3.输入的对象
        FileReader fd= null;
        FileWriter fw=null;
        try {
            fd = new FileReader(f1);

            char[] chars = new char[5];
            int len=fd.read(chars);//每次读入5个
            while (len!=-1){
                String s=new String(chars,0,len);//转为字符串输出
                fw.write(s);
                len=fd.read(chars);
            }

        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if(fw!=null)//防止空指针异常
                fw.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                if(fd!=null)//防止空指针异常
                fd.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

5.FileInputStream读取文件内容
【1】利用字节流读文本文件
a. 文件是utf-8进行存储的,英文字符占一个字节,中文字符占三个字节
b.文本文件应使用字符流读取,不应该使用字节流读取
c.read()读取一个字节,返回值应为int类型,而不是byte类型
dread方法底层做了处理,让返回值的类型都为正数,为了避免返回值为-1时,分清楚是到文件结尾还是读入字节

   public static void main(String[] args) throws IOException {
        //功能利用字节流将文件中的内容读到文件中
        //1.一个原文件
        File f1=new File("d:\\text.txt");
        FileInputStream fis=new FileInputStream(f1);
        /*
        文件是utf-8进行存储的,英文字符占一个字节,中文字符占三个字节
        文本文件应使用字符流读取,不应该使用字节流读取
        read()读取一个字节,返回值应为int类型,而不是byte类型
        read方法底层做了处理,让返回值的类型都为正数,为了避免返回值为-1时,分清楚是到文件结尾还是读入字节
         */
        int i = fis.read();
        while (i!=-1){
            System.out.println(i);
            i=fis.read();
        }
        //关闭流
        fis.close();
    }

【2】利用字节流复制
一个一个复制

   public static void main(String[] args) throws IOException {
        //完成图片的复制
        //1.原文件
        File f1=new File("d:\\WS.jpg");
        //2.目标文件
        File f2=new File("d:\\sw.jpg");
        //3.输入管道
        FileInputStream fis=new FileInputStream(f1);
        //4、输出管道
        FileOutputStream fos=new FileOutputStream(f2);
        //5.复制(一个一个复制)
        int i = fis.read();
        while (i!=-1){
            fos.write(i);
            i=fis.read();
        }
        //6.关闭流倒着关闭流
        fos.close();
        fis.close();
    }

添加字节缓冲数组

    public static void main(String[] args) throws IOException {
        //1.原文件
        File f1=new File("d:\\WS.jpg");
        //2、目标文件
        File f2=new File("d:\\wer.jpg");
        //3.输入管道
        FileInputStream fis=new FileInputStream(f1);
        //4.输出管道
        FileOutputStream fos=new FileOutputStream(f2);
        //5、复制
        byte[] b = new byte[1024 * 8];
        int len = fis.read(b);
        while (len!=-1){
           fos.write(b,0,len);
           len=fis.read();
        }
        //6、关闭流    
        fos.close();
        fis.close();
    }

【3】缓冲流
缓冲字节流(处理流)BufferedInputStream/ BufferedOutputStream

   public static void main(String[] args) throws IOException {
        //1.原文件
        File f1=new File("d:\\WS.jpg");
        //2、目标文件
        File f2=new File("d:\\wer.jpg");
        //3.输入管道
        FileInputStream fis=new FileInputStream(f1);
        //4.输出管道
        FileOutputStream fos=new FileOutputStream(f2);
        //5.功能加强,在FileInputStream外面套一个管子
        BufferedInputStream bis=new BufferedInputStream(fis);
        //6.功能加强,在FileoutputStream外面套一个管子
        BufferedOutputStream bos=new BufferedOutputStream(fos);
        //7.复制
        //5、复制
        byte[] b = new byte[1024 * 8];
        int len = bis.read(b);
        while (len!=-1){
            bos.write(b,0,len);
             /* bos.flash(),底层已经帮助我们刷新了缓冲区,不需要手动清除*/
            len=bis.read();
        }
        //6、关闭流
        //如果处理流包裹着节点流的话,只需要关闭高级流,里面的字节流随之就会被关闭
        bos.close();
        bis.close();
        //fos.close();
        //fis.close();
    }

缓冲字符流(处理流) BufferedReader/BufferedWriter

   public static void main(String[] args) throws IOException {
        //1.原文件
        File f1=new File("d:\\text.txt");
        //2、目标文件
        File f2=new File("d:\\demo1.txt");
        //3.输入管
        FileReader fr=new FileReader(f1);
        //4.输出管
        FileWriter fw=new FileWriter(f2);
        //5.输入字符流外面的管
        BufferedReader br=new BufferedReader(fr);
        //6、输出字符流外面的管
        BufferedWriter bw=new BufferedWriter(fw);
        //7.复制
        //方式一:一个一个删
        int n = br.read();
        while (n!=-1){
            bw.write(n);
            n=br.read();
        }
        //方式二:缓冲数组
        char[] ch=new char[20];
        int len = br.read(ch);
        while (len!=0){
            bw.write(ch,0,len);
            len=br.read();
        }

        //方式三:一行一行读
        String str = br.readLine();
        while (str!=null){
            bw.write(str);
            bw.newLine();//每次写出一行后换行
            str=br.readLine();
        }
        //8、关闭流
        bw.close();
        br.close();
    }

【4】转换流
作用:将字节流和字符流进行转换
属于字符流,由后缀得出
inputStreamReader:字节输入流---->字符输入流
outputStreamWriter:字符输出流---->字节输出流
将输入的字节流转换为输入芙蓉字符流,然后完成文件复制到程序

   public static void main(String[] args) throws IOException {
        //1.原文件
        File f1=new File("d:\\text.txt");
        //2.输入字节流接触文件
        FileInputStream fis=new FileInputStream(f1);
        //3.讲字节流转换为字符流
        //讲字节转换为字符的时候需要按照原文件的编码格式进行转化,否则会出现乱码
        InputStreamReader isr=new InputStreamReader(fis,"utf-8");
        //4.复制
        char[] ch=new char[20];
        int len = isr.read(ch);
        while (len!=-1){
            //将缓冲字符转换为字符串在控制台上打印出来
            System.out.print(new String(ch,0,len));
            len=isr.read(ch);
        }
        //5.关闭流
        isr.close();
    }

文本文件的复制

    public static void main(String[] args) throws IOException {
        //1.原文件
        File f1=new File("d:\\text.txt");
        //2.目标文件
        File f2=new File("d:\\demo3.txt");
        //3.输入方向
        FileInputStream fis=new FileInputStream(f1);
        InputStreamReader isr=new InputStreamReader(fis,"utf-8");
        //4.输出方向
        FileOutputStream fos=new FileOutputStream(f2);
        OutputStreamWriter osw=new OutputStreamWriter(fos,"gbk");
        //5.复制
        char[] ch=new char[20];
        int len = isr.read(ch);
        while (len!=-1){
            osw.write(ch,0,len);
            len=isr.read();
        }
        //6.关闭流
        osw.close();
        isr.close();
    }

三、Systen类对IO流的支持
1.System的属性
System.in(字节流):标准输入流,默认情况下从键盘输入

 public static void main(String[] args) throws IOException {
        //得到的是标准的输入流
        /*InputStream in = System.in;
        int n = in.read();//等待键盘的录入,这个方法是一个阻塞方法
        System.out.println(n);
        Scanner sc=new Scanner(System.in);
        String s = sc.next();
        System.out.println(s);
        //Scanner相当于一个扫描器,不一定可以扫描System.in扫进来的东西

         */
        Scanner sd=new Scanner(new FileInputStream(new File("d:\\text.txt")));
        while(sd.hasNext()){
            System.out.println(sd.next());
        }
    }

System.out(字节流):标准输出流,默认情况下输出到控制台

public static void main(String[] args) {
        //写到控制台
        PrintStream out = System.out;
        //调用方法
        out.print("这既是爱");
        out.print("张杰");
        
        out.println("你好");//直接在控制台写出,并且换行操作
        out.println("你好2");
    }
}

2.键盘内容输出到文件中

   public static void main(String[] args) throws IOException {
        //1.输入方向
        //键盘录入
        InputStream in = System.in;//字节流
        //转换为字符流
        InputStreamReader isr=new InputStreamReader(in);
        //在字符流外面加一个缓冲流
        BufferedReader br=new BufferedReader(isr);

        //2.输出方向
        //目标文件
        File f=new File("d:\\demo5.txt");
        //字符输出流
        FileWriter fw=new FileWriter(f);
        //缓冲流
        BufferedWriter bw=new BufferedWriter(fw);

        //3.开始动作
        String s = br.readLine();
        while (!s.equals("exit" )){
            bw.write(s);
            bw.newLine();//换行
            s = br.readLine();
        }

        //4.关闭流
        bw.close();
        br.close();
    }

四、数据流
数据流:用来操作基本数据类型和字符串的
DataInputStream:将文件中存储的基本数据类型和字符串写入内存的变量中

public static void main(String[] args) throws IOException {
       /* //1.文件
        File f=new File("d:\\text.txt");
        //2.字节输出流
        FileOutputStream fos=new FileOutputStream(f);
        //3.数据流
        DataOutputStream dos=new DataOutputStream(fos);
        */
        DataOutputStream dos=new DataOutputStream(new FileOutputStream(new File("d:\\text.txt")));
        //写出
        dos.write(11);
        dos.writeBoolean(false);
        dos.writeChar('s');
        dos.writeUTF("hello");

        //关闭流
        dos.close();

DateOutputStream:将内存的基本数据类型和字符串的变量写出到文件中

public static void main(String[] args) throws IOException {
        //
        File f=new File("d:\\text.txt");
        //字节输入流
        FileInputStream fis=new FileInputStream(f);
        DataInputStream dis=new DataInputStream(fis);
        //将文件中的内容读取到程序中
        System.out.println(dis.read());
        System.out.println(dis.readBoolean());
        System.out.println(dis.readChar());
        System.out.println(dis.readUTF());

        dis.close();
    }

五、对象流(ObjectInputStream,ObjectInputStream)
用于存储和读取基本数据类型的数据或对象的处理流,可以将Java中的对象写到数据源中,也可以把对象从数据源中还原
将字符串对象写到文件中去<序列化>

 public static void main(String[] args) throws IOException {
         //讲一个对象写入到文件中
        ObjectOutputStream oos=new ObjectOutputStream(new FileOutputStream(new File("d:\\text01.txt"))); 
        oos.writeObject("hello");
        oos.close();   
    }

将字符串从文件中读到控制台<反序列化>

 public static void main(String[] args) throws IOException, ClassNotFoundException {
        ObjectInputStream ois=new ObjectInputStream(new FileInputStream(new File("d:\\text01.txt")));
        String s = (String) ois.readObject();
        System.out.println(s);
        ois.close();
    }

序列化:爸爸内存中的Java对象转换成平台无关的二进制数据,从而允许把这种二进制数据持久的保存在磁盘上
反序列化:当其他的程序获取了这种二进制数据,就可以恢复成原来的Java对象
五、操作自定义的类
1.

public class Person {
    private int age;
    private String name;
    private double weight;
    //构造器
    public Person(int i, String lili, double v) {
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public double getWeight() {
        return weight;
    }

    public void setWeight(double weight) {
        this.weight = weight;
    }
}
public class Test01 {
    public static void main(String[] args) throws IOException {
        Person p=new Person(19,"lili",123.2);
        ObjectOutputStream oos=new ObjectOutputStream(new FileOutputStream(new File("d:\\text02.txt")));
        oos.writeObject(p);

        oos.close();
    }
}

2.按照已经学习的操作,实现将类写出到文件中会出现错误,因为没有进行序列化
必须要实现一个接口

public interface Serializable{
}

标识接口:接口内部什么都没有
作用:起标识作用,只有实现这个接口的类的对象才能序列化
3.将要写出的类实现标识接口
实现接口:public class Person implements Serializable {
反序列化:

public static void main(String[] args) throws IOException, ClassNotFoundException {
        ObjectInputStream ois=new ObjectInputStream(new FileInputStream(new File("d:\\text02.txt")));
        Person p=(Person)ois.readObject();
        System.out.println(p);
        ois.close();
    }

4.反序列化会出现异常的原因:
序列化:Person对象---->文件中
当时的Person类没有toString方法
在Person中加入toString方法,然后再进行反序列化,读进来的对象的类不带toString,所以出现了类不匹配的问题
解决:加入一个序列号

  private static final long serialVersionUID=123L;

5.serialVersionUID
凡是实现serialVersionUID的类都有一个表示序列化版本标识符的静态常量
private static final long serialVersionUID=123L;
serialVersionUID用来表明类的不同版本间的兼容性,其目的是以序列化对象进行版本控制,有关各版本反序列化是是否兼容
如果类没有显示定义这个静态变量,它的值是Java运行时环境更具内的内部细节自动生成的,若类的实例变量做了修改,serialVersionUID可能发生变化
6.序列化
(1)被序列化的类的内部的所有属性必须是可序列化的(基本数据类型都是可序列化的)
(2)static,transient修饰的属性,不可以被序列化

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值