14_IO_其他流

news2024/11/16 2:38:38

文章目录

  • 数据流
    • DataOutputStream数据输出流
    • DataInputStream数据输入流
  • 打印流
    • PrintStream字节打印流
    • PrintWriter字符打印流
  • 标准输入输出流
    • 标准输入流
    • 标准输出流
  • 对象流(序列化与反序列化流)
    • ObjectOutputStream序列化流
    • ObjectInputStream反序列化流
  • RandomAccessFile随机访问文件流
  • NIO
    • NIO核心
    • Buffer
      • Buffer的实例化
      • buffer的存取数据
  • 总结


数据流

DataOutputStream数据输出流

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

构造方法

DataOutputStream(OutputStream out)        
// 创建一个新的数据输出流,将数据写入指定基础输出流。

成员方法

在这里插入图片描述

  • 每种数据类型都有1个对应的write方法

DataInputStream数据输入流

数据输入流允许应用程序以与机器无关方式从底层输入流中读取基本 Java 数据类型

构造方法

DataInputStream(InputStream in)       
// 使用指定的底层 InputStream 创建一个 DataInputStream。

成员方法

在这里插入图片描述

  • 每种数据类型都有1个对应的read方法

eg:

/*
通过数据流写数据
 */
 
// 1. 创建数据输出流对象
DataOutputStream dataOutputStream = new DataOutputStream(new FileOutputStream("a.txt"));

// 2. writeInt
dataOutputStream.writeInt(1000);

// 3. writeDouble
dataOutputStream.writeDouble(3.14);

// 4. close
dataOutputStream.close();

/*
通过数据流读取数据
 */

// 1. 创建数据输入流对象
DataInputStream dataInputStream = new DataInputStream(new FileInputStream("a.txt"));

// 2. readInt
int readint = dataInputStream.readInt();
System.out.println(readint);

// 3. readDouble
double readdouble = dataInputStream.readDouble();
System.out.println(readdouble);

// 4. close
dataInputStream.close();

注意事项

  • 读取的顺序要跟写的顺序保持一致

打印流

核心思想: 把不同的数据类型转换成String

需求

  • 定义一个类Printer
  • 定义成员变量OutputStream
  • 定义5个方法
    • int的方法 void printInt(int a)
    • int并且换行的方法 void printIntLn(int a)
    • double的方法 void printDouble(double a)
    • double并且换行的方法 void printDoubleLn(double a)
    • 写一个close方法 void close()

eg:


class Printer{
    // 定义成员变量OutputStream
    OutputStream out;

    public Printer(OutputStream out){
        this.out = out;
    }

    // 写int的方法  void printInt(int a)
    public void printInt(int a) throws IOException {
        // int 转换成 String
        String s = String.valueOf(a);
        out.write(s.getBytes());
    }

    // 写int并且换行的方法 void printIntLn(int a)
    public void printIntLn(int a) throws IOException{
        // int 转换成 String
        String s = String.valueOf(a);
        out.write(s.getBytes());
        out.write(System.lineSeparator().getBytes());
    }

    // 写double的方法  void printDouble(double a)
    public void printDouble(double a) throws IOException{
        // int 转换成 String
        String s = String.valueOf(a);
        out.write(s.getBytes());
    }

    // 写double并且换行的方法 void printDoubleLn(double a)
    public void printDoubleLn(double a) throws IOException{
        // int 转换成 String
        String s = String.valueOf(a);
        out.write(s.getBytes());
        out.write(System.lineSeparator().getBytes());
    }

    // 写一个close方法  void  close()
    public void close() throws IOException{
        out.close();
    }

}

PrintStream字节打印流

PrintStream 为其他输出流添加了功能,使它们能够方便地打印各种数据值表示形式

继承关系
在这里插入图片描述

构造方法


PrintStream(File file)        // 创建具有指定文件且不带自动行刷新的新打印流。

PrintStream(OutputStream out)       // 创建新的打印流。

