节点流处理流

节点流和包装流是对流的另外一种分类 , 节点流可以从一个特定的数据源读写数据 , 包装流连接已经存在的节点流或者处理流之上 , 提供更强大的读写功能

节点流处理流一览

image-20220905144929085

节点流

​ 节点流是对各种资源的直接操作 , 属于比较低级的操作

image-20220905145535799

包装流

​ 包装流在节点流之上提供更强大的功能 , 可以用包装流对应的节点流构造包装流 , 如
​ bufferedReader 可以接受 Reader 的子类 来构造

​ 包装流中封装了read write 等节点流的基类 , 使其可以灵活地接受各种节点流 , 对访问的资源不会有限制 , 可以消除各个节点流之间的差异 , 有的流对文件操作 , 有的流对数组操作 , 你想对那种数据源操作 ,你就传入那种节点流 , 包装起来之后可以 更加方便的输入输出

image-20220905150907305

字符装流

流的输入

​ 以 bufferedReader 为例子

方法 解释
bufferedReader.readLine() 返回String,读完返回null,不读回车换行

流的输出

以 bufferedWriter 为例子

bufferedWriter.write(12); int 为ACS , 读取的时候需要强转 , 建议直接输入时候转为String
bufferedWriter.newLine(); 包装流写入没有换行,newline函数可以根据系统的不同写入不同的换行符
bufferedWriter.write("akaashi"); String / char[ ]
bufferedWriter.write("akaashi",0,1); tring/char[],开始下标,截取长度
package Io_;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileReader;
import java.io.FileWriter;

public class _01 {
    public static void main(String[] args) throws Exception{
        String path = "d://aa.txt";
        BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter(path, false));
        bufferedWriter.write("12345678654",0,9);
        bufferedWriter.close();
        BufferedReader bufferedReader = new BufferedReader(new FileReader(path));
        String aa ;
        while ((aa = bufferedReader.readLine()) != null) {
            System.out.print(aa);
        }
        bufferedReader.close();
        //必须要关闭或者刷新,不然写不进去
    }
}

文件拷贝

package Io_;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileReader;
import java.io.FileWriter;

/**
 * @author Akaashi
 * @version 1.0
 */
public class _02 {
    public static void main(String[] args) throws Exception{
        String a1 = "d://a1.txt";
        String a2 = "d://a2.txt";
        BufferedReader bufferedReader = new BufferedReader(new FileReader(a1));
        BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter(a2,true));
        String num ;
        while ((num = bufferedReader.readLine())!=null){
            bufferedWriter.write(num);
            bufferedWriter.newLine();
        }
        bufferedReader.close();
        bufferedWriter.close();

    }
}

字节包装流

​ 用于处理二进制的数据源 , 直接传入字节处理流即可

流的输入

image-20220905185138329

方法 解释
read ( ) 读一个 , 数据存在 int中 , 读完返回-1 ,
read ( byte [] , int off , int len ) 读一个数组 ,

流的输出

image-20220905185207421

方法 解释
flush ( ) 刷新,要刷新才算写入
write ( ) 写一个
write ( byte [] , int off , int len ) 写一个数组

对象包装流

​ 保存的是序列化的文本 , 就是不仅仅保存内容 , 也保存数据类型

序列化

​ 只有实现了可序列化接口的内容才能使用对象流 , 特别是自己定义的对象 , 要继承可序列化接口 , 可以下面两个接口选一个

  • Serializable

    标记接口 , 没有方法 , 直接实现就行 , 建议选这个

  • Externalizable

    其中有两个方法需要去实现


    最基本的包装类都实现了可序列化功能

  1. 可序列化的类中要保证每一个属性都是序列化的
  2. 序列化具有可继承性,父类可序列化,子类也可以

流的输入

image-20220906091000199

提供反序列化功能 , 为使用修饰器模式的包装流

序列化之后 , 保存的文件格式不是 txt 是 dat

方法 解释
writeInt 保存数字
writeChar 保存字符
writeUTF 保存字符串
writeObject 保存对象

单独写write ( ) 无法保存数据类型

public class _03 {
    public static void main(String[] args) throws Exception{
        ObjectOutputStream objOutput = new ObjectOutputStream(new FileOutputStream("D://data.dat",true));
        objOutput.writeInt(100);
        objOutput.writeChar('a');
        objOutput.writeUTF("字符串");
        objOutput.writeObject(new People("赤苇",24));
        objOutput.close();//不关闭流会导致写入错误
       
    }
}
class People implements Serializable{
    String name;
    int age;

    public People(String name, int age) {
        this.name = name;
        this.age = age;
    }
    
