其他分享
首页 > 其他分享> > 学习博客:IO流之处理流

学习博客:IO流之处理流

作者:互联网

处理流/包装流”连接“在已存在的流(节点流和处理流)之上,拥有更强大的读写功能、更灵活(BufferedReader、BufferedWriter)

消除不同节点流之间的实现差异,提供更方便的方法完成输入输出
使用修饰器设计模式,不会直接与数据源相接

提高性能:以增加缓冲的方式提高输入输出的效率
方便操作:一次大批量输入输出数据

1.BufferReader

import java.io.BufferedReader;
import java.io.FileReader;

public class BufferReader_ {
    public static void main(String[] args) throws Exception{
        //路径
        String filePath = "D:\\test1.txt";

        //创建对象
        BufferedReader bufferedReader = new BufferedReader(new FileReader(filePath));


        //读取
        String line;
        while((line = bufferedReader.readLine()) != null){  //按行读取,返回null则读取完毕
            System.out.println(line);
        }

        //关闭外层即可,底层会自动关闭节点流
        bufferedReader.close();

    }
}

2.BufferWriter

import java.io.BufferedWriter;
import java.io.FileWriter;

public class BufferWriter_ {
    public static void main(String[] args) throws Exception{
        //路径
        String filePath = "D:\\qqq.txt";

        //创建BufferedWriter
        BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter(filePath));

        bufferedWriter.write("hi,java");
        bufferedWriter.newLine();
        bufferedWriter.write("hi,php");
        bufferedWriter.newLine();
        bufferedWriter.write("hi,python");
        bufferedWriter.newLine();
        
        bufferedWriter.close();
    }
}

应用

import java.io.*;