PrintStream(OutputStream out, boolean autoFlush)      // 创建新的打印流。

PrintStream(String fileName)       // 创建具有指定文件名称且不带自动行刷新的新打印流。

成员方法

在这里插入图片描述

  • 每个数据类型有一个相对应的print方法

/*
使用字节打印流打印数据
 */

// 1. 创建字节打印流对象
PrintStream printStream = new PrintStream("a.txt");

// 2. 写 1000
printStream.print(1000);

// 3. 写 true
printStream.print(true);

// 4. close
printStream.close();

PrintWriter字符打印流

向文本输出流打印对象的格式化表示形式

构造方法


PrintWriter(File file)       // 使用指定文件创建不具有自动行刷新的新 PrintWriter。

PrintWriter(OutputStream out)  //  根据现有的 OutputStream 创建不带自动行刷新的新 PrintWriter。

PrintWriter(OutputStream out,  boolean autoFlush)    
// 通过现有的 OutputStream 创建新的  PrintWriter。

PrintWriter(String fileName)    //  创建具有指定文件名称且不带自动行刷新的新 PrintWriter。

PrintWriter(Writer out)    // 创建不带自动行刷新的新 PrintWriter。

PrintWriter(Writer out,  boolean autoFlush)     // 创建新 PrintWriter。

成员方法

在这里插入图片描述

  • 每个数据类型有一个相对应的print方法

eg:

// 1.
PrintWriter printWriter = new PrintWriter("a.txt");

// 2.
printWriter.println(100);
printWriter.print("a");

// 3.
printWriter.flush();

// 4.
printWriter.close();
    

打印流特点

  • 只能操作目的地,不能操作数据来源。
    • 没有与之相对应的输入流
  • 可以操作任意类型的数据
    • 任意类型的数据—>String(String.valueOf(不同类型的数据))
  • 如果启动了自动刷新,能够自动刷新。
    • autoFlush如果为 true,则 printlnprintfformat 方法将刷新输出缓冲区
    • 下面是println源码举例:
    public void write(String s) {
        write(s, 0, s.length());
    }
    
    private void newLine() {
        try {
            synchronized (lock) {
                ensureOpen();
                out.write(System.lineSeparator());
                if (autoFlush)
                    out.flush();
            }
        }
        catch (InterruptedIOException x) {
            Thread.currentThread().interrupt();
        }
        catch (IOException x) {
            trouble = true;
        }
    }
    
  • 可以操作文件的流
    • 构造方法里可以传File对象或者String fileName

标准输入输出流

标准输入流

  • System.in
  • 默认输入设备是键盘
  • 本质: InputStream 普通的字节输入流

标准输出流

  • System.out
  • 默认输出设备是显示器
  • 本质: PrintStream 字节打印流

注意事项

  • read方法是一个阻塞方法

eg:

需求:利用System.in 完成Scanner的nextLine()的功能


BufferedReader bufferedReader = new BufferedReader(
        new InputStreamReader(System.in));
// InputStreamReader是字节流和字符流的转换桥梁

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

bufferedReader.close();


对象流(序列化与反序列化流)

  • 序列化: 把对象数据转为二进制数据, 存到文件的过程
  • 反序列:(序列化的逆过程) :把二进制数据还原回对象数据的过程

ObjectOutputStream序列化流

  • ObjectOutputStream 将 Java 对象的基本数据类型和图形写入 OutputStream。
    可以使用 ObjectInputStream 读取(重构)对象。通过在流中使用文件可以实现对象的持久存储
    如果流是网络套接字流,则可以在另一台主机上或另一个进程中重构对象。
  • 只能将支持 java.io.Serializable 接口的对象写入流中,Serializable接口是一个空接口(跟cloneable接口是一样的), 起到标记的作用
  • writeObject 方法用于将对象写入流中

继承关系

在这里插入图片描述

构造方法

ObjectOutputStream(OutputStream out)  // 创建写入指定 OutputStream 的 ObjectOutputStream。

