JavaIO流——文件的读取与传输
I/O也叫做输入/输出,在java编程语言中,I/O更被看作是一种流;JavaI/O的体系设计与Linux内核I/O有着密不可分的关系;
为了操作系统的安全考虑,Linux进程是无法直接操作I/O设备的,必须通过内核来协助完成I/O动作,而内核会为每个I/O设备维护一个缓冲区Buffer,又叫做缓冲区;
数据从I/O设备拷贝到buffer缓冲区(等待数据阶段);
数据再从缓冲区拷贝到Linux进程(拷贝数据阶段);
此过程可分为五种模型:
**阻塞I/O模型(Blocking I/O):**在Linux中默认情况下所有请求都是阻塞的,一个典型的读操作如下图:
**非阻塞I/O(Non-Blocking I/O):**应用会不断询问内核是否准备好了数据,系统不会阻塞用户进程,而是立即返回,从用户进程角度讲,并不需要等待可以立即返回结果;
I/O 复用(I/O Multiplexing):
信号驱动 I/O(Signal Driven I/O):
异步 I/O(Asynchrnous I/O):
Java标准I/O模型(Blocking I/O)
早期的Java I/O都是基于阻塞I/O模型的,他按照处理的数据类型分为字符流和字节流,按照工作职责分为处理流和装饰流。
字节流: 以 8 位( 即 1byte, 8bit) 作为一个数据单元, 数据流中最小的数据单元是字节;
字符流: 以 16 位( 即 1char, 2byte, 16bit) 作为一个数据单元, 数据流中最小的数据单元是字符, Java 中的字符是 Unicode 编码, 一个字符占用两个字节;
Java依据据字节流定义了了InputStream/OutputStream,依据字符流Java定义了Reader/Writer;Java 再根据不同应用场景或功能, 通过继承这两种抽象基类派生出子类, 用
来满足文件、 网络、 管道等不同场景的 I/O 需求, 从而形成了 Java 的基本 I/O 体系。
又可按照工作职能分为:
处理流: 真正直接处理 I/O 数据的类, 包括文件流、 数组流、 字符串流、 管道流;
装饰流: 用来装饰加工节点流的, 比如封装某些功能, 包括缓冲流、 转换流、 数据流、 对象流;
这些标准输入现在正逐渐被NIO取代
Java NIO模型(Non-blocking I/O)
**NIO 出现了(有的也称之为 New I/O),NIO 不但新增加了许多全新的类,而且还对原 java.io 包中的很多类进行了改写,NIO 主要包含三个核心部分:Channel、Buffer 和 **
Selector。
**Channel(通道):**NIO 中所有的读写操作都是从 Channel(通道)开始的,顾名思义,Channel 就是一条能够让数据通过的管道(像喝奶茶的吸管那样),它最重要的实可
以分为两大类:用于本地文件的 Channel 和用于网络的 Channel。
**Buffer(缓冲区):**Buffer 是专门用来缓存输入或输出的数据,分为输入缓冲区和输出缓冲区,它可以解决高速设备与低速设备速度的不匹配问题,也可以减少读写次数,
Channel提供从文件、网络读取数据的渠道,但是读写的数据都必须经过 Buffer。
Selector(选择器):数据总是从 Channel 读取到 Buffer,或者从 Buffer 写入到Channel,单个线程可以监听多个 Channel——Selector 就是这个线程背后的实现机制。
Selector 通过单线程处理多个 Channel,而 Selector(线程)之间需要传递数据的话,需要用到 Pipe,它是用于 Selector 之间数据传递的一种「单向」「管道」。
Scatter/Gather
Java NIO 支持一种称之为支持本地矢量 I/O(native vectored I/O)的技术(或者称为 Scatter/Gather 操作),当应用在一个 Channel 上请求一个 Scatter/Gather 操作时,这
个请求会被翻译为适当的本地调用来直接填充或抽取缓冲区,减少或避免了缓冲区拷贝和系统调用,这也意味着,Scatter/Gather 将使用直接缓冲区以从本地 I/O 获取最大性优
势(直接缓冲区的概念请参考名词解释),具体来说:
Scatter:将从一个 Channel 里读取的信息分散到多个 Buffer 中;
Gather:将多个 Buffer 里面的内容按顺序发送到一个 Channel 中。
标准I/O如何使用
File类及相关应用
File类的构造方法:
File(File parent,String child)
从父抽象路径名和子路径名字符串创建新的 File
实例。
File(String pathname)
通过将给定的路径名字符串转换为抽象路径名来创建新的 File
实例。
File(String parent, String child)
从父路径名字符串和子路径名字符串创建新的 File
实例。
File(URI uri)
通过将给定的 file:
URI转换为抽象路径名来创建新的 File
实例。
常用方法
public String getAbsolutePath() :
返回此File
的绝对路径名字符串。
public String getPath() :
将此File
转换为路径名字符串。
public String getName() :
返回由此File
表示的文件或目录的名称。
public long length() :
返回由此File
表示的文件的长度。
判断功能的方法
public boolean exists() :
此File
表示的文件或目录是否实际存在。
public boolean isDirectory() :
此File
表示的是否为目录。
public boolean isFile() :
此File
表示的是否为文件。
增删的方法
public boolean createNewFile() :
当且仅当具有该名称的文件尚不存在时,创建一个新的空文件。
public boolean delete() :
删除由此File
表示的文件或目录。
public boolean mkdir() :
创建由此File
表示的目录。
public boolean mkdirs() :
创建由此File
表示的目录,包括任何必需但不存在的父目录。
目录的遍历
public String[] list() :
返回一个String
数组,表示该File目录中的所有子文件或目录。
public File[] listFiles() :
返回一个File
数组,表示该File目录中的所有的子文件或目录
任务一:如果是 Windows 系统,以递归方式读取 C 盘中所有的目录和文件,并打印出每个文件的大小和每个目录中文件的数量;如果是 Linux/Mac 系统,那么递归方式读取/usr中所有的目录和文件,并打印出每个文件的大小和每个目录中文件的数量。
package T11.windowC;import java.io.File;
import java.text.DecimalFormat;import static java.lang.Math.pow;/*** @Author: Administrator* Date: 2021/12/14 21:15* @Version:* @Description:*/
public class Test {public void soutWindowC(File file) {File[] files = {};if (file.isFile()) {System.out.print(file.getName());String s = fileSize(file);System.out.println("----" + s);return;} else if (file.isDirectory()) {files = file.listFiles();if (files == null) {return;} else {for (File file1 : files) {if (file1.isDirectory()) {System.out.println(file1.getName());System.out.print("\t");soutWindowC(file1);}if (file1.isFile()) {System.out.print(file1.getName());String s = fileSize(file1);System.out.println("----" + s);return;}}}}}String fileSize(File file) {DecimalFormat df = new DecimalFormat("#.00");String fileSize = "";if (file.length() < 1024) {fileSize = df.format(file.length()) + "B";}else if (file.length() < pow(1024, 2)) {fileSize = df.format(file.length()/1024) + "KB";}else if (file.length() < pow(1024, 3)) {fileSize = df.format(file.length()/pow(1024, 2)) + "MB";}else if (file.length() < pow(1024, 4)) {fileSize = df.format(file.length()/pow(1024, 3)) + "GB";}return fileSize;}@org.junit.Testpublic void test() {File file = new File("D:/");soutWindowC(file);}}
字节操作流
InputStream(字节输入流):
public void close() :
关闭此输入流并释放与此流相关联的任何系统资源。当完成流的操作时,必须调用此方法,释放系统资源。
public abstract int read() :
从输入流中读取下一个数据字节。值字节返回int
,范围为0
至255
。如果由于到达流末尾而没有可用字节,则返回值-1
。此方法将阻塞,直到输入数据可用,检测到流的末尾或抛出异常。子类必须提供此方法的实现.
public int read(byte[] b) :
从输入流中读取一些字节数,并将它们存储到字节数组 b中 。
OutputStream(字节输出流):
public void close() :
关闭此输出流并释放与此流相关联的任何系统资源。当完成流的操作时,必须调用此方法,释放系统资源。
public void flush() :
刷新此输出流并强制任何缓冲的输出字节被写出。
public void write(byte[] b) :
将 b.length字节从指定的字节数组写入此输出流。
public void write(byte[] b, int off, int len) :
从指定的字节数组写入 len字节,从偏移量 off开始输出到此输出流。
public abstract void write(int b) :
将指定的字节输出流。
public class InputStreamDemo {@Testpublic void test() throws IOException {FileInputStream fis = new FileInputStream("E://old/battleField.png");FileOutputStream fos = new FileOutputStream("E://new/battleField.png");byte[] b= new byte[1024];int len;while((len = fis.read(b))!=-1){fos.write(b, 0, len);}}
}
字符操作流
Reader(字符输入流):
public void close() :
关闭此输入流并释放与此流相关联的任何系统资源。当完成流的操作时,必须调用此方法,释放系统资源。
public abstract int read() :
从输入流中读取下一个数据字节。值字节返回int
,范围为0
至255
。如果由于到达流末尾而没有可用字节,则返回值-1
。此方法将阻塞,直到输入数据可用,检测到流的末尾或抛出异常。子类必须提供此方法的实现.
public int read(byte[] b) :
从输入流中读取一些字节数,并将它们存储到字节数组 b中 。
Writer(字符输出流):
public void close() :
关闭此输出流并释放与此流相关联的任何系统资源。当完成流的操作时,必须调用此方法,释放系统资源。
public void flush() :
刷新此输出流并强制任何缓冲的输出字节被写出。
public void write(byte[] b) :
将 b.length字节从指定的字节数组写入此输出流。
public void write(byte[] b, int off, int len) :
从指定的字节数组写入 len字节,从偏移量 off开始输出到此输出流。
public abstract void write(int b) :
将指定的字节输出流。
public class ReaderDemo {@Testpublic void test() throws IOException {FileReader reader = new FileReader("E://old/battleField.png");FileWriter writer = new FileWriter("E://new/battleField.png");char c[] = new char[1024];int len;while ((len = reader.read(c)) != -1){writer.write(c, 0, len);writer.flush();}}
}
NIO应该如何使用
public class NIODemo {@Testpublic void test() throws IOException {FileChannel channelIn = new FileInputStream("E://old/battleField.png").getChannel();FileChannel channelOut = new FileOutputStream("E://new/battleField.png").getChannel();channelIn.transferTo(0, channelIn.size(), channelOut);}
}
感谢您的阅读,如果本篇文章对您有帮助,欢迎点赞,关注,您的阅读是我莫大的鼓励!
JavaIO流——文件的读取与传输相关推荐
- javaIO流详解--读取,写入文件的所有类与方法
目录 IO流简介: 1 :InputStream 2:OutputStream 3:FileInputStream 4:FileOutputStream 5:利用FileInputStream和Fil ...
- javaio流_万字长文+思维导图帮你梳理 Java IO 流,还学不会你来打我(值得收藏)...
前言 在上一篇的文章获取不错的浏览量后,继续加更的念头一直徘徊在心中,本来是想花段时间深入学习tomcat的,可是tomcat的源码中就有至关重要的NIO,于是得先整一下NIO,但是NIO的基础是BI ...
- 文件_ _android从资源文件中读取文件流并显示的方法
======== 1 android从资源文件中读取文件流并显示的方法. 在android中,假如有的文本文件,比如TXT放在raw下,要直接读取出来,放到屏幕中显示,可以这样: private ...
- php接收流文件,PHP传输文件流及文件流的保存
什么是文件流 在HTTP数据传送过程中,传输一方直接以二进制流方式传送文件内容,这样就形成了一个文件流: 文件流的接收通常涉及到预定义变量函数 $HTTP_RAW_POST_DATA 和 file_g ...
- Java------IO流之文件专属流
文件专属流 文章目录 文件专属流 FileInputStream流 FileInputStream初步读取 FileInputStream循环读 IDEA默认当前路径 往byte数组中读 最终版Fil ...
- 用对象流把对象存到文件中,再从文件中读取出来打印。
例如把学生对象存到文件中: 1.先创建一个学生类 ***注意 用对象流时,要保存的对象所属的类必须要实现序列化(implements Serializable) package my_tes ...
- 小师妹学JavaIO之:文件读取那些事
文章目录 简介 字符和字节 按字符读取的方式 按字节读取的方式 寻找出错的行数 总结 简介 小师妹最新对java IO中的reader和stream产生了一点点困惑,不知道到底该用哪一个才对,怎么读取 ...
- java读取二进制流文件_java分别通过字节流、字符流、二进制读取文件的代码
将做工程过程中比较好的一些内容段做个备份,下面的资料是关于 java分别通过字节流.字符流.二进制读取文件的内容,应该是对小伙伴们有些用途. public class Start { public s ...
- 使用IO流对文件进行读取功能
对于文件的读取可以用字符流也可以用字节流,下面整理了一份利用字节读流对本地文件进行读取 1.实现思路 第一步:选择文件 实例化一个文件File,在File的构造里放上你要读取的文件路径,文件路径的斜杠 ...
- Java字符流Writer写入文件Reader读取文件
写文件 public class WriteDemo {public static void main(String[] args) throws IOException {File file = n ...
最新文章
- 基于python的快速傅里叶变换FFT(二)
- POJ 2481 Cows POJ 2352 Stars(树状数组妙用)
- Linux上安装Julia-1.1
- u盘病毒之tel.xls.exe
- Memcached服务端自动启动(转载)
- Spark 性能优化指南(官网文档)
- input组件android,React-Native TextInput组件详解及实例代码
- 【免费下载】2021年9月热门报告盘点(附热门报告列表及下载链接)
- 如何解决多机房、多网络下的物联网部署方案?
- 正则表达式替换字符串
- mql 查询多结果_MQL入门到精通EA教程第六课MQL语言基础(五)
- 编码,隐匿在计算机软硬件背后的语言读书笔记(作者序)
- 将US7ASCII 字符集的数据转到ZHS16GBK 字符集数据库
- 网站更换国外服务器,备案被注销替换外国服务器?这样合理吗?
- 混沌的有关概念——1
- 基于ARMv8的固件系统架构
- Halium 9 尝鲜 -- 在小米平板4上的移植 (一)
- python日常实用小脚本-用Python编写渗透用小脚本 短小实用
- Helicon Focus Pro(景深合成软件)官方中文版V7.6.6 | helicon focus中文版下载 | 含helicon focus使用方法
- photon 服务器操作系统,PhotonServer游戏服务器端教程