什么流读取MultipartFile_一篇彻底读懂java中的IO流!

2023-12-02 16:50

本文主要是介绍什么流读取MultipartFile_一篇彻底读懂java中的IO流!,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

一、IO概念

• I/O 即输入Input/ 输出Output的缩写,其实就是计算机调度把各个存储中(包括内存和外部存储)的数据写入写出的过程;

• java中用“流(stream)”来抽象表示这么一个写入写出的功能,封装成一个“类”,都放在http://java.io这个包里面。

二、来理解“流”是什么?

通过“流”的形式允许java程序使用相同的方式来访问不同的输入/输出源。stream是从起源(source)到接收的(sink)的有序数据。我们这里把输入/输出源对比成“水桶”,那么流就是“管道”,这个“管道”的粗细、单向性等属性也就是区分了不同“流”的特性。

0b215670-9312-eb11-8da9-e4434bdf6706.png

三、IO流的分类

可以从三个不同的维度进行分类:

• 1、按照流的方向(输出输入都是站在程序所在内存的角度划分的)

• 输入流:只能从中读取数据【主要由InputStream和Reader作为基类】

• 输出流:只能向其写入数据【主要由outputStream和Writer作为基类】

在下图中,从磁盘读取数据到内存是输入流,从client读取数据到server是输入流;同样,把内存数据写到磁盘是输出流,把server数据写到client是输出流

0d215670-9312-eb11-8da9-e4434bdf6706.png

• 2、按照流的操作颗粒度划分

• 字节流:以字节为单元,可操作任何数据【主要由InputStream和outPutStream作为基类】

• 字符流:以字符为单元,只能操作纯字符数据,比较方便【主要由Reader和Writer作为基类】

• 3、按照流的角色划分

• 节点流:可以从/向一个特定的IO设备(如磁盘,网络)读/写数据的流,也叫【低级流,主要由】

• 处理流:用于对一个已存在的流进行连接和封装,通过封装后的流来实现数据的读/写功能,也叫【高级流】

下图中可以看出来,处理流就是在基础的字节流上,进行了封装,增加了特定的功能,使得传输更适合特定的场景。

0f215670-9312-eb11-8da9-e4434bdf6706.png

四、流的原理以及一共有多少IO流

• 1、流的原理解析

流其实我们可以想象成一个“水管”,源端和目的端就是两个“水桶”,数据是通过这个“水管”进行流动传输的,以InputStream和Reader为例,水管的每个“水滴”就是具体的数据,如果是字节流,那么一个“水滴”就是一个字节,如果是字符流,那么一个“水滴”就是一个字符。

当创建一个流对象的时候,如fis=new FileInputStream(“…xxxx.txt”),记录指针来表示当前正准备从哪个“水滴”开始读取,每当程序从InputStream或者Reader里面取出一个或者多个“水滴”后,记录指针自定向后移动;除此之外,InputStream和Reader里面都提供了一些方法来控制记录指针的移动。

12215670-9312-eb11-8da9-e4434bdf6706.png

如果是处理流的话,就相当于在这个水管上面装了一些“控制阀门”,最终用户只要关心“阀门”具备的能力就行

13215670-9312-eb11-8da9-e4434bdf6706.png

• 2、java中所有流汇总

http://java.io中子类有40个“流”类,我们用以下表格来综合划分,当然这些流你不用都去花时间一个一个看过来,我们只要熟悉掌握几类常用的“流”就足够了,后续项目中如果用到陌生的“流”,知道原理的话可以快速地去检索学习下就ok了。

16215670-9312-eb11-8da9-e4434bdf6706.png

上图中我们可以看到,InputStream/Reader,OutputStream/Writer 是整个I/O体系的基类,他们本身不能用来创建实例,下面开始逐一对常见的I/O类进行实战

五、常见IO流的实战

1、访问操作文件(FileInputStream/FileReader ,FileOutputStream/FileWriter)

FileInputStream中包含以使用FileInputStream为例,类中包含的属性及方法,我们可以在线查看jdk的api文档http://tool.oschina.net/apidocs/apidoc?api=jdk-zh),下面只是截图了FileInputStream的构造方法:

17215670-9312-eb11-8da9-e4434bdf6706.png

1)使用FileInputStream,从文件读取数据

import java.io.*;
public class TestFileImportStream {public static void main(String[] args) {int b=0;FileInputStream in = null;try {in =new FileInputStream("C:Users41639DesktopjavaFileTextsrcTestFileImportStream.java");}catch(FileNotFoundException e){System.out.println("file is not found");System.exit(-1);}try {long num=0;while ((b=in.read())!=-1) {System.out.println((char)b);num++;}in.close();System.out.println();System.out.println("共读取了"+num+"个字节");}catch(IOException e) {System.out.println("IO异常,读取失败");System.exit(-1);}}

2)使用FileOutputStream,往文件里写数据

