Java程序设计--输入输出流(下)(十七)

本文详细介绍了Java中的IO流,包括缓冲流的提升性能原理,字节缓冲流和字符缓冲流的使用,转换流的字符输入输出转换,对象序列化与反序列化的步骤,以及打印流的高效打印功能和输出语句的重定向。此外,还讲解了Properties对象在处理属性文件中的作用。
摘要由CSDN通过智能技术生成


1、缓冲流

1.1 缓冲流概述

  • 缓冲流也称为高效流、或者高级流。之前学习的字节流可以称为原始流。
  • 作用:缓冲流自带缓冲区、可以提高原始字节流、字符流读写数据的性能。

在这里插入图片描述

1.2 字节缓冲流

字节缓冲流性能优化原理:

  • 字节缓冲输入流自带了8KB缓冲池,以后我们直接从缓冲池读取数据,所以性能较好。
  • 字节缓冲输出流自带了8KB缓冲池,数据就直接写入到缓冲池中去,写数据性能极高了。

字节缓冲流

  • 字节缓冲输入流: BufferedInputStream,提高字节输入流读取数据的性能,读写功能上并无变化。
  • 字节缓冲输出流: BufferedOutputStream,提高字节输出流读取数据的性能,读写功能上并无变化。
构造器说明
public BufferedInputStream(InputStream is)可以把低级的字节输入流包装成一个高级的缓冲字节输入流管道,从而提高字节输入流读数据的性能
public BufferedOutputStream(OutputStream os)可以把低级的字节输出流包装成一个高级的缓冲字节输出流,从而提高写数据的性能
import java.io.*;

/**
    使用字节缓冲流完成数据的读写操作。
 */
public class ByteBufferDemo {
    public static void main(String[] args) {

        try (
                // 这里面只能放置资源对象,用完会自动关闭:自动调用资源对象的close方法关闭资源(即使出现异常也会做关闭操作)
                // 1、创建一个字节输入流管道与原视频接通
                InputStream is = new FileInputStream("D:\\resources\\demo.jpeg");
                // a.把原始的字节输入流包装成高级的缓冲字节输入流
                InputStream bis = new BufferedInputStream(is);
                // 2、创建一个字节输出流管道与目标文件接通
                OutputStream os = new FileOutputStream("D:\\resources\\demo222.jpeg");
                // b.把字节输出流管道包装成高级的缓冲字节输出流管道
                OutputStream bos = new BufferedOutputStream(os);

        ) {

            // 3、定义一个字节数组转移数据
            byte[] buffer = new byte[1024];
            int len; // 记录每次读取的字节数。
            while ((len = bis.read(buffer)) != -1){
                bos.write(buffer, 0 , len);
            }
            System.out.println("复制完成了!");

        } catch (Exception e){
            e.printStackTrace();
        }

    }
}

1.3 字符缓冲流概述

字符缓冲输入流:BufferedReader。

  • 作用:提高字符输入流读取数据的性能,除此之外多了按照行读取数据的功能。
构造器说明
public BufferedReader( Reader r)可以把低级的字符输入流包装成一个高级的缓冲字符输入流管道,从而提高字符输入流读数据的性能

字符缓冲输入流新增功能

方法说明
public String readLine()读取一行数据返回,如果读取没有完毕,无行可读返回null
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.io.Reader;

/**
    学会使用缓冲字符输入流提高字符输入流的性能,新增了按照行读取的方法(经典代码)
 */
