欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Java IO流(小结)

程序员文章站 2022-04-03 19:35:53
...


IO流

IO流概述

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

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


IO流的分类

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

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

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

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


java.io.FileOutputStream

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

Java IO流(小结)

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

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

Java IO流(小结)

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

Java IO流(小结)

OutputStreanWriter

Java IO流(小结)

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
        }
    }
}