Java IO流(小结)


IO流

IO流概述

​ 可以将这种数据传输的操作,看做一种数据的流动 ,按照流动的方向分为输入Input 和输出Output

​ Java中的IO操作主要指的是 java.io 包下的一些常用类的使用。通过这些常用类对数据进行读取(输入Input)和写出(输出Output)


IO流的分类

​ 按照流的方向来分,可以分为:输入流和输出流

​ 按照流动的数据类型来分,可以分为:字节流和字符流

 字节流
     - 输入流:InputStream (读取)
     - 输出流:OutputStream (写入)
 字符流
     - 输入流:Reader (读取)
     - 输出流:Writer (写入)

一切皆字节:
计算机中的任何数据(文本,图片,视频,音乐等等)都是以二进制的形式存储的。
在数据传输时也都是以二进制的形式存储的。
后续学习的任何流,在传输时底层都是二进制。


java.io.FileOutputStream

文件输出流是用于将数据写入FileFileDescriptor的输出流。

在这里插入图片描述

public static void main(String[] args) throws IOException {
    /**
     * 参数
     * name - 与系统相关的文件名
     * append - 如果是 true ,那么字节将被写入文件的末尾而不是开头(追加模式) 
     *          不写 则在流重新创建时会清除源文件内容并重新写入
     */
    FileOutputStream fos = new FileOutputStream("c://a.txt",true);
    // 方式一:写入ABCD
    byte[] bytes1 = {65,66,67,68};
    fos.write(bytes1);
    
    // 方式二:getBytes()方法:将字符串 变成 字节数组
    byte[] bytes2 = "ABCDE".getBytes();
    fos.write(bytes2);
    
	// 记得关闭流
    fos.close();
    System.out.println("已经写出");
}

java.io.FileInputStream

文件字节输入流,意思指对文件数据以字节的形式进行读取操作,如读取图片、视频等。

在这里插入图片描述

public static void main(String[] args) throws IOException {
    FileInputStream fis = new FileInputStream("c://a.txt");
    // 一次读取一个字节
    while(true){
        byte b = (byte) fis.read();
        // -1即为流读取完毕
        if(b == -1){
        	break;
        }
    	System.out.println((char)b);
    }
    
    // 一次读取一组字节(可以以 1M(1024*1024 byte)为单位读取)
    // 创建一个大小为10的数组,将读取到的内容放进数组里(每次读10个字节)
    byte[] bytes = new byte[10];  
    int len = fis.read(bytes);
    // 当我们不知道文件内容大小的情况下,用 len 表示每次读取的字节数
    System.out.println(new String(bytes,0,len));
    len = fis.read(bytes);
    System.out.println(new String(bytes,0,len));
    len = fis.read(bytes);
    System.out.println(len);
    
    fis.close();
}

文件加密和解密工具

public static void main(String[] args) throws Exception {
    System.out.println("请输入文件存储的全路径:");
    Scanner input = new Scanner(System.in);
    String fileName = input.nextLine();
    // 原文件: a.png
    File oldFile = new File(fileName);
    
    // 加密存储的新文件 a-encryption.png (encryption加密)
    File newFile = new File(oldFile.getParentFile(), oldFile.getName() + "-encryption");
    FileInputStream fis = new FileInputStream(oldFile);
    FileOutputStream fos = new FileOutputStream(newFile);
        while(true) {
        int b = fis.read();
        // 读取完毕,跳出循环
        if(b == -1) {
        	break;
        }
    	// 加密方式:任何数据^相同的数字 两次结果就是其本身
   		 fos.write(b^10);
    }
    System.out.println("加密或解密完成");
}

字符输出流(FileWriter)

public static void main(String[] args) throws IOException {
    FileWriter fw = new FileWriter("c://b.txt");
    fw.append("锄禾日当午").append(",").append("汗滴禾下土");
    // flush刷新管道,每次输出一段内容都要刷新一次
    fw.flush();
    // close在调用时,会刷新一次内容
    fw.close();
}

字符输入流(FileReader)

public static void main(String[] args) throws IOException {
    FileReader fr = new FileReader("b.txt");
    char[] chars = new char[100]; 
    int len = fr.read(chars);
    String text = new String(chars,0,len);
    System.out.println(text);
    System.out.println(text.length());
    fr.close();
}

