IO流

IO流

以流的方向:

  • 输入流(input、read读)
  • 输出流(output、write写)

以读取数据类型:

  • 字节流
  • 字符流

字节流

以Stream结尾的都是字节流。

以字节为单位,一次读取一个字节,可以读图片、文档、视频、音频等。

字符流

以Writer或Reader结尾的都是字符流。

以字符为单位,一次读一个字符,只能读取纯文本文件。

文件专属流

FileInputStream

  • read()(获取当前读到字节)
  • read(byte)(把读到的字节放到数组中,一次放byte.length)
  • skip(x)(跳过x个字节读)
  • available()(获取还未读的字节个数)
FileInputStream fis = null;
        try {
            fis = new FileInputStream("C:\\Users\\Administrator\\Desktop\\小结.txt");
            byte[] bytes = new byte[10];
            //记录读取的一次读取信息到的个数
            int count=0;
            //文件读取一次读10个,并把数据放入bytes数组中,如果没有读到信息就返回-1
            while((count=fis.read(bytes))!=-1){
                //将bytes数组转换成字符串,从下标bytrs[0]开始,一次转换count个
                System.out.print(new String(bytes,0,count));
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (fis != null) {//如果流不是空,就关闭流
                try {
                    fis.close();//及时关闭流
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

FileOutputStream

  • write()(写入数据)
  • flush()(刷新流通道)
 FileOutputStream fos=null;
        try {
            //指定文件位置,true代表可以继续写入,而不是覆盖原文件的内容
            fos=new FileOutputStream("C:\\Users\\Administrator\\Desktop\\qq.txt",true);
            String str="ajbdfuyshyfyrdkjgh可hi应嘎是gd";
            //将String转换成byte数组
            byte[] bytes = str.getBytes();
            //将数组写入文件
            fos.write(bytes);

            fos.flush();//刷新
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (fos != null) {
                try {
                    fos.close();//关闭流
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

FileReader

以字符的形式读。

FileWriter

以字符的形式写。

    FileReader fr=null;
    FileWriter fw=null;
    try {
        fr=new FileReader("qq.txt");
        fw=new FileWriter("qq.txt",true);//续写到文件中
        char[] chars=new char[10];//一次读10个字符
        int count=0;
        //一边读,一边写。可以实现拷贝文件。
        while((count=fr.read(chars))!=-1){
            fw.write(chars,0,count);//写入
        }
        fw.flush();//刷新
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        if (fr != null) {
            try {
                fr.close();//关闭流
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        if (fw != null) {
            try {
                fw.close();//关闭流
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

缓冲流

BufferedReader

  • readLine()(读一行)

缓冲流可以一次读一行,就不需要再指定数组了。

BufferedWriter

BufferedInputStream

BufferedOutputStream

BufferedReader br = null;
BufferedWriter bw=null;
FileOutputStream fw=null;
try {
    FileReader fr = new FileReader("Hello/src/base/IO流/CopyDemo1.java");
    br = new BufferedReader(fr);//放的是字符流
    fw= new FileOutputStream("qq");//以字节流的形式xier
    String data=null;
    while((data=br.readLine())!=null){
        fw.write(data.getBytes());//读和写不需要一样,用字符流读的文件,也可以用字节流写。
    }
    fw.flush();//刷新
} catch (FileNotFoundException e) {
    e.printStackTrace();
} catch (IOException e) {
    e.printStackTrace();
} finally {
    if (br != null) {
        try {
            br.close();//关闭流只需要关闭最外边的。
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

转换流

InputStreamReader

可以将字节输入流转换为字符输入流

FileInputStream fis=new FileInputStream("qq.txt");
InputStreamReader ir=new InputStreamReader(fis);//将字节流转换成字符流

OutputStreamWriter

可以将字节输出流转换为字符输出流

new OutputStreamWriter(new FileOutputStream("qq")

数据专属流

DataInputStream

可以读取数据的类型和值。

DataInputStream dis=null;
try {
    dis=new DataInputStream(new FileInputStream("qq"));
    byte b = dis.readByte();//可以读到数据的类型。
    short s = dis.readShort();
    int i = dis.readInt();
    long l = dis.readLong();
    float f = dis.readFloat();
    double d = dis.readDouble();
    boolean flag = dis.readBoolean();
    char c = dis.readChar();
    System.out.println(b);//100
    System.out.println(s);//200
    System.out.println(i);//300
    System.out.println(l);//400
    System.out.println(f);//500.0
    System.out.println(d);//600.0
    System.out.println(flag);//false
    System.out.println(c);//c

} catch (FileNotFoundException e) {
    e.printStackTrace();
} catch (IOException e) {
    e.printStackTrace();
} finally {
    if (dis != null) {
        try {
            dis.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

DataOutputStream

可以写入数据的类型。

DataOutputStream dos=null;
try {
    dos=new DataOutputStream(new FileOutputStream("qq"));
    byte b=100;
    short s=200;
    int i=300;
    long l=400;
    float f=500.0f;
    double d=600.0;
    boolean flag=false;
    char c='c';
    dos.writeByte(b);//根据数据类型调用不同方法保存数据。
    dos.writeShort(s);
    dos.writeInt(i);
    dos.writeLong(l);
    dos.writeFloat(f);
    dos.writeDouble(d);
    dos.writeBoolean(flag);
    dos.writeChar(c);
    dos.flush();
} catch (FileNotFoundException e) {
    e.printStackTrace();
} catch (IOException e) {
    e.printStackTrace();
} finally {
    if (dos != null) {
        try {
            dos.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

标准输出流

PrintWriter

PrintStream

//标准输出流不需要手动关闭
PrintStream ps=null;
System.out.println("张飞");//现在是输出到控制台中
try {
    ps=new PrintStream("log");
    System.setOut(ps);//改变输出方向
    Date date=new Date();//获取当前时间。
    SimpleDateFormat simpleDateFormat=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss SSS");//设置时间格式
    String time = simpleDateFormat.format(date);
    System.out.println(time+"用户登录失败");
    System.out.println(time+"用户重新登录");
    System.out.println(time+"用户登录还是失败");
    System.out.println(time+"用户走了");
    //以上信息不会显示到控制台中,而是会输入到log文件中。
} catch (FileNotFoundException e) {
    e.printStackTrace();
}

对象专属流

ObjectOutputStream

将对象写入硬盘中。这个过程也叫序列化。

User user1=new User(111,"张飞");
ObjectOutputStream oos=null;
try {
    oos=new ObjectOutputStream(new FileOutputStream("Three Country"));
    //序列化
    oos.writeObject(user1);//将对象写入Three Country文件中
    oos.flush();
} catch (IOException e) {
    e.printStackTrace();
}finally {
    if (oos != null) {
        try {
            oos.close();//关闭流
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

ObjectInputStream

将对象从硬盘中读出来。这个过程也叫反序列化。

ObjectInputStream ois=null;
try {
    ois=new ObjectInputStream(new FileInputStream("Three Country"));
    System.out.println(ois.readObject());//读User类型
    //User{id=0, name='张飞', gender=null}
} catch (IOException e) {
    e.printStackTrace();
} catch (ClassNotFoundException e) {
    e.printStackTrace();
} finally {
    if (ois != null) {
        try {
            ois.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

也可以存多个对象,以List的形式。

//创建User对象
User user1=new User(111,"张飞");
User user2=new User(222,"关羽");
User user3=new User(111,"赵云");
ObjectOutputStream oos2=null;
try {
    oos2=new ObjectOutputStream(new FileOutputStream("Three Country2"));
    //序列化
    List<User> list=new ArrayList<>();
    list.add(user1);
    list.add(user2);
    list.add(user3);
    list.add(user3);
    oos2.writeObject(list);	
    oos2.flush();
} catch (IOException e) {
    e.printStackTrace();
}finally {
    if (oos2 != null) {
        try {
            oos2.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
ObjectInputStream ois2=null;
try {
    ois2=new ObjectInputStream(new FileInputStream("Three Country2"));
    //反序列化
    System.out.println(ois2.readObject());//读List类型
    //[User{id=0, name='张飞', gender=null}, User{id=0, name='关羽', gender=null}, User{id=0, name='赵云', gender=null}, User{id=0, name='赵云', gender=null}]
} catch (IOException e) {
    e.printStackTrace();
} catch (ClassNotFoundException e) {
    e.printStackTrace();
} finally {
    if (ois2 != null) {
        try {
            ois2.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

注意

  1. 序列化的对象类需要实现Serializable接口

  2. 当序列化一个对象类后,JVM会默认生成一个序列化版本号。JVM识别一个类先看类名,类名一致再看序列化版本号。此时如果修改对象类的内容,JVM会重写分配一个序列化版本号。当两个序列化版本号不一致时,就会报错。

  3. 对象类序列化后不能修改,如果修改再执行反序列化会报错。会出现问题。

    //InvalidClassException: base.bean.User;
        // local class incompatible:
        // stream classdesc serialVersionUID = -2261533198529479100,
        // local class serialVersionUID = 4860489787298953017
    

    解决方案:

     //在对象类中手动增加一个序列化版本号
    private static final long serialVersionUID = 1557683056911141067L;
    
  4.  private transient int id;//transient游离的,不参加序列化,反序列化时会输出默认值。
    
    
    
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值