import java.io.*;
public class TextFileOutputStream {public static void main(String[] args) {int b=0;FileInputStream in = null;FileOutputStream out = null;try {in =new FileInputStream("C:Users41639DesktopjavaFileTextsrcTestFileImportStream.java");out=new FileOutputStream("C:Users41639Desktopjavatempout.java");}catch(FileNotFoundException e){System.out.println("file is not found");System.exit(-1);}try {while ((b=in.read())!=-1) {out.write(b);}in.close();out.close();}catch(IOException e) {System.out.println("IO异常,读取失败");System.exit(-1);}System.out.println("文件复制完成");}}

PS:大家也可以尝试使用FileReader、FileWriter,看看和FileInputStream、FileOutputStream有什么区别

2、缓存流的使用(BufferedInputStream/BufferedOutputStream,BufferedReader/BufferedWriter)

import java.io.*;
public class TestBufferStream {public static void main (String[] args) throws IOException{BufferedInputStream bis=null;BufferedOutputStream bos=null;try {FileInputStream fis = new FileInputStream("C:Users41639DesktopjavaFileTextsrcTestFileImportStream.java");FileOutputStream fos = new FileOutputStream("C:Users41639Desktopjavatempout2.java");bis = new BufferedInputStream(fis);bos = new BufferedOutputStream(fos);byte[] b = new byte[1024];int off=0;while ((off=bis.read(b))>0) {bos.write(b,0,off);}bis.close();bos.close();}catch (IOException e) {e.printStackTrace();}finally {bis.close();bos.close();}		}
}

从代码中可以看到,他们最基本的其实也是FileInputStream和FileOutputStream,在这个“流”的基础上,又加了缓存的功能流BufferedInputStream和BufferedOutputStream。相对比较好理解。

3、转换流的使用(InputStreamReader/OutputStreamWriter)

字面意思理解,转化流就是用来转化的,那么到底是什么转什么呢?我们可以通过以下的例子来熟悉。读取键盘输入的每一行内容,并写入到文本中,直到遇到over行结束输入

import java.io.*;
public class TransStreamTest {public static void main(String[] args) throws IOException {BufferedReader br = new BufferedReader(new InputStreamReader(System.in));BufferedWriter bw = new BufferedWriter(new FileWriter("C:Users41639Desktopjavatemptest1031.txt"));String line =null;while ((line=br.readLine())!=null) {if ("over".contentEquals(line)) {break;}bw.write(line);bw.newLine();bw.flush();}bw.close();br.close();}}

PS:readLine()方法在进行读取一行时,只有遇到回车(r)或者换行符(n)才会返回读取结果,这就是“读取一行的意思”,有兴趣的同学查看readLine()源码

4、对象流的使用(FileInputStream/ObjectOutputStream)

前面讲了字节和字符流,包括封装在他们上面的处理流,那么我们想,在程序设计的过程中,我们都是用类和对象来描述定义,能不能直接把对象进行传输。答案当然是肯定的,对象流其实就是一种特殊的处理流水,也是在基础的字节流上去作封装。【可以应用于游戏存盘】

下面程序使用一个对象流,把对象直接写到文件中

import java.io.*;
public class ObjectStreamTest {public static void main(String[] args) throws Exception{try {Person P=new Person("Jeccica",26);FileOutputStream fos=new FileOutputStream("C:UsersadminDesktopJavatemp22.txt");ObjectOutputStream oos=new ObjectOutputStream(fos);oos.writeObject(P);oos.flush();oos.close();}catch(FileNotFoundException e) {e.printStackTrace();}catch(IOException e) {e.printStackTrace();}			FileInputStream fis=new FileInputStream("C:UsersadminDesktopJavatemp22.txt");ObjectInputStream ois=new ObjectInputStream(fis);Person P2=(Person)ois.readObject();System.out.println(P2.name+"的年龄为"+P2.age);}}class Person implements Serializable{String name=null;int age=0;Person(String _name,int _age){name=_name;age=_age;}
}

5、字节数组流的使用(ByteArrayInputStream/ByteArrayOutputStream)【通常结合数据流DataInputStream/DataOutputStream】

我们分析了常见的节点流和常见的处理流等,经常而言我们都是针对文件的操作,然后带上缓冲的节点流进行处理,但有时候为了提升效率,我们发现频繁的读写文件并不是太好,那么于是出现了字节数组流,即存放在内存中,因此有称之为内存流;其中字节数组流也一种节点流;除了节点流外,我们也将学习另外一种处理流,即数据流。数据处理流是用于针对数据类型传输处理的,是一种处理流,即是在节点流之上的增强处理,一般用于序列化和反序列化的时候用到。