字节流转换字符流

InputStreamReader

在这里插入图片描述

OutputStreanWriter

在这里插入图片描述

public static void main(String[] args) throws IOException {	
	FileInputStream fis = new FileInputStream("c://a. txt");
    // 将字节输入流,转换为字符输入流
    InputStreamReader isr = new InputStreamReader(fis, "gbk");
    while(true){
    	int c = isr.read();
    	if(c == -1){
    		break;
   	 	}
    	System.out.println((char)c);
    }
    
   	FileOutputStream fos = new FileOutputStream("c://a. txt"); 
    // 将字节输出流,转换为字符输出流
    OutputStreamWriter osw = new OutputStreamWriter(fos);
    osw.write("床前明月光");
    osw.flush();
   	osw.close();
}

Print(打印流)与BufferedReader(缓存读取流)

public static void main(String[] args) throws IOException {
    // PrintStream(打印流) — 自动刷新
    PrintStream ps = new PrintStream("c://c.txt"); 
    ps.println("锄禾日当午,汗滴禾下土1");
    ps.println("锄禾日当午,汗滴禾下土2");
    ps.println("锄禾日当午,汗滴禾下土3");
    
    // PrintWriter(打印流) - 需要刷新管道 (更好用)
    PrintWriter pw = new PrintWriter("c://c.txt");
    pw.println("锄禾日当午,汗滴禾下土1");
    pw.println("锄禾日当午,汗滴禾下土2");
    pw.println("锄禾日当午,汗滴禾下土3");
    pw.flush();

    //缓存读取流,将字符输入流转换为带有缓存可以一次读取一行的缓存字符读取流
    FileReader fr = new FileReader("c://c.txt");
    BufferedReader br = new BufferedReader(fr);
    String text = br.readLine();
    System.out.println(text); 
}

收集异常日志

public static void main(String[] args) throws FileNotFoundException {
    try{
    	String s = null;
    	s.toString();
    }catch(Exception e){ 
    	PrintWriter pw = new PrintWriter("c://bug.txt");
    	SimpleDateFormat sdf = new SimpleDateFormat("yyy-MM-dd HH:mm");
    	pw.println(sdf.format(new Date()));
    	e.printStackTrace(pw);
        // 关闭流
    	pw.close();
    }
}

序列化与反序列化

实现序列化和反序列化时,类要实现 Serializable 标记接口(无抽象方法)

public class Demo3 {
    /**
     * 序列化和反序列化的定义
     *      Java序列化就是指把Java对象转换为字节序列的过程
     *      Java反序列化就是指把字节序列恢复为Java对象的过程
     *
     * 序列化的作用
     *      在传递和保存对象时,保证对象的完整性和可传递性。对象转换为有序字节流,以便在网络上传输或者保存在本地文件中。
     * 反序列化的作用
     *      根据字节流中保存的对象状态及描述信息,通过反序列化重建对象。
     *
     * 序列化优点:
     * 		1、将对象转为字节流存储到硬盘上,当下一次JVM启动,把序列化的对象,通过反序列化为原来的对象,并且序列化的二进制序列能够减少存储空间(永久性保存对象)。
     *    	2、序列化成字节流形式的对象可以进行网络传输(二进制形式),方便了网络传输。
     *      3、通过序列化可以在进程间传递对象。
     */
    public static void main(String[] args) throws IOException, ClassNotFoundException {
        // 序列化
        Person p = new Person("张三",18);
        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("person.txt"));
        oos.writeObject(p);
        oos.close();

        // 反序列化
        ObjectInputStream ois = new ObjectInputStream(new FileInputStream("person.txt"));
        Object o = ois.readObject();
        System.out.println(o);
        // 也可以类型强转
        //Person o = (Person) ois.readObject();
        //System.out.println(o.getName());
    }

    static class Person implements Serializable {
        private String name;
        private int age;

        public Person() {}

        public Person(String name, int age) {
            this.name = name;
            this.age = age;
        }
        public String getName() {
            return name;
        }
        public void setName(String name) {
            this.name = name;
        }
        public int getAge() {
            return age;
        }
        public void setAge(int age) {
            this.age = age;
        }

        @Override
        public String toString() {
            return "Person{" +
                    "name='" + name + '\'' +
                    ", age=" + age +
                    '}';java
        }
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值