//BufferedReader和BufferedWriter是安装字符操作  避免操作二进制文件,会造成文件损坏
public class BufferedCopy_ {
    public static void main(String[] args){

        String srcFilePath = "D:\\qqq.txt";
        String destFilePath = "D:\\1\\qqq.txt";
        BufferedReader br = null;
        BufferedWriter bw = null;
        String line;

        try {
            br = new BufferedReader(new FileReader(srcFilePath));
            bw = new BufferedWriter(new FileWriter(destFilePath));

            while((line = br.readLine()) != null){
                bw.write(line); //读一行写一行
                bw.newLine();   //插入换行
            }

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

2.BufferedInputStream\BufferedOutputStream

缓冲字节输入流 BufferedInputStream,在创建BufferedInputStream时,会创建一个内部缓冲区数组

缓冲字节输出流 BufferedOutputStream,实现缓冲的输出流,可以将多个字节写入底层输出流中,不必对每次字节写入调用底层系统

字节流可以操作二进制文件,字符流不能操作二进制文件

应用

import java.io.*;

//二进制文件拷贝
public class BufferedCopy__ {
    public static void main(String[] args) {
        //路径
        String srcFilePath = "D:\\IMG_7489.JPG";
        String destFilePath = "D:\\1\\h.JPG";

        //创建BufferedInputStream对象和BufferedOutputStream对象
        BufferedInputStream bis = null;
        BufferedOutputStream bos = null;

        try {
            bis = new BufferedInputStream(new FileInputStream(srcFilePath));
            bos = new BufferedOutputStream(new FileOutputStream(destFilePath));

            //循环读取文件,写入destFilePath
            byte[] buff = new byte[1024];
            int readLen = 0;
            while((readLen = bis.read(buff)) != -1){
                bos.write(buff, 0, readLen);
            }

        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if(bis != null){
                    bis.close();
                }
                if(bos != null){
                    bos.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        System.out.println("拷贝成功");
    }
}

3.序列化与反序列化

1.仅将程序(内存)中的数据写入至文件(磁盘),保存的是值
2.将程序(内存)中的保存值和数据类型写入至文件(磁盘),称作序列化
3.将保存在文件的数据(值和数据类型)恢复至程序,称作反序列化
4.若某个对象支持序列化机制,其类必须是可序列化的,需要是实现两个接口之一(Serializable(标记接口,没有方法)、Externalizable(需要是实现方法))

3.1 对象字节输出流 ObjectOutputStream(序列化)

创建一个Person类

import java.io.Serializable;

public class Person implements Serializable {
    private String name;
    private int age;
    
    //序列化对象时,默认将其所有属性都序列化,除static和transient修饰的成员
    private transient String nation;
    private static String city;
    
    //序列化对象时,其属性的类型也需要实现序列化接口
    private Hobby hobby = new Hobby();
    
    //serialVersionUID序列化版本号,可提高兼容性
    private static final long serialVersionUID = 1L;

    public Person(String name, int age, String nation, String city) {
        this.name = name;
        this.age = age;
        this.nation = nation;
        this.city = city;
    }

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

    public String getNation() {
        return nation;
    }

    public void setNation(String nation) {
        this.nation = nation;
    }

    public static String getCity() {
        return city;
    }

    public static void setCity(String city) {
        Person.city = city;
    }

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", nation='" + nation + '\'' +
                '}' + city + hobby;
    }
}

实现序列化

import com.yl.IO.Person;

import java.io.FileOutputStream;
import java.io.ObjectOutputStream;

public class ObjectOutputStream_ {
    public static void main(String[] args) throws Exception {

        String filePath = "D:\\data.dat";

        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(filePath));

        //序列化数据
        oos.writeInt(10);  //int -> Integer (实现了Serializable)
        oos.writeBoolean(true); //boolean -> Boolean (实现了Serializable)
        oos.writeChar('q'); //char -> Charactor (实现了Serializable)
        oos.writeDouble(3.14159);   //double -> Double (实现了Serializable)
        oos.writeUTF("杨杨杨");    //String

        //保存一个Person对象
        oos.writeObject(new Person("架构师", 28, "china", "beijing"));

        oos.close();    //关闭流

        System.out.println("序列化成功");
    }
}

在这里插入图片描述

3.2 对象字节输入流 ObjectInputStream(反序列化)

import com.yl.IO.Person;

import java.io.FileInputStream;
import java.io.IOException;
import java.io.ObjectInputStream;

public class ObjectInputStream_ {
    public static void main(String[] args) throws IOException, ClassNotFoundException {
        String filePath = "D:\\data.dat";

        ObjectInputStream ois = new ObjectInputStream(new FileInputStream(filePath));

        //读取(反序列化)的顺序需要和保存数据(序列化)的顺序一致

        System.out.println(ois.readInt());
        System.out.println(ois.readBoolean());
        System.out.println(ois.readChar());
        System.out.println(ois.readDouble());
        System.out.println(ois.readUTF());

        Object person = ois.readObject();
        System.out.println("运行类型:" + person.getClass());
        System.out.println("对象信息:" + person);   //底层 Object -> Person

        //若调用Person类中的方法,则需要向下转型,Person类必须在可以引用到的位置
        Person person2 = (Person)person;
        System.out.println(person2.getName());

        ois.close();    //关闭流
    }
}

在这里插入图片描述

小结
1.读写顺序一致
2.要求实现序列化\反序列化对象,需要实现Serializablea
3.序列化的类中添加序列化版本号 private static final long serialVersionUID = 1L 可以提高版本兼容性
4.序列化对象时,默认将其所有属性都序列化,除static和transient修饰的成员
5.序列化对象时,要求其属性的类型也要是实现序列化接口
6.序列化具备可继承性,若某类已实现序列化,则其所有子类也默认实现了序列化

4.标准输入输出流

System.in 标准输入 InputStream 键盘
System.out 标准输出 PrintStream 显示器

public class InputAndOutput {
    public static void main(String[] args) {
        //System类的     public final static InputStream in = null;
        //System.in 编译类型    InputStream
        //System.in 运行类型    BufferedInputStream
        //标准输入 键盘
        System.out.println(System.in.getClass());

        //System.out    public final static PrintStream out = null;
        //编译类型  PrintStream
        //运行类型  PrintStream
        //标准输出 显示器
        System.out.println(System.out.getClass());
    }
}

应用
1.System.out.println() 使用out对象将数据输出到显示器
2.Scanner scanner = new Scanner(System.in) 从标准输入键盘接受数据

5.转换流

InputStreamReader是Reader的子类,可将InputStream(字节流)包装成Reader(字符流)

OutputStreamWriter是Writer的子类,可将OutputStream(字节流)包装成Writer(字符流)

处理纯文本数据时,若使用字符流效率更高,且可解决中文乱码问题,则将字节流转换成字符流

指定编码格式,UTF-8,GBK,GB2312,ISO-8859-1

文件乱码可由转换流解决

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;

public class CodeQ {
    public static void main(String[] args) throws IOException {
        //路径
        String filePath = "D:\\run.txt";

        //创建字符输入流 BufferedReader
        BufferedReader br = new BufferedReader(new FileReader(filePath));

        //默认 utf-8 若改成其他编码会出现乱码,以ANSI为例
        String s = br.readLine();
        System.out.println(s);
        br.close();
    }
}

在这里插入图片描述

5.1 InputStreamReader

import java.io.*;

public class InputStreamReader_ {
    public static void main(String[] args) throws IOException {
        //路径
        String filePath = "D:\\run.txt";

        //FileInputStream 转换成 InputStreamReader
        //InputStreamReader isr = new InputStreamReader(new FileInputStream(filePath),"GBK");

        //将InputStreamReader 传入 BufferedReader
        //BufferedReader br = new BufferedReader(isr);

        BufferedReader br = new BufferedReader(new InputStreamReader(
                new FileInputStream(filePath),"GBK"));

        String s = br.readLine();
        System.out.println(s);

        br.close();
    }
}

在这里插入图片描述

5.2 OutputStreamWriter

import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;

public class OutputStreamWriter_ {
    public static void main(String[] args) throws IOException {

        //路径
        String filePath = "D:\\yl.txt";

        String charset = "GBK";
        OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream(filePath), charset);
        osw.write("哈喽,Java");
        osw.close();
        System.out.println("以" + charset + "方式保存文件成功");
    }
}

在这里插入图片描述

6.打印流

只有输出流,没有输入流

6.1 字节打印流 PrintStream

import java.io.IOException;
import java.io.PrintStream;

public class PrintStream_ {
    public static void main(String[] args) throws IOException {
        PrintStream out = System.out;

        out.println("hi,java");

/*      //print的底层方法是write
        public void print(String s) {
            if (s == null) {
                s = "null";
            }
            write(s);
        }*/
        out.write("hi,杨杨杨".getBytes());
        out.close();

        //修改打印流输出的位置\设备
        System.setOut(new PrintStream("D:\\rain.txt"));
/*        public static void setOut(PrintStream out) {
            checkIO();
            setOut0(out);   //native方法,修改了out
        }*/
        System.out.println("hi,杨杨杨");
    }
}

在这里插入图片描述

6.2 字符打印流 PrintWriter

import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;

public class PrintWriter_ {
    public static void main(String[] args) throws IOException {

        //PrintWriter printWriter = new PrintWriter(System.out);
        //重定向
        PrintWriter printWriter = new PrintWriter(new FileWriter("D:\\yly.txt"));
        printWriter.print("hi,跑步");
        printWriter.close();
    }
}

7.Properties

专门读写配置文件的集合类

格式:键=值
键值对不需要空格,值不需要引号,默认类型:String

新建mysql.properties

ip=192.168.1.1
user=admin
pwd=mima123

使用Properties类读取文件

import java.io.FileReader;
import java.io.IOException;
import java.util.Properties;

public class Properties1 {
    public static void main(String[] args) throws IOException {
        //使用Properties类读取mysql.properties文件

        //创建Properties对象
        Properties properties = new Properties();

        //加载指定配置文件
        properties.load(new FileReader("src\\mysql.properties"));

        //显示K-V至控制台
        properties.list(System.out);

        //根据键获取对应的值
        String user = properties.getProperty("user");
        String pwd = properties.getProperty("pwd");
        System.out.println("用户名:" + user);
        System.out.println("密码:" + pwd);
    }
}

在这里插入图片描述

使用Properties类修改文件

import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Properties;

public class Properties2 {
    public static void main(String[] args) throws IOException {
        //使用Properties类创建、配置文件,修改配置文件内容
        Properties properties = new Properties();

        //若文件没有key,为创建
        //有key,为修改
/*       
            Properties父类是Hashtable,底层是Hashtable
            
            public synchronized V put(K key, V value) {
            // Make sure the value is not null
            if (value == null) {
                throw new NullPointerException();   //值为空则抛出空指针异常
            }

            // Makes sure the key is not already in the hashtable.
            Hashtable.Entry<?,?> tab[] = table;
            int hash = key.hashCode();  //计算哈希值,相同则判定为替换
            int index = (hash & 0x7FFFFFFF) % tab.length;
            @SuppressWarnings("unchecked")
            Hashtable.Entry<K,V> entry = (Hashtable.Entry<K,V>)tab[index];
            for(; entry != null ; entry = entry.next) {
                if ((entry.hash == hash) && entry.key.equals(key)) {
                    V old = entry.value;
                    entry.value = value;    //如果key存在则替换
                    return old;
                }
            }

            addEntry(hash, key, value, index);  //如果是新key则addEntry
            return null;
        }*/
        
        properties.setProperty("charset","utf-8");
        properties.setProperty("user","超级admin");    //保存中文 -> 保存它的unicode值
        properties.setProperty("pwd","123mima");
        
        //将键值对存入文件
        properties.store(new FileOutputStream("src\\mysql2.properties"),null);
        System.out.println("创建配置文件成功");

    }
}

在这里插入图片描述

标签:String,流之,System,博客,IO,new,序列化,public,out
来源: https://blog.csdn.net/Aurinko324/article/details/123609361