    @Override//在加入,删除了toString,或者更新了对象的方法的时候需要将对象重新保存才能正确读取 , 修改toString方法不用重新写入也可以修改
    public String toString() {
        return "People{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}

流的输出

image-20220906091108037

提供序列化功能 , 为使用修饰器模式的包装流

需要保存顺序和读取顺序一致

package Io_;

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

/**
 * @author Akaashi
 * @version 1.0
 */
public class _04 {
    public static void main(String[] args) throws Exception{
        ObjectInputStream objInput = new ObjectInputStream(new FileInputStream("D://data.dat"));
        System.out.println(objInput.readInt());
        System.out.println(objInput.readChar());
        System.out.println(objInput.readUTF());
        System.out.println(objInput.readObject());package Io_;

import java.io.FileInputStream;
import java.io.ObjectInputStream;
import
/**
 * @author Akaashi
 * @version 1.0
 */
public class _04 {
    public static void main(String[] args) throws Exception{
        ObjectInputStream objInput = new ObjectInputStream(new FileInputStream("D://data.dat"));
        System.out.println(objInput.readInt());
        System.out.println(objInput.readChar());
        System.out.println(objInput.readUTF());
        System.out.println(objInput.readObject());
        People a = (People)objInput.readObject();
        //希望使用people的方法需要向下转型
        a.as();//注意,这里会出现EOFException问题
        // 在之前的代码中我们可以看到people的访问修饰符是默认的
        // 所以这里不能使用people的方法
    }
}

​ 我们有三种方法解决这个问题

  1. 将people类的信息粘贴到输入的地方 , 此时我们需要将类重新保存

  2. 将people类公有化成public

  3. 将people类import

对象包装流使用细节

  1. 读写顺序要一致
  2. 可以在可序列化对象中加入 serialVersionUID 属性 , 如果之后有类的内容更新 , 有这个属性会让jvm认为还是这个类 , 只不过版本修改了
  3. static, transient ( 短暂的 ) 修饰的属性无法序列化 , 无法被保存
class People implements Serializable {
    String name;
    int age; 
    private static final long serialVersionUID = 1L;
    static String sex;
    transient String adess;
    //最后读出来的是
    //People{name='cw', age=24, adess='null'sex=null}




  1. 需要序列化对象中的所有属性都可以序列化

标准输入输出流

image-20220906104454430

system.in  编译类型 inputstream
		  运行类型 bufferedinputstream
    //表示标准输入 键盘
system.out 编译类型 printstream
		  运行类型 printstream
    //表示标准输出 显示器
		 

image-20220906104848968

System . in 就是标准输入流的对象 ,传给扫描器

转换流

​ 将字节字符流相互转化 , 可以将乱码变成可以读的 , 当你需要指定字符写入文件的时候也可以使用转换流

​ 文件流读取是默认utf-8 , 如果不是这个编码 , 可能会出现乱码 , 此时我们可以使用字节流读取 , 因为字节流可以指定编码读取 , 再用装换流将字节流转化成字符流

outputstream writer ( ) 是 输入字符流 子类
inputstream reader ( ) 是 输出字符流 子类
public class _05 {
    public static void main(String[] args) throws   Exception {
        OutputStreamWriter gbk = new OutputStreamWriter(
                                 new FileOutputStream("d://a.txt",true), "gbk");
        //将output转化成Writer,并在创建转换流的时候传入节点流和写入编码
        gbk.write("asdad");
        gbk.close();
        InputStreamReader inputStreamReader = new InputStreamReader(
                                              new FileInputStream("d://a.txt"),"gbk");
        //将input转化成reader,并在创建转换流的时候传入节点流和读取编码
        BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
        //将reader包装成buffer reader,方便读取
        String data = "";
        while ((data = bufferedReader.readLine()) != null) {
            System.out.println(data);
        }
        bufferedReader.close();
    }
}

打印流

​ 只有输出流 , 毕竟是用来打印的

printstream

​ 字节打印流 , 继承outputstream , 默认控制台输出 , 可以通过 构造器 打印到 指定资源中 , 例如 , 打印到输出流 , 字符串 ,文件

image-20220915164702926
public class _07 {
    public static void main(String[] args) throws FileNotFoundException {
        PrintStream printStream = System.out;
        printStream.print(123);//输出123
        printStream.write(123);//输出123对应的acs
        //用println底层就是write,但仍旧有不同
        /*
          public void print(int i) {
               write(String.valueOf(i));
          }

         */
        PrintStream printStream = new PrintStream(new 								FileOutputStream("d:\\a.txt"));
        printStream.println(12311);
//输出到文件
        printStream.close();



    }
}

steam.out

​ steam.out 是字节打印流 , 可以直接给 printstream , 默认打印在显示器上 , 可以修改打印的位置

public class _07 {
    public static void main(String[] args) throws FileNotFoundException {
        System.setOut(new PrintStream("d:\\a.txt"));
        System.out.println(12);//输出到文件
    }
}

printwriter

​ 字符打印流 , 继承writer

properties类

​ 用来写配置文件 , 更加灵活 , 更加方便

image-20220915204359450

properties 类是 hashtable 的子类 , 用于保存键值对

image-20220915210146019
posted @   卓亦苇  阅读(9)  评论(0编辑  收藏  举报
编辑推荐:
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
· AI与.NET技术实操系列(六):基于图像分类模型对图像进行分类
点击右上角即可分享
微信分享提示