public class BufferedReaderDemo1 {
    public static void main(String[] args) {
        try (
                // 1、创建一个文件字符输入流与源文件接通。
                Reader fr = new FileReader("io-app2/src/data01.txt");
                // a、把低级的字符输入流包装成高级的缓冲字符输入流。
                BufferedReader br = new BufferedReader(fr);
                ){
              String line;
              while ((line = br.readLine()) != null){
                  System.out.println(line);
              }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

字符缓冲输出流:BufferedWriter。

  • 作用:提高字符输出流写取数据的性能,除此之外多了换行功能
构造器说明
public BufferedWriter(Writer w)可以把低级的字符输出流包装成一个高级的缓冲字符输出流管道,从而提高字符输出流写数据的性能
字符缓冲输出流新增功能
方法说明
:-::-:
public void newLine()换行操作
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.Writer;

/**
        缓冲字符输出流的使用,学会它多出来的一个功能:newLine();
 */
public class BufferedWriterDemo2 {
    public static void main(String[] args) throws Exception {
        // 1、创建一个字符输出流管道与目标文件接通
        Writer fw = new FileWriter("io-app2/src/out02.txt"); // 覆盖管道,每次启动都会清空文件之前的数据
       //Writer fw = new FileWriter("io-app2/src/out02.txt", true); // 追加数据
        BufferedWriter bw = new BufferedWriter(fw);

//      a.public void write(int c):写一个字符出去
        bw.write(98);
        bw.write('a');
        bw.write('徐'); // 不会出问题了
        bw.newLine(); // bw.write("\r\n"); // 换行

//       b.public void write(String c)写一个字符串出去
        bw.write("abc我是中国人");
        bw.newLine(); // bw.write("\r\n"); // 换行


//       c.public void write(char[] buffer):写一个字符数组出去
        char[] chars = "abc我是中国人".toCharArray();
        bw.write(chars);
        bw.newLine(); // bw.write("\r\n"); // 换行


//       d.public void write(String c ,int pos ,int len):写字符串的一部分出去
        bw.write("abc我是中国人", 0, 5);
        bw.newLine(); // bw.write("\r\n"); // 换行

//       e.public void write(char[] buffer ,int pos ,int len):写字符数组的一部分出去
        bw.write(chars, 3, 5);
        bw.newLine(); // bw.write("\r\n"); // 换行


        // fw.flush();// 刷新后流可以继续使用
        bw.close(); // 关闭包含刷线,关闭后流不能使用

    }
}


2、转换流

2.1 字符输入转换流

字符输入转换流: InputStreamReader,可以把原始的字节流按照指定编码转换成字符输入流。可以解决字符流读取不同编码乱码问题。

构造器说明
public InputStreamReader(InputStream is)可以把原始的字节流按照代码默认编码转换成字符输入流。几乎不用,与默认的FileReader—样。
public InputStreamReader(InputStream is , String charset)可以把原始的字节流按照指定编码转换成字符输入流,这样字符流中的字符就不乱码了(重点)
import java.io.*;

public class InputStreamReaderDemo {
    public static void main(String[] args) throws Exception {
        // 代码UTF-8   文件 GBK  "D:\\resources\\data.txt"
        // 1、提取GBK文件的原始字节流。   abc 我
        //                            ooo oo
        InputStream is = new FileInputStream("D:\\resources\\data.txt");
        // 2、把原始字节流转换成字符输入流
        // Reader isr = new InputStreamReader(is); // 默认以UTF-8的方式转换成字符流。 还是会乱码的  跟直接使用FileReader是一样的
        Reader isr = new InputStreamReader(is , "GBK"); // 以指定的GBK编码转换成字符输入流  完美的解决了乱码问题

        BufferedReader br = new BufferedReader(isr);
        String line;
        while ((line = br.readLine()) != null){
            System.out.println(line);
        }
    }
}

2.2 字符输出转换流

字符输入转换流:OutputStreamWriter,可以把字节输出流按照指定编码转换成字符输出流。

构造器说明
public OutputStreamWriter(OutputStream os)可以把原始的字节输出流按照代码默
public OutputStreamWriter(OutputStream os,String charset)可以把原始的字节输出流按照指定编码转换成字符输出流(重点)
import java.io.*;
import java.nio.Buffer;

public class OutputStreamWriterDemo {
    public static void main(String[] args) throws Exception {
        // 1、定义一个字节输出流
        OutputStream os = new FileOutputStream("io-app2/src/out03.txt");

        // 2、把原始的字节输出流转换成字符输出流
        // Writer osw = new OutputStreamWriter(os); // 以默认的UTF-8写字符出去 跟直接写FileWriter一样
        Writer osw = new OutputStreamWriter(os , "GBK"); // 指定GBK的方式写字符出去

        // 3、把低级的字符输出流包装成高级的缓冲字符输出流。
        BufferedWriter bw = new BufferedWriter(osw);

        bw.write("我爱中国1~~");
        bw.write("我爱中国2~~");
        bw.write("我爱中国3~~");

        bw.close();
    }
}

3、序列化对象

3.1 对象序列化

在这里插入图片描述

对象序列化:

  • 作用:以内存为基准,把内存中的对象存储到磁盘文件中去,称为对象序列化(对象必须实现序列化接口)。
  • 使用到的流是对象字节输出流:ObjectOutputStream

在这里插入图片描述

使用到的流是对象字节输出流:ObjectOutputStream

构造器说明
public ObjectOutputstream(Outputstream out)把低级字节输出流包装成高级的对象字节输出流
ObjectOutputStream序列化方法
方法名称说明
:-::-:
public final void writeObject(object obj)把对象写出去到对象序列化流的文件中去
import java.io.Serializable;

/**
  对象如果要序列化,必须实现Serializable序列化接口。
 */
public class Student implements Serializable {
    // 申明序列化的版本号码
    // 序列化的版本号与反序列化的版本号必须一致才不会出错!
    private static final long serialVersionUID = 1;
    private String name;
    private String loginName;
    // transient修饰的成员变量不参与序列化了
    private transient String passWord;
    private int age ;

    public Student(){
    }

    public Student(String name, String loginName, String passWord, int age) {
        this.name = name;
        this.loginName = loginName;
        this.passWord = passWord;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getLoginName() {
        return loginName;
    }

    public void setLoginName(String loginName) {
        this.loginName = loginName;
    }

    public String getPassWord() {
        return passWord;
    }

    public void setPassWord(String passWord) {
        this.passWord = passWord;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", loginName='" + loginName + '\'' +
                ", passWord='" + passWord + '\'' +
                ", age=" + age +
                '}';
    }
}

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

public class ObjectOutputStreamDemo {
    public static void main(String[] args) throws Exception {
        // 1、创建学生对象
        Student s = new Student("陈磊", "chenlei","1314520", 21);

        // 2、对象序列化:使用对象字节输出流包装字节输出流管道
        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("io-app2/src/obj.txt"));

        // 3、直接调用序列化方法
        oos.writeObject(s);

        // 4、释放资源
        oos.close();
        System.out.println("序列化完成了~~");

    }
}

3.2对象反序列化

对象反序列化:

  • 使用到的流是对象字节输入流:ObjectlnputStream
  • 作用:以内存为基准,把存储到磁盘文件中去的对象数据恢复成内存中的对象,称为对象反序列化。
    在这里插入图片描述
构造器说明
public objectInputstream(Inputstream out)把低级字节输如流包装成高级的对象字节输入流

objectInputStream序列化方法

方法名称说明
public Obiect readObiect()把存储到磁盘文件中去的对象数据恢复成内存中的对象返回
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.ObjectInputStream;

/**
    目标:学会进行对象反序列化:使用对象字节输入流把文件中的对象数据恢复成内存中的Java对象。
 */
public class ObjectInputStreamDemo {
    public static void main(String[] args) throws Exception {
        // 1、创建对象字节输入流管道包装低级的字节输入流管道
        ObjectInputStream is = new ObjectInputStream(new FileInputStream("io-app2/src/obj.txt"));

        // 2、调用对象字节输入流的反序列化方法
        Student s = (Student) is.readObject();

        System.out.println(s);
    }
}

4、打印流

4.1 PrintStream、PrintWriter

在这里插入图片描述

打印流

  • 作用: 打印流可以实现方便、高效的打印数据到文件中去。 打印流一般是指: PrintStream,PrintWriter两个类。
  • 可以实现打印什么数据就是什么数据,例如打印整数97写出去就是97,打印boolean的true,写出去就是true。

PrintStream

构造器说明
public PrintStream(OutputStream os)打印流直接通向字节输出流管道
public printStream(File f)打印流直接通向文件对象
public PrintStream(String filepath)打印流直接通向文件路径
方法说明
public void print(Xxx xx)打印任意类型的数据出去

PrintWriter

构造器说明
public Printwriter(OutputStream os)打印流直接通向字节输出流管道
public printwriter (Writer w)打印流直接通向字符输出流管道
public Printwriter (File f)打印流直接通向文件对象
public Printwriter (String filepath)打印流直接通向文件路径
方法说明
public void print(Xxx xx)打印任意类型的数据出去

PrintStream和PrintWriter的区别

  • 打印数据功能上是一模一样的,都是使用方便,性能高效(核心优势)
  • PrintStream继承自字节输出流OutputStream,支持写字节数据的方法。
  • PrintWriter继承自字符输出流Writer,支持写字符数据出去。
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.PrintStream;
import java.io.PrintWriter;

/**
    学会使用打印流 高效  方便写数据到文件。
 */
public class PrintDemo {
    public static void main(String[] args) throws Exception {
        PrintWriter ps = new PrintWriter("io-app2/src/ps.txt"); // 打印功能上与PrintStream的使用没有区别

        ps.println(97);
        ps.println('a');
        ps.println(23.3);
        ps.println(true);
        ps.println("我是打印流输出的,我是啥就打印啥");

        ps.close();
    }
}

4.2 输出语句的重定向

属于打印流的一种应用,可以把输出语句的打印位置改到文件。

import java.io.FileOutputStream;
import java.io.PrintStream;

/**
    目标:了解改变输出语句的位置到文件
 */
public class PrintDemo2 {
    public static void main(String[] args) throws Exception {
        System.out.println("锦瑟无端五十弦");
        System.out.println("一弦一柱思华年");

        // 改变输出语句的位置(重定向)
        PrintStream ps = new PrintStream("io-app2/src/log.txt");
        System.setOut(ps); // 把系统打印流改成我们自己的打印流

        System.out.println("庄生晓梦迷蝴蝶");
        System.out.println("望帝春心托杜鹃");
    }
}

5、Properties

在这里插入图片描述

Properties属性集对象

  • 其实就是一个Map集合,但是我们一般不会当集合使用,因为HashMap更好用。

Properties核心作用:

  • Properties代表的是一个属性文件,可以把自己对象中的键值对信息存入到一个属性文件中去。
  • 属性文件:后缀是.properties结尾的文件,里面的内容都是key=value,后续做系统配置信息的。

Properties的API:

Properties和IO流结合的方法:

构造器说明
void load(InputStream inStream)从输入字节流读取属性列表(键和元素对)
void load(Reader reader)从输入字符流读取属性列表(键和元素对)
void store(OutputStream out,String comments)将此属性列表(键和元素对)写入此 Properties表中,以适合于使用load(InputStream)
void store(Writer writer,String comments)将此属性列表(键和元素对)写入此 Properties表中以适合使用load(Reader)方法的格式写入输出字符流
public object setProperty(String key,String value)保存键值对(put)
public object setProperty(String key)使用此属性列表中指定的键搜索属性值(get)
public Set< string > stringPropertyNames()所有键的名称的集合(keySet())
import java.io.FileWriter;
import java.util.Map;
import java.util.Properties;
import java.util.Scanner;


public class PropertiesDemo {
    public static void main(String[] args) throws Exception {
        // 需求:使用Properties把键值对信息存入到属性文件中去。
        Properties properties = new Properties();
        properties.setProperty("admin", "123456");
        properties.setProperty("dlei", "003197");
        properties.setProperty("heima", "itcast");
        System.out.println(properties);

        /**
           参数一:保存管道 字符输出流管道
           参数二:保存心得
         */
        properties.store(new FileWriter("io-app2/src/users.properties")
                , "this is users!! i am very happy! give me 100!");

    }
}


6、IO框架

commons-io概述

  • commons-io是apache开源基金组织提供的一组有关IO操作的类库,可以提高IO功能开发的效率。
  • commons-io工具包提供了很多有关io操作的类。有两个主要的类FileUtils, IOUtils

FileUtils主要有如下方法:

方法名说明
String readFileToString(File file,string encoding)读取文件中的数据,返回字符串。
void copyFile(File srcFile,File destFile)复制文件。
void copyDirectoryToDirectory(File srcDir,File destDir)复制文件夹。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

会思想的苇草i

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值