Java学习——day 17

主要内容

  • 缓冲流
  • 转换流
  • 字节数组流
  • 数据流
  • 对象流

笔记详情

1. 缓冲流

Java中的流可以分为节点流和处理流,节点流处于IO操作的第一线,所有的操作都必须通过他们进行。处理流可以对节点流进行其他流进行处理(提高效率或者操作灵活性)。

缓冲流是Java中的处理流,可以用来提高性能。常见的处理流有字节处理流(BufferedInputStream、BufferedOutputStream )和字符处理流(BufferReader BufferWriter)。常用的用法如下:

/**
 * 使用缓冲流增强功能,提高性能
 */
import java.io.*;
public class Demo01 {

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

        // 建立文件的联系
        File src = new File("src/testStream/1.jpg");
        File dest = new File("src/testStream/2.jpg");

        // 缓冲流,嵌套在文件流的外面,提高性能
        InputStream is = new BufferedInputStream(new FileInputStream(src));
        OutputStream os = new BufferedOutputStream(new FileOutputStream(dest));
        
        byte[] data = new byte[10];       // 每次读取和写入的字节大小
        int len;

        // 不断读取和写入
        while ((len = is.read(data)) != -1) {
            os.write(data);
            os.flush();
        }

        // 关闭的时候,先打开的后关闭
        os.close();
        is.close();
    }
}

2. 转换流

转换流是Java中的处理流,主要的作用是在字节流和字符流之间的转换,在使用的时候要注意到字符集的选择,否则会出现乱码的情况。这里提一下编码和解码: 字符到字节的过程称为编码,字节到字符的过程称为解码。

实例如下:

字符流转换为字节流(编码过程)
import java.io.*;

/**
 * 使用转换流实现字节到字符的转换,写出到外部文件
 * 字符流 ----> 字节流
 */
public class Demo04 {

    public static void main(String[] args) throws FileNotFoundException, UnsupportedEncodingException ,IOException{
        File file01 = new File("src/testStream/1.txt");

        // 使用指定的字符集,将字符流转成字节流
        OutputStream os = new FileOutputStream(file01);
        Writer fileWriter = new OutputStreamWriter(os, "GBK");

        String content = new String("冯振振");

        fileWriter.write(content);

        fileWriter.flush();

        fileWriter.close();
    }
}
字节流转换为字符流(解码过程)
import java.io.*;

/**
 * 使用转换流实现字节到字符的转换,读取外部文件
 * 字节流 ----> 字符流
 */
public class Demo03 {

