【缓冲流、转换流、序列化流,打印流、Properties集合】

缓冲流

缓冲流其实是一个包装流,基于基本输入和输出流,提供程序读写的效率。
    字节缓冲流:底层的读和写还是依赖于InputStream和OutputStream
    字符缓冲流:底层的渡河写还是依赖于Reader和Writer
    
字节缓冲流
    //把a.flv内容复制到b.flv中
    //使用BufferedInputStream 对InputStream进行包装
    BufferedInputStream bis=new BufferedInputStream(new FileInputStream("C:\\Users\\WANGQI\\Desktop\\a.flv"));

    //使用BufferedOuputStream, 对OutputStream进行包装
    BufferedOutputStream bos=new BufferedOutputStream(new FileOutputStream("C:\\Users\\WANGQI\\Desktop\\b.flv"));

    byte[] bs=new byte[1024];
    int len;
    while((len=bis.read(bs))!=-1){
        bos.write(bs,0,len);
    }

    bis.close();
    bos.close(); 

字符缓冲流
    //把a.txt内容复制到b.txt中
    //使用BufferedReader 对 FileReader进行包装
    BufferedReader br=new BufferedReader(new FileReader("day10-code\\a.txt"));
    //使用BufferedWriter 对 FileWriter进行包装
    BufferedWriter bw=new BufferedWriter(new FileWriter("day10-code\\b.txt"));

    //一次读取一行的方式 readLine()
    String line; //记录每次读取的一行数据
    while((line=br.readLine())!=null){
        bw.write(line);
        bw.newLine(); //写换行付(可以跨平台)
        bw.flush();
    }

    //释放资源
    bw.close();
    br.close();
 
缓冲流练习
    public class Demo3 {
        public static void main(String[] args) throws IOException {
            //1. 读文件到集合
            ArrayList<String> list=new ArrayList<>();
            BufferedReader br=new BufferedReader(new FileReader("day10-code\\a.txt"));
            String line;
            while ((line=br.readLine())!=null){
                list.add(line);
            }
            br.close();
            //2. 对集合进行排序
            Collections.sort(list, new Comparator<String>() {
                @Override
                public int compare(String o1, String o2) {
                    //o1-o2 升序
                    //o2-o1 降序
                    return o2.compareTo(o1);
                }
            });
            //3. 把集合中的元素,写入到a.txt文件中覆盖即可
            BufferedWriter bw=new BufferedWriter(new FileWriter("day10-code\\a.txt"));
            for (String s : list) {
                bw.write(s);
                bw.newLine();
                bw.flush();
            }
            bw.close();
        }
    }

    

了解几种常用的编码表
    ASCII码表: 包含一些字母、符号、数字
        一个符号占用一个字节
    GBK码表:兼容ASCII码表,包含汉字
        一个汉字占2个字节
    UTF-8码表: 兼容ASCII码表,包含汉字也包含其他国家的文字
        一般情况一个汉字占3个字节

由编码表引出的问题: 
    由于中文简体Windows操作系统使用的编码表是GBK,如果使用系统新建一个文本文件默认编码表就是GBK.
    如果使用Java代码读取这个文件,就会有乱码。因为Intellij IDEA使用的UTF-8编码。
    
    【乱码的原因:编码和解码的字符集不是同一个,就会产生乱码】
    
转换流

可以使用指定的编码进行读和写的操作
    背景:任何文件底层其实都是字节,IDE默认使用的是UTF-8 编码对文本文件进行读和写的操作。如果不是UTF-8 文件就会读写错误
    为了解决这个问题,我们可以使用转换流指定编码进行读和写的操作。

    /*
    把a.txt文件(GBK编码)中的内容,复制到b.txt文件(UTF-8编码)中
    数据源: a.txt文件(GBK编码)
        使用GBK读取a.txt文件中的内容
    数据目的: b.txt文件(UTF-8编码)
        把读取到的内容通过UTF-8编码写到b.txt文件中去
     */
    
    //使用GBK读取a.txt文件中的内容
    InputStreamReader isr=new InputStreamReader(new FileInputStream("day10-code\\a.txt"),"GBK");
    //把读取到的内容通过UTF-8编码写到b.txt文件中去
    OutputStreamWriter osw=new OutputStreamWriter(new FileOutputStream("day10-code\\b.txt"),"UTF-8");

    char[] chs=new char[1024];
    int len=0;
    while((len=isr.read(chs))!=-1){
        osw.write(chs,0,len);
    }

    isr.close();
    osw.close(); 

Properties集合:
    属于Map集合的实现类,也是一个双列集合。【注意:键和值都是String类型】
Properties常用方法
    Object setProperty(String key, String value)  
        添加建值对到集合。如果键重复,把原来的值覆盖。
    String getProperty(String key) 
        根据键获取值
    Set<String> stringPropertyNames() 
        获取所有的键,把所有的键存储到Set集合。

    void load(Reader reader)  
        把文件中的键值对,加载到Properties中
    
    void store(Writer writer, String comments)  
        把Properties集合中的键值对,存储到文件中

