当前位置: 首页 > news >正文

java-io流

Java-I/O流

读取和数据的一种解决方案。

1.1什么是IO流

I指的是in,O是out,也就是输入输出,指的是程序和外部之间的数据传递,通过流的方式。

那什么是流呢?

这是一种抽象的概念,一系列字节以队列的方式,先进先出,我们知道,程序运行在内存当中,而想要持久化记忆数据,就需要我们在内存和存储设备之间搭建一个数据传输的通道。

1.2流的分类

根据不同的分类方式,我们可以将流分为不同的方式:

  1. 方向:输入流和输出流 (这里的输入输出的对象相对于内存来收,也就是运行的程序。)
  2. 单位:字节流和字符流 (字节流可以处理所有类型的文件,而字符流只能处理纯文本文件(txt,md))
  3. 功能:节点流和处理流

纯文本文件,用windows自带的记事本打开并且能读懂的文件。

1.3字节流

字节流由两个抽象类InputStream和OutputStream继承于Objections类

1.3.1FileInputStream

接下介绍Fileinputstream常用的方法:

方法
read()返回输入流中下一字节的数据(0~255),如果是-1.则表示文件结束。
read(byte b[ ])从输入流中读取一些字符储存到数组b中,最多读取b.length字节数,没有则返回-1
close()关闭输入流释放相关系统资源
readAllBytes()读取输入流中的所有字节,返回字节数组
available()返回输入流中利用读取的字节数
public long skip(long n)跳过输入流中的指定字节数,不读取这些字节