成员方法

writeObject(Object obj)      // 将指定的对象写入 ObjectOutputStream。

ObjectInputStream反序列化流

ObjectInputStream以前使用 ObjectOutputStream 写入的基本数据和对象进行反序列化

构造方法

ObjectInputStream(InputStream in)   //  创建从指定 InputStream 读取的 ObjectInputStream。

成员方法

readObject()     //  从 ObjectInputStream 读取对象。

eg:


public class Demo {
    public static void main(String[] args) throws IOException, ClassNotFoundException {
        /*
        使用对象流(序列化和反序列化)
        写入对象
        读取对象
         */

        // 序列化流操作

        // 1. 创建学生对象
        Student stu = new Student("zs",10);

        // 2. 创建序列化流的对象
        ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("a.txt"));

        // writeObject(Object obj)
        out.writeObject(stu);

        // close
        out.close();

        // 反序列化流操作

        // 1. 创建反序列化流对象
        ObjectInputStream in = new ObjectInputStream(new FileInputStream("a.txt"));

        // 2. readObject()
        Object o = in.readObject();
        System.out.println(o);

        // 3. close
        in.close();

    }
}

/*
java.io.NotSerializableException 没有实现Serializable接口
 */

class Student implements Serializable {
    String name;
    int age;

    // transient修饰不想被序列化的成员变量
    transient int score;
    static final long serialVersionUID = -7889256375299507710L;

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

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

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

注意事项

  • java.io.NotSerializableException
    • 没有实现Serializable接口
  • java.io.InvalidClassException: _18io03.com.cskaoyan._04serialize.Student; local class incompatible: stream classdesc serialVersionUID = -7889256375299507710, local class serialVersionUID = 7388140007375758175
    • 设置为:static final long serialVersionUID = -7889256375299507710L;
    • SerialVersionUID不匹配
  • transient修饰不想被序列化的成员变量,就是反序列化后看不到具体的值

RandomAccessFile随机访问文件流

  • RandomAccessFile 声明在java.io包下,但直接继承于java.lang.Object类,这个类既可以读也 可以写
  • 支持 “随机访问” 的方式,程序可以直接跳到文件的任意地方来读、写文件
    • 支持只访问文件的部分内容
    • 可以向已存在的文件后追加内容
  • RandomAccessFile 对象包含一个记录指针,用以标示当前读写处的位置。

构造方法

RandomAccessFile(File file, String mode)   
// 创建从中读取和向其中写入(可选)的随机访问文件流,该文件由 File 参数指定。

RandomAccessFile(String name, String mode)   
// 创建从中读取和向其中写入(可选)的随机访问文件流,该文件具有指定名称。

注意
创建 RandomAccessFile 类实例需要指定一个 mode 参数,该参数指 定 RandomAccessFile 的访问模式(介绍2种常用的):

  • r: 以只读方式打开(不会创建文件,读取已经存在的文件)
  • rw:可读可写(文件不存在会创建,存在不会创建)

成员方法

  • 常规的readwrite方法
  • RandomAccessFile 类对象可以自由移动记录指针
    • long getFilePointer():获取文件记录指针的当前位置
    • void seek(long pos):将文件记录指针定位到 pos 位置

eg:

@Test
public void Test() throws IOException {
    File file = new File("D:\\java_test\\a.txt");

    RandomAccessFile randomAccessFile = 
    new RandomAccessFile("D:\\java_test\\a.txt", "rw");

    // 获取当前文件的指针
    long filePointer = randomAccessFile.getFilePointer();

    // write写数据
    randomAccessFile.write("abjdefg".getBytes());

    // 从文件的某个位置进行写数据
    // 移动指针
    randomAccessFile.seek(4);
    randomAccessFile.write("999".getBytes());

    // 从文件的末尾开始写
    randomAccessFile.seek(file.length());
    randomAccessFile.write("1998".getBytes());

    // 从文件中读取数据
    randomAccessFile.seek(0);
    byte[] bytes = new byte[1024];
    int readCount = randomAccessFile.read(bytes);
    System.out.println(new String(bytes,0,readCount));

    randomAccessFile.close();
}

NIO