代码演示:
    Properties pro=new Properties();
    pro.setProperty("name","LOL");
    pro.setProperty("date","2018-08-08");
    //把集合中的键值对,存储到config.pro文件中。
    pro.store(new FileWriter("day10-code\\config.pro"),null);
    
    //把config.pro文件中的键值对,读取到Properties集合中
    pro.load(new FileReader("day10-code\\config.pro"));
    //获取所有的键
    Set<String> keys=pro.stringPropertyNames();
    for(String key:keys){
        //通过键获取值
        String value=pro.getProperty(key);
        System.out.println(key+"="+value);
    } 

程序结束后,看config.txt文件中的内容如下(#代表注释,不会被读取)
    #Wed Aug 22 10:11:58 CST 2018 
    date=2018-08-08
    name=LOL
 


    

一、标准的输入输出流
    System.out: 标准的输出流,数据会输出到控制台
    System.in:标准的输入流,用来读取键盘录入的数据

二、打印流
    只关注数据的输出目的,不关注数据源。【只能写,不能读】
    PrintWriter和PrintStream
    
    //只关注数据的输出目的,不关注数据源。【只能写,不能读】
    //输出目的是控制台
    PrintWriter pw=new PrintWriter(System.out);
    pw.println(true);
    pw.close();

    //输出目的是文件路径
    PrintWriter pw1=new PrintWriter("day10-code\\b.txt");
    pw1.write("hello");
    pw1.close();

    //输出目的可以是File对象
    PrintWriter pw2=new PrintWriter(new File("day10-code\\b.txt"));
    pw2.write("hello");
    pw2.close();

    //输出目的可以是流对象
    PrintWriter pw3=new PrintWriter(new FileOutputStream("day10-code\\b.txt"));
    pw3.write("wrold");
    pw3.close();

    除了可以使用write方法往对应的目的地写数据,还有两个特殊的方法
        print(...) 可以把想要的数据,原样输出。
        println(...) 可以把想要的数据,原样输出。还可以自动换行;还可以自动刷新,但是要写一个true标记。

三、对象流(序列化流)
    对象流是用来往文件中存储对象或者从文件中读取对象的
    ObjectOutputStream:存储对象(序列化)
        writeObject(Object obj)     往文件写对象
        
    ObjectInputStream:读取对象(反序列化)
        Object readObject()    读取文件中的对象
    
    注意事项:
        1. 被序列化的类必须实现Serializable,否则会报错NotSerializableException
        2. 读和写的序列化必须保持一致,否则就会出现无效的类异常InvalidClassException
            解决办法:写一个固定的序列号,不会被改变。
            private static final long serialVersionUID = 8683488581122892189L;
    
    

今日重点总结:

一、Properties集合
    属于Map集合的实现类,也是一个双列集合。【注意:键和值都是String类型】    
    Properties一般和配置文件结合起来使用。

    Properties pro=new Properties();
    pro.setProperty("name","LOL");
    pro.setProperty("date","2018-08-08");
    //把集合中的键值对,存储到config.pro文件中。
    pro.store(new FileWriter("day10-code\\config.pro"),null);
    
    //把config.pro文件中的键值对,读取到Properties集合中
    pro.load(new FileReader("day10-code\\config.pro"));
    //获取所有的键
    Set<String> keys=pro.stringPropertyNames();
    for(String key:keys){
        //通过键获取值
        String value=pro.getProperty(key);
        System.out.println(key+"="+value);
    } 

二、缓冲流
    缓冲流其实是一个包装流,基于基本输入和输出流,提供程序读写的效率。
        字节缓冲流:底层的读和写还是依赖于InputStream和OutputStream
        字符缓冲流:底层的渡河写还是依赖于Reader和Writer

    //把a.txt内容复制到b.txt中
    //使用BufferedReader 对 FileReader进行包装
    BufferedReader br=new BufferedReader(new FileReader("day10-code\\a.txt"));
    //使用BufferedWriter 对 FileWriter进行包装
    BufferedWriter bw=new BufferedWriter(new FileWriter("day10-code\\b.txt"));

    //一次读取一行的方式 readLine()
    String line; //记录每次读取的一行数据
    while((line=br.readLine())!=null){
        bw.write(line);
        bw.newLine(); //写换行付(可以跨平台)
        bw.flush();
    }

    //释放资源
    bw.close();
    br.close();
    

三、转换流
    /*
    把a.txt文件(GBK编码)中的内容,复制到b.txt文件(UTF-8编码)中
    
    数据源: a.txt文件(GBK编码)
        使用GBK读取a.txt文件中的内容
    数据目的: b.txt文件(UTF-8编码)
        把读取到的内容通过UTF-8编码写到b.txt文件中去
     */
    
    //使用GBK读取a.txt文件中的内容
    InputStreamReader isr=new InputStreamReader(new FileInputStream("day10-code\\a.txt"),"GBK");
    BufferedReader br=new BufferedReader(isr);

    //把读取到的内容通过UTF-8编码写到b.txt文件中去
    OutputStreamWriter osw=new OutputStreamWriter(new FileOutputStream("day10-code\\b.txt"),"UTF-8");
    BufferedWriter bw=new BufferedWriter(osw);

    String line;
    while((line=br.readLine())!=null){
        bw.write(line);
        bw.newLine();
        bw.flush();
    }

    bw.close();
    br.close(); 
    

猜你喜欢

转载自blog.csdn.net/L531003231/article/details/82055450
今日推荐