案例:通过Fileinputstream打印数据

 public static void main(String[] args)  {try (InputStream fis = new FileInputStream("input.txt")) {long skip = fis.skip(2);//跳过两个字节,skip=2(txt实际大小大于2,否则返回0或1.)int content;while ((content = fis.read()) != -1) {System.out.print((char) content);}}catch (IOException e) {e.printStackTrace();}}

注意

创建对象时:

  1. 文件不存在时就直接报错。

写入数据时:

  1. 一次读一个字节,读出来的数据在ASCII对应的数字,注意编码和解码方式。
  2. 读到文件末尾,read方法返回-1。

释放资源:

每次使用完流之后都要释放资源。

1.3.2FileOutputStream

介绍FileOutputStream常用的方法:

方法名描述
void write(int b)将指定的字节写入此文件输出流中。
void write(byte[] b)将指定的字节数组全部写入此文件输出流中。
void write(byte[] b, int off, int len)从指定的字节数组写入一部分数据(从偏移量off开始,长度为len)到此文件输出流中。
void flush()刷新此输出流并强制任何缓冲的输出字节被写出。通常不需要调用,除非使用了带有缓冲的装饰器如BufferedOutputStream
void close()关闭此文件输出流并释放与此流有关的所有系统资源。
final FileChannel getChannel()返回与此文件输出流关联的唯一 FileChannel 对象。
FileDescriptor getFD()返回与该流相关的文件描述符对象。

可以把程序中的数据写到本地文件中,是字节流的基本流,书写分为三部,创建对象,写入数据,释放资源

当我们创建FileOutputStream对象时,具体流程如下:

FileOutputStream fos = new FileOutputStream("C:\\output.txt"); //创建对象,里面可以是路径也可以file对象
fos.write(97);//写入一个字节
fos.close();//关闭输出流

注意

创建对象时:

  1. 参数可以是字符串表示的路径或者是file对象。
  2. 如果文件不存在会创建一个新的文件,要保证父级路径存在。
  3. 如果文件存在,则会清空文件。可以在创建是添加append属性。

写入数据时:

  1. write方法的参数是整数,写入本地文件是对应的ASCII对应的字符。

  2. '值’直接传入数据也可。

释放资源:

每次使用完流之后都要释放资源。

拓展

换行

输入换行的时候,不同操作系统对应不同换行符

windows:\r\n

Linux"\n

MAc:\r

在window操作系统中,Java对换行符做了优化,\r或\n都可,做了补全处理,但是建议补全。

案例:换行符的使用

package io;import java.io.FileOutputStream;
import java.io.IOException;public class demo1 {public static void main(String[] args) throws IOException {try (FileOutputStream fos = new FileOutputStream("a.txt")) {String str = "hello world1";byte[] bytes = str.getBytes();fos.write(bytes);String wrap="\r\n";fos.write(wrap.getBytes());String str2 = "hello world2";byte[] bytes2 = str2.getBytes();fos.write(bytes2);            }//自动会执行fos.close();}
}
1.3.3练习-拷贝文件

要求:把某个文件拷贝到当前目录下(文件不要太大)

    FileInputStream fis=new FileInputStream("a.txt");FileOutputStream fos=new FileOutputStream("b.txt");int i;while((i=fis.read())!=-1){fos.write(i);}fis.close();fos.close();

当我们通过拷贝的时候,发现一次循环只能读取一个字节那么如果是拷贝视频,那么是不是要循环次数将会很多,有没有解决方法呢?换句话说,在一次的拷贝过程中,能不能拷贝多个字节。

解决方案,通过read,并传入字节数组,我们人为开辟一个空间,将字符存入,这样子增加了效率,减少了时间。

    FileInputStream fis=new FileInputStream("a.txt");FileOutputStream fos=new FileOutputStream("b.txt");byte[] b=new byte[1024];//每次读多少个字节数据,和开辟的数组大小有关int len;  //read返回值是返回本次读到多少个字节数据while((len=fis.read(b))!=-1){fos.write(b,0,len);//将读到的数据覆盖到原数组}fis.close();fos.close();
1.3.4try…catch 异常处理机制(了解即可)

到我们使用字节流是,他会让我们抛出异常,我们可以throws IOException 或者使用try…catch包裹。

try{FileOutputStream fos=new FileOutputStream("b.txt");fos.write(97)
}
catch(IOException){e.printStackTrace();
}finally{fos.close(); //不管有无异常,都执行
}

在版本更新呢过程中,关于资源的释放存在三种机制

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

如果我们用jdk9的方式来写拷贝案例的话,那么代码如下,在未来我们会直接抛出异常。

 FileInputStream fis=null;FileOutputStream fos=null;try {fis=new FileInputStream("a.txt");fos=new FileOutputStream("b.txt");int len;byte[] b=new byte[1024];while ((len= fis.read(b))!=-1){fos.write(b,0,len);}}catch (IOException e){e.printStackTrace();}finally {if (fos!=null){try {fos.close();}catch (IOException e){e.printStackTrace();}if (fis!=null){try {fos.close();}catch (IOException e){e.printStackTrace();}}   }}

1.4字符流

1.4.1编码

在了解字符流之前,我们需要对编码和乱码等有初步的了解。

在计算机中,,任意数据都是以二进制的方式来存储的,存储单位是一个字节,在ASCII中,一个英文占一个字符,而windows(简体中文),默认使用GBK,以存储英文为例,a字符查询ASCII表对应的是110 0001,用先导0补齐,0110 0001。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

字符流原理解析

  1. 创建字符输入流对象

​ 底层:关联文件,创建缓冲区(长度8192的字节数组bb,通过断点测试也可以得出)。

  1. 读取数据

​ 底层:1. 缓冲区中是否有数据可以读取

​ 缓冲区没有数据:就从文件中读取数据,装到缓冲区中,每次尽可能的将缓冲区填满,如果文件中没有数据,则返回-1。

​ 缓冲区存在是数据:就从缓冲区中读取数据。

空惨的read方法:一次读取一个字符,遇到中文一次读多个字节(根据不同的编码),把字节解码并转成十进制返回。

有参的read方法:把读取字节,解码和强转三步和并了,强转之后的字符放在数组中。避免返回的是十进制,更加易懂。

1.5字节缓冲流

1.5.1基本使用

学完四个基本流,接下来学习高级流,在基本流的基础进行封装,基本流的效率普遍的较低,那么前面我们采用缓冲区的方法,Java当中也为我们封装好了。当然除了缓冲流,还有转换流,序列化流,打印流等。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

底层自带了长度为8192的缓冲区提高性能,但是本质上还是对基本流进行包装。

方法名称说明
public BufferedInputStream(InputStream is)把基本流进行封装,提高读取性能
public BufferedOutputStream(OutputStream io)把基本流进行封装,提高写性能

案例:拷贝(也可以通过创建字节数字一次操作多个字节)

package io;import java.io.*;public class demo1 {public static void main(String[] args) throws IOException {BufferedInputStream bis = new BufferedInputStream(new FileInputStream("a.txt"));BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("b.txt"));int c;while ((c = bis.read()) != -1) {bos.write(c);}bis.close();//释放代码,只需要关闭高级流,在底层会给我们关闭基本流bos.close();}
}
1.5.2原理

创建缓冲流的时候,会在内存中开辟两个区域,存放大小为8192的字节数组,创建一个变量b,将两个缓冲区的数据循环传递,那一次还是一个字节的搬运,为什么提高了效率,他其实是减少与存储设备打交道的时间,内存的运行效率其实快得多。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

1.6字符缓冲流

案例:利用字符缓冲流写入数据

 BufferedWriter bw = new BufferedWriter(new FileWriter("b.txt"));bw.write("<UNK>");bw.newLine();bw.write("<UNK>");bw.newLine();bw.close();

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

1.7转换流

减少与存储设备打交道的时间,内存的运行效率其实快得多。

[外链图片转存中…(img-WRbUKpJE-1752158721772)]

1.6字符缓冲流

案例:利用字符缓冲流写入数据

 BufferedWriter bw = new BufferedWriter(new FileWriter("b.txt"));bw.write("<UNK>");bw.newLine();bw.write("<UNK>");bw.newLine();bw.close();

[外链图片转存中…(img-btyyCVHQ-1752158721773)]

1.7转换流

http://www.dtcms.com/a/273343.html

相关文章:

  • 对象序列化与反序列化
  • 【PyTorch】PyTorch 自动微分与完整手动实现对比
  • vue3 element plus table 使用固定列,滑动滚动会错位、固定列层级异常、滑动后固定列的内容看不到了
  • Java多线程 V1
  • AIStarter 3.2.0正式上线!高速下载+离线导入+一键卸载新功能详解【附完整使用教程】✅ 帖子正文(字数:约 400 字)
  • 静态路由综合实验
  • WiFi技术深度研究报告:从基础原理到组网应用与未来演进
  • python+django/flask基于微信小程序的农产品管理与销售APP系统
  • CTFshow-PWN-栈溢出(pwn62-pwn64)
  • JAVA面试宝典 -《新潮技术:协程与响应式编程实践》
  • 【Ubuntu】编译sentencepiece库
  • next.js打包后的前端资源如何进行部署和访问,为什么没有index.html
  • Vue响应式原理六:Vue3响应式原理
  • Java 17 新特性解析:密封类与模式匹配的完美协作
  • 01背包问题总结
  • 三维旋转沿轴分解
  • AWS ECS任务角色一致性检查与自动修复工具完全指南
  • LVGL学习笔记-----进度条控件(lv_bar)
  • Java结构型模式---桥接模式
  • 什么?不知道 MyBatisPlus 多数据源(动态数据源)干什么的,怎么使用,看这篇文章就够了。
  • AI探索 | 豆包智能助手跟扣子空间(AI办公助手)有什么区别
  • Ranger框架的发展历程
  • Windows系统DLL、运行库、DirectX等DLL丢失等异常状态
  • 数组的应用示例
  • 【Python进阶篇 面向对象程序设计(7) Python操作数据库】
  • 《测试开发:从技术角度提升测试效率与质量》
  • 《Revisiting Generative Replay for Class Incremental Object Detection》阅读笔记
  • 3D lidar目标跟踪
  • PyTorch自动微分:从基础到实战
  • Linux C 文件基本操作