  • Java NIO(New IO, Non Blocking IO),可以替代标准的Java IO API。
  • NIO与原来的IO有同样的作用和目的,但是使用的方式完全不同
  • NIO支持面向缓冲区buffer的、基于通道channel的IO操作
  • NIO将以更加高效的方式进行文件的读写操作。
IONIO
面向流(Stream Oriented)面向缓冲区(块)(Buffer Oriented)
阻塞IO(Blocking IO)非阻塞IO(Non Blocking IO)

NIO核心

  • Buffer
  • Channel

Channel负责传输,Buffer负责存储

Buffer

除了boolean之外的基本数据类型都有1个对应的Buffer
比如 IntBuffer 放int数据(除了boolean)

  • ByteBuffer 最常用

  • IntBuffer

  • ShortBuffer

  • LongBuffer

  • DoubleBuffer

  • FloatBuffer

  • CharBuffer
    在这里插入图片描述

Buffer的实例化

ByteBuffer为例:

public static ByteBuffer allocate(int capacity)

public static ByteBuffer allocateDirect(int capacity)

public static ByteBuffer wrap(byte[] array)

public static ByteBuffer wrap(byte[] array, int offset, int length)

eg:

    @Test
    public void Test2(){
        ByteBuffer allocate = ByteBuffer.allocate(10);
        System.out.println(allocate);

		
    }

在这里插入图片描述
其中

  • capacity

    • 表示Buffer最大数据容量,创建后不能更改.一旦Buffer满了,需要将其清空(通过读数据或者清除数据, 才能继续往里写数据)
  • limit

    • 是第一个不应该读取或写入的元素的索引。缓冲区的限制不能为负,并且不能大于其容量
    • 写数据到Buffer时,limit表示可对Buffer最多写入多少个数据(写模式下 limit = capacity)
    • 读数据时,limit表示Buffer里有多少可读数据,可以读取到之前写入的所有数据(limit被设置成已写数据的数量,这个值在写模式下就是position)
  • position

    • 写数据时,position表示写入数据的当前位置,初始值为0.当数据写入到Buffer中后,position会向后移动到1个可插入数据的Buffer单元.position最大值可为capacity
    • 读数据时,position表示读入数据的当前位置,如position=2时,表示已经读入了2个值,或从第2个位置开始读取.通过flip()切换到读模式时position会被重置为0,当Buffer从position读入数据后,position会移动到下一个可读入的数据Buffer单元
  • mark

    • 跟reset()结合进行标记,通过Buffer中的mark()方法,指定一个Buffer的特定的position,之后可以通过reset()方法恢复到这个position.
  • 这4个属性遵循如下关系:

    • 0<=mark<=position<=limit<=capacity

buffer的存取数据

put操作(存)

put(byte b)   // 将给定的字节写入此缓冲区的当前位置,然后该位置递增 。  position+1

put操作


总结

类型字节输出流字节输入流字符输出流字符输入流
抽象基类OutputStreamInputStreamWriterReader
文件相关FileOutputStreamFileInputStreamFileWriterFileReader
缓冲相关BufferedOutputStreamBufferedInputStreamBufferedWriterBufferedReader
转换相关OutputStreamWriterInputStreamReader
数据相关DataOutputStreamDataInputStream
打印相关PrintStreamPrintWriter
对象相关ObjectOutpuStreamObjectInputStream

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1364467.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【Harmony OS - 网络请求】

在一个应用开发中&#xff0c;网络请求是必不可少的&#xff0c;我们一般用的fetch、axios来进行http请求&#xff0c;在鸿蒙中也可以通过createHppt来发生一个http请求&#xff0c;它们都是异步请求返回的Promise&#xff0c;下面我们将介绍’ohos.net.http’和axios这两种方式…

(21)Linux的文件描述符输出重定向

一、文件描述符 1、文件描述符的底层理解 在上一章中&#xff0c;我们已经把 fd 的基本原理搞清楚了&#xff0c;知道了 fd 的值为什么是 0,1,2,3,4,5... 也知道了 fd 为什么默认从 3 开始&#xff0c;而不是从 0,1,2&#xff0c;因为其在内核中属于进程和文件的对应关系。 …

Mysql SQL审核平台Yearning本地部署

文章目录 前言1. Linux 部署Yearning2. 本地访问Yearning3. Linux 安装cpolar4. 配置Yearning公网访问地址5. 公网远程访问Yearning管理界面6. 固定Yearning公网地址 前言 Yearning 简单, 高效的MYSQL 审计平台 一款MYSQL SQL语句/查询审计工具&#xff0c;为DBA与开发人员使用…

Python的基础练习题之学生管理系统

需求 使用Python基础写一个基于控制台的学生管理平台&#xff0c;里面功能分别是&#xff1a;1.录入学生信息2.查找学生信息3.删除学生信息4.修改学生信息5.排序6.统计学生总人数7.显示所有学生信息&#xff0c;要求数据存储在文件里。 代码 代码资源地址可以直接下载 效果图…

05 Ciso模拟器连接腾讯云物联网开发平台

Ciso声明&#xff1a;本篇文章基于使用腾讯云物联网平台连接自定义esp8266物联网设备(腾讯连连控制开关实现) - CSDN App改编 一、总体概览 功能描述&#xff1a; 使用腾讯连连小程序进行控制&#xff0c; Alarm&#xff08;警铃&#xff09;&#xff1a;开的时候&#xff…

【AI视野·今日Robot 机器人论文速览 第六十九期】Wed, 3 Jan 2024

AI视野今日CS.Robotics 机器人学论文速览 Wed, 3 Jan 2024 Totally 5 papers &#x1f449;上期速览✈更多精彩请移步主页 Daily Robotics Papers NID-SLAM: Neural Implicit Representation-based RGB-D SLAM in dynamic environments Authors Ziheng Xu, Jianwei Niu, Qingf…

实现在一个文件夹中找到特定名称特点格式的文件

当你要在一个文件夹中查找特定名称和格式的文件时&#xff0c;你可以使用 Python 的 os 和 fnmatch 模块。以下是一个简单的脚本示例&#xff0c;它可以在指定目录中查找文件&#xff1a; import os import fnmatchdef find_files(directory, pattern):"""在指…

C#使用栈方法遍历二叉树

步骤一&#xff1a;定义一个二叉树的节点类 定义一个二叉树的节点类&#xff0c;其中包含节点的值、左子节点和右子节点。 // 二叉树节点定义public class TreeNode{public int Value { get; set; } // 节点的值public TreeNode Left { get; set; } // 左子节点public TreeN…

Java Base64简单介绍

1. Base64工具 工具链接 2. Base64示例代码 public class Base64Demo {// 请注意&#xff0c;在处理二进制数据时&#xff08;例如图片或文件&#xff09;&#xff0c;不需要将字节数组转换为字符串再进行编码或解码&#xff0c;// 可以直接对字节数组进行Base64操作。上述…

Python基础知识总结3-面向对象进阶知识

面向对象三大特征介绍 继承子类扩展父类语法格式关于构造函数&#xff1a;类成员的继承和重写查看类的继承层次结构 object根类dir() 查看对象属性重写 __str__() 方法 多重继承MRO方法解析顺序super()获得父类定义多态特殊方法和运算符重载特殊属性 对象的浅拷贝和深拷贝组合_…

学习笔记——C++一维数组

1&#xff0c;一维数组的定义方式 三种定义方式 1&#xff0c;数据类型 数组名[ 数组长度 ]&#xff1b; 2&#xff0c;数据类型 数组名[ 数组长度 ]{值1&#xff0c;值2&#xff0c;值3 ……}&#xff1b;//未说明的元素用0填补 3&#xff0c;数据类型 数组名[ ]{值1&…

【数据仓库与联机分析处理】数据仓库工具Hive

目录 一、Hive简介 &#xff08;一&#xff09;什么是Hive &#xff08;二&#xff09;优缺点 &#xff08;三&#xff09;Hive架构原理 &#xff08;四&#xff09;Hive 和数据库比较 二、MySQL的安装配置 三、Hive的安装配置 1、下载安装包 2、解压并改名 3、配置环…

嵌入式培训机构四个月实训课程笔记(完整版)-Linux系统编程第三天-Linux进程练习题(物联技术666)

更多配套资料CSDN地址:点赞+关注,功德无量。更多配套资料,欢迎私信。 物联技术666_嵌入式C语言开发,嵌入式硬件,嵌入式培训笔记-CSDN博客物联技术666擅长嵌入式C语言开发,嵌入式硬件,嵌入式培训笔记,等方面的知识,物联技术666关注机器学习,arm开发,物联网,嵌入式硬件,单片机…

React 中条件渲染的 N 种方法

本文作者系360奇舞团前端开发工程师 条件渲染在React开发中非常重要的功能&#xff0c;它允许开发人员根据条件控制渲染的内容&#xff0c;在创建动态和交互式用户界面方面发挥着至关重要的作用&#xff0c;本文总结了常用的的条件渲染方法。 1.If-else if-else是一种控制流程的…

rime中州韵小狼毫 敏感词脱敏滤镜

快速录入&#xff0c;是任何一个输入法&#xff0c;以及输入人员&#xff08;无论是否专业&#xff09;的追求目标之一。现实中&#xff0c;由于各种输入法在录入文本时&#xff0c;都无法完全避免重码的问题&#xff0c;所以在输入过程中都或多或少的需要进行选字/选词操作。这…

OpenSource - 基于Netty的网络扩展库HServer

文章目录 概述官网Hserver的理念特点原理图代码案例HelloWorld 概述 HServer是一个基于Netty开发网络扩展库.使用插件方式来扩展我们的业务 HServer提供 web,gateway,rpc 等插件 同时用户也可以自定义插件&#xff0c;来完成各种各样的业务场景。 官网 https://gitee.com/HSe…

认识Git

&#x1f30e;初识Git 初识Git 什么是Git Git的安装       Centos平台安装Git       Ubuntu平台安装Git Git的基本操作       创建远程仓库       配置Git 认识工作区、暂存区与版本库       添加文件到暂存区       将暂存区文件提交至本…

JVM中对象的创建

一.JVM运行流程 JVM向操作系统申请内存&#xff0c;初始化运行时数据区&#xff0c;接下来装载使用的类&#xff0c;执行类里面相应方法的时候为当前虚拟机栈压入一个栈帧&#xff0c;方法执行完成后栈帧出栈&#xff0c;进行垃圾回收。 二.JVM中对象的创建过程 符号引用&…

三维模型数据的几何坐标变换的点云重建并行计算技术方法分析

三维模型数据的几何坐标变换的点云重建并行计算技术方法分析 倾斜摄影三维模型数据的几何坐标变换与点云重建并行计算技术的探讨主要涉及以下几个方面&#xff1a; 1、坐标系定义与转换&#xff1a;在进行坐标变换前&#xff0c;需要确定各个参考系的定义并实现坐标系之间的转…

区间预测 | Matlab实现CNN-LSTM-KDE的卷积长短期神经网络结合核密度估计多变量时序区间预测

区间预测 | Matlab实现CNN-LSTM-KDE的卷积长短期神经网络结合核密度估计多变量时序区间预测 目录 区间预测 | Matlab实现CNN-LSTM-KDE的卷积长短期神经网络结合核密度估计多变量时序区间预测效果一览基本介绍程序设计参考资料 效果一览 基本介绍 1.CNN-LSTM-KDE多变量时间序列区…