    public static void main(String[] args) {
        File file01 = new File("src/testStream/1.txt");

        try {
            // 使用字节流读取文本,然后使用指定的字符集,将字节流转成字符流
            // 如此一来,就不会出现读取文本乱码的问题
            InputStream tempStream = new FileInputStream(file01);
            Reader is = new InputStreamReader(tempStream, "Unicode");

            char[] flush = new char[1024];
            int len;
            while ((len = is.read(flush)) != -1) {
                System.out.println(flush);
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
            System.out.println("文件未找到");
        } catch (IOException e) {
            e.printStackTrace();
            System.out.println("文件读取失败");
        }
    }
}

3. 字节数组流

字节数组流也是用来处理数据的一种形式,在使用的时候与前面提到的几种流相似,也有输入流(ByteArrayInputStream)和输出流(ByteArrayOutputStream)。下面给出连个方法的实例,介绍一下字节数组流的使用方式:

将字节数组流的数据写入到外部文件中
/**
 * 将字节数组写入到外部文件中
 * @param src 字节数组
 * @param destPath 写出的外部文件
 * @throws IOException
 */
public static void write(byte[] src, String destPath) throws IOException {

    // 根据传入的参数,创建字节数组输入流和文件输出流
    File dest = new File(destPath);
    InputStream is = new BufferedInputStream(new ByteArrayInputStream(src));
    OutputStream os = new BufferedOutputStream(new FileOutputStream(dest));

    byte[] flush = new byte[10];
    int len = 0;

    // 不断读取字节数组输入流,写出到外部文件
    while (-1 != (len = is.read(flush))) {
        os.write(flush, 0, len);
    }

    os.flush();

    os.close();
    is.close();
}
以字节数组流的形式读取外部文件中的内容
/**
 * 从外部文件中读取字节数组内容
 * @param srcPath 外部文件的路径
 * @return 包含外部文件的字节数组
 * @throws IOException
 */
public static byte[] read(String srcPath) throws IOException {
    File src = new File(srcPath);
    InputStream is = new BufferedInputStream(new FileInputStream(src));
    ByteArrayOutputStream bos = new ByteArrayOutputStream();

    byte[] flush = new byte[10];
    int len = 0;

    while (-1 != (len = is.read(flush))) {
        bos.write(flush, 0, len);
    }
    bos.flush();

    return bos.toByteArray();
}

4. 数据流

数据流可以实现Java中数据类型的写入与写出,不仅保存数据值本身,还可以保存数据的类型。

其中数据输出流允许应用程序以适当方式将基本 Java 数据类型写入输出流中。然后,应用程序可以使用数据输入流将数据读入。

需要注意的是,使用数据输出流将数据类型写出到外部文件中的时候,内容和字节码文件相似,是一些机器识别的编码,我们看不懂。在读取外部文件中数据流内容的时候,读取的顺序要和写入的顺序相同,否则会发生错误。下面给出两个实例:

将Java中的数据流写出到外部文件
public static void write() throws FileNotFoundException, IOException {
    File dest = new File("src/testStream/3.txt");
    DataOutputStream dos = new DataOutputStream(
            new BufferedOutputStream(new FileOutputStream(dest))
    );

    int num = 6;
    double doubleNum = 20.5;
    String name = "fengzhen";

    dos.writeInt(num);
    dos.writeDouble(doubleNum);
    dos.writeUTF(name);

    dos.close();
}
从外部文件中读取Java数据流
public static void read(String srcPath) throws FileNotFoundException, IOException {
    File srcFile = new File(srcPath);
    DataInputStream dis = new DataInputStream(
            new BufferedInputStream(new FileInputStream(srcFile))
    );

   int num =  dis.readInt();
   double doubleNum = dis.readDouble();
   String name = dis.readUTF();

   System.out.println(num);
   System.out.println(doubleNum);
   System.out.println(name);

}

5. 对象流

对象流和上面的数据流一样,可以实现对象的写入与写出。对象的写入与写出又被称为 反序列化序列化

但是并不是每一个对象都可以被写入写出,也不是每一个属性能够被写入和写出。首先我们先定义一个Student类,注意看其中的注释:

/**
 * 定义一个Student类,该类必须继承Serializable接口,才能实现对象的写入与写出
 * 该接口是一个空接口,里面没有定义方法
 */
public class Student implements java.io.Serializable {

    private String name;
    private double height;
    private transient String gender;        // 不需要序列化的属性,使用transient修饰

    public Student() {
    }

    public Student(String name, double height, String gender) {
        this.name = name;
        this.height = height;
        this.gender = gender;
    }

    public String getName() {
        return name;
    }

    public double getHeight() {
        return height;
    }

    public String getGender() {
        return gender;
    }
}

下面提供两个方法的实例,了解一下对象流的使用:

将Java程序中的对象写出到外部文件
/**
 * 将对象写出到外部文件中,即对象的序列化
 * @throws IOException
 */
public static void write() throws IOException {
    File dest = new File("src/testStream/3.txt");
    ObjectOutputStream dos = new ObjectOutputStream(
            new BufferedOutputStream(new FileOutputStream(dest))
    );

    Student stu = new Student("Tom", 175, "male");

    dos.writeObject(stu);

    dos.close();
}
从外部文件中读取对象
/**
 * 从外部文件中读取对象,即对象的反序列化
 * @param srcPath
 * @throws IOException
 * @throws ClassNotFoundException
 */
public static void read(String srcPath) throws IOException, ClassNotFoundException {
    File srcFile = new File(srcPath);
    ObjectInputStream dis = new ObjectInputStream(
            new BufferedInputStream(new FileInputStream(srcFile))
    );

    Student stu = (Student) dis.readObject();

    System.out.println(stu.getGender());        // 没有被序列化,结果为null
    System.out.println(stu.getHeight());
    System.out.println(stu.getName());
}

猜你喜欢

转载自blog.csdn.net/fengzhen8023/article/details/86665178