14_IO_其他流

文章目录

  • 数据流
    • 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

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

八大算法排序@快速排序、递归版本一(C语言版本)

目录 快速排序版本一概念算法思想一二三 快排步骤代码实现时间复杂度空间复杂度特性总结 快速排序版本一 概念 快速排序&#xff08;Quicksort&#xff09;是一种高效的排序算法&#xff0c;它是由英国计算机科学家 Tony Hoare 在1960年提出的。快速排序是基于分治&#xff08…

STM32深入系列02——BootLoader分析与实现

文章目录 1. STM32程序升级方法1.1 ST-Link / J-link下载1.2 ISP&#xff08;In System Programing&#xff09;1.3 IAP&#xff08;In Applicating Programing&#xff09;1.3.1 正常程序运行流程1.3.2 有IAP时程序运行流程 2. STM32 Bootloader实现2.1 方式一&#xff1a;Boo…

西电期末1026.删除特定字符后排序输出

一.题目 二.分析与思路 题目名字很有意思&#xff0c;先删除后排序&#xff0c;难死了&#xff0c;还是先排序后删除简单吧&#xff1f;注意字符串里有空格&#xff0c;前面提到过了&#xff1a;只能用fgets!! 三.代码实现 #include<bits/stdc.h>//万能头 #define MAX…

SpringBoot-项目引入Redis依赖

在使用Spring Boot开发应用时&#xff0c;可以使用Redis来实现缓存、分布式锁等功能。在编写业务逻辑代码时&#xff0c;可以通过注入RedisTemplate或StringRedisTemplate对象来操作Redis&#xff0c;如存取数据、设置过期时间、删除数据等。同时&#xff0c;还可以使用Redis的…

西电期末1027.判断同构数

一.题目 二.分析与思路 不用把他转成字符串再转成数字之类的&#xff0c;用数学解决就好&#xff01;找出一个数的最后位就是将其对求余啊&#xff0c;找一个数有几位以前也有过啊&#xff0c;那不就过了嘛&#xff01; 三.代码实现 #include<bits/stdc.h>//万能头 in…

Windows.OpenSSL生成ssl证书配置到nginx

一、下载OpenSSL程序安装 到E:\soft\OpenSSL-Win64 二、打开一个CMD控制台窗口&#xff0c;设置好openssl.cnf路径 E: cd E:\soft\OpenSSL-Win64\bin set OPENSSL_CONFE:\soft\OpenSSL-Win64\bin\openssl.cnf 三、在当前目录 E:\soft\OpenSSL-Win64\bin 里创建两个子目录 m…

MySQL 8.0 InnoDB Tablespaces之Temporary Tablespaces(临时表空间)

文章目录 MySQL 8.0 InnoDB Tablespaces之Temporary Tablespaces&#xff08;临时表空间&#xff09;会话临时表空间会话临时表空间的磁盘分配和回收会话临时表空间的创建创建临时表和查看临时表信息会话临时表空间相关的设置参数innodb_temp_tablespaces_dir 全局临时表空间查…

CentOS安装gcc及g++

目录 一、在线安装 二、离线安装 1、收集对应.rpm文件 2、rpm文件上传 3、在该目录下执行安装命令 3、测试 一、在线安装 联网安装比较简单只需使用如下命令即可 yum install gcc yum install gcc-c 二、离线安装 1、收集对应.rpm文件 &#xff08;1&#xff09;、解压…

OS_lab——保护模式之GDT、 Descriptor、Selector、GDTR 及其之间关系

1. 保护模式的相关数据结构 保护模式必要的数据结构定义 • GDT&#xff1a;即为 Global Descriptor Table&#xff08;全局描述符表&#xff09;&#xff0c;又称段描述符表&#xff0c; 为保护模式下的一个数据结构。其中包含多个 descriptor&#xff0c;定义了段的起始地…

pyinstaller生成的exe文件启动时间漫长的原因

加-F慢的原因是&#xff0c;pyinstaller把所有资源文件包括python解释器的依赖文件和库都打包到exe一个文件中&#xff0c;用户打开时&#xff0c;pyinstaller需要先执行一边解压操作&#xff0c;把依赖文件全部解压出来。慢就慢在这里。 如果不加-F&#xff0c;你会发现那些文…