import java.io.*;
public class DataStream {public static void main(String[] args) {ByteArrayOutputStream baos=new ByteArrayOutputStream();//创建字节数组流,同时会在内存里面创建数组DataOutputStream dos=new DataOutputStream(baos);//对字节数组流外封装成数据处理流try {dos.writeDouble(Math.random());//利用数据流里面的写入方法,写一个Double类型的随机数据dos.writeBoolean(true);ByteArrayInputStream bias=new ByteArrayInputStream(baos.toByteArray());//toByteArray()方法是创建一个新分配的字节数组。数组的大小和当前输出流的大小。这里指的是baos这个字节数组System.out.println(bias.available());DataInputStream dis=new DataInputStream(bias);System.out.println(dis.readDouble());System.out.println(dis.readBoolean());		dos.close();dis.close();}catch (IOException e) {e.printStackTrace();}}
}

这篇关于什么流读取MultipartFile_一篇彻底读懂java中的IO流!的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/446094

相关文章

SpringBoot使用Apache Tika检测敏感信息

《SpringBoot使用ApacheTika检测敏感信息》ApacheTika是一个功能强大的内容分析工具,它能够从多种文件格式中提取文本、元数据以及其他结构化信息,下面我们来看看如何使用Ap... 目录Tika 主要特性1. 多格式支持2. 自动文件类型检测3. 文本和元数据提取4. 支持 OCR(光学

Java内存泄漏问题的排查、优化与最佳实践

《Java内存泄漏问题的排查、优化与最佳实践》在Java开发中,内存泄漏是一个常见且令人头疼的问题,内存泄漏指的是程序在运行过程中,已经不再使用的对象没有被及时释放,从而导致内存占用不断增加,最终... 目录引言1. 什么是内存泄漏?常见的内存泄漏情况2. 如何排查 Java 中的内存泄漏?2.1 使用 J

JAVA系统中Spring Boot应用程序的配置文件application.yml使用详解

《JAVA系统中SpringBoot应用程序的配置文件application.yml使用详解》:本文主要介绍JAVA系统中SpringBoot应用程序的配置文件application.yml的... 目录文件路径文件内容解释1. Server 配置2. Spring 配置3. Logging 配置4. Ma

Java 字符数组转字符串的常用方法

《Java字符数组转字符串的常用方法》文章总结了在Java中将字符数组转换为字符串的几种常用方法,包括使用String构造函数、String.valueOf()方法、StringBuilder以及A... 目录1. 使用String构造函数1.1 基本转换方法1.2 注意事项2. 使用String.valu

java脚本使用不同版本jdk的说明介绍

《java脚本使用不同版本jdk的说明介绍》本文介绍了在Java中执行JavaScript脚本的几种方式,包括使用ScriptEngine、Nashorn和GraalVM,ScriptEngine适用... 目录Java脚本使用不同版本jdk的说明1.使用ScriptEngine执行javascript2.

Spring MVC如何设置响应

《SpringMVC如何设置响应》本文介绍了如何在Spring框架中设置响应,并通过不同的注解返回静态页面、HTML片段和JSON数据,此外,还讲解了如何设置响应的状态码和Header... 目录1. 返回静态页面1.1 Spring 默认扫描路径1.2 @RestController2. 返回 html2

Spring常见错误之Web嵌套对象校验失效解决办法

《Spring常见错误之Web嵌套对象校验失效解决办法》:本文主要介绍Spring常见错误之Web嵌套对象校验失效解决的相关资料,通过在Phone对象上添加@Valid注解,问题得以解决,需要的朋... 目录问题复现案例解析问题修正总结  问题复现当开发一个学籍管理系统时,我们会提供了一个 API 接口去

Java操作ElasticSearch的实例详解

《Java操作ElasticSearch的实例详解》Elasticsearch是一个分布式的搜索和分析引擎,广泛用于全文搜索、日志分析等场景,本文将介绍如何在Java应用中使用Elastics... 目录简介环境准备1. 安装 Elasticsearch2. 添加依赖连接 Elasticsearch1. 创

Spring核心思想之浅谈IoC容器与依赖倒置(DI)

《Spring核心思想之浅谈IoC容器与依赖倒置(DI)》文章介绍了Spring的IoC和DI机制,以及MyBatis的动态代理,通过注解和反射,Spring能够自动管理对象的创建和依赖注入,而MyB... 目录一、控制反转 IoC二、依赖倒置 DI1. 详细概念2. Spring 中 DI 的实现原理三、

SpringBoot 整合 Grizzly的过程

《SpringBoot整合Grizzly的过程》Grizzly是一个高性能的、异步的、非阻塞的HTTP服务器框架,它可以与SpringBoot一起提供比传统的Tomcat或Jet... 目录为什么选择 Grizzly?Spring Boot + Grizzly 整合的优势添加依赖自定义 Grizzly 作为