STL标准库与泛型编程(侯捷)笔记3

STL标准库与泛型编程&#xff08;侯捷&#xff09; 本文是学习笔记&#xff0c;仅供个人学习使用。如有侵权&#xff0c;请联系删除。 参考链接 Youbute: 侯捷-STL标准库与泛型编程 B站: 侯捷 - STL Github:STL源码剖析中源码 https://github.com/SilverMaple/STLSourceCo…

常用服务器管理面板整理汇总

服务器管理面板是用于管理和控制服务器的软件&#xff0c;可以帮助管理员更轻松地进行服务器管理和维护。以下是几种常用的服务器管理面板&#xff1a; 1、宝塔面板【官网直达】 宝塔面板是一款服务器运维管理软件&#xff0c;支持Windows和Linux等操作系统&#xff0c;提供了…

《动手学深度学习》学习笔记 第6章 卷积神经网络

本系列为《动手学深度学习》学习笔记 书籍链接&#xff1a;动手学深度学习 笔记是从第四章开始&#xff0c;前面三章为基础知道&#xff0c;有需要的可以自己去看看 关于本系列笔记&#xff1a; 书里为了让读者更好的理解&#xff0c;有大篇幅的描述性的文字&#xff0c;内容很…

TypeScript 从入门到进阶之基础篇(六) 类型(断言 、推论、别名)| 联合类型 | 交叉类型

系列文章目录 TypeScript 从入门到进阶系列 TypeScript 从入门到进阶之基础篇(一) ts基础类型篇TypeScript 从入门到进阶之基础篇(二) ts进阶类型篇TypeScript 从入门到进阶之基础篇(三) 元组类型篇TypeScript 从入门到进阶之基础篇(四) symbol类型篇TypeScript 从入门到进阶…

鱼类识别Python+深度学习人工智能+TensorFlow+卷积神经网络算法

一、介绍 鱼类识别系统。使用Python作为主要编程语言开发&#xff0c;通过收集常见的30种鱼类&#xff08;‘墨鱼’, ‘多宝鱼’, ‘带鱼’, ‘石斑鱼’, ‘秋刀鱼’, ‘章鱼’, ‘红鱼’, ‘罗非鱼’, ‘胖头鱼’, ‘草鱼’, ‘银鱼’, ‘青鱼’, ‘马头鱼’, ‘鱿鱼’, ‘鲇…

如何批量自定义视频画面尺寸

在视频制作和编辑过程中&#xff0c;对于视频画面尺寸的调整是一项常见的需求。有时候&#xff0c;为了适应不同的播放平台或满足特定的展示需求&#xff0c;我们需要对视频尺寸进行批量调整。那么&#xff0c;如何实现批量自定义视频画面尺寸呢&#xff1f;本文将为您揭示这一…

github action

https://www.bilibili.com/video/BV1PM411B7um/?spm_id_frompageDriver&vd_sourcefd0f4be6d0a5aaa0a79d89604df3154a workflow pipeline

PyTorch 进阶指南,这个宝典太棒了

最新写了很多关于 Pytorch 的文章&#xff0c;主要针对刚刚接触 Pytorch 的同学&#xff0c;文章我给大家列出来了&#xff0c;喜欢可以从0开始学习&#xff1a; 小白学 PyTorch 系列&#xff1a;这一次&#xff0c;我准备了 20节 PyTorch 中文课程小白学 PyTorch 系列&#x…

【深度deepin】深度安装,jdk,tomcat,Nginx安装

目录 一 深度 1.1 介绍 1.2 与别的操作系统的优点 二 下载镜像文件及VM安装deepin 三 jdk&#xff0c;tomcat&#xff0c;Nginx安装 3.1 JDK安装 3.2 安装tomcat 3.3 安装nginx 一 深度 1.1 介绍 由深度科技社区开发的开源操作系统&#xff0c;基于Linux内核&#xf…

学完 Pinia 再也不想用 vuex 真香啊!!!!

&#x1f495;Pinia 注册 ✔ vue3 与 Pinia 注册 import { createApp } from vue import { createPinia } from pinia import App from ./App.vueconst app createApp()app.use(createPinia()) app.mount(#app)✔ vue2 与 Pinia 注册 import Vue from vue import App from …