I/O流(Input、Output)
文章目录
- 1. 概念
- 2. 分类
- 3. 应用实例
- 3.1 文件流
- 3.2 缓冲流
- 3.3 转换流
- 3.4 标准输入输出流
- 3.5 打印流
- 3.6 数据流
- 3.7 对象流
- 3.8 随机存取文件流
- 4. Java NIO
1. 概念
Input
,从硬盘读取数据到内存
Output
,将内存中的数据输出到硬盘
- 代表数据源对象或者接收数据的接收端对象
- 本质是数据传输,根据传输的特性将流抽象为各种类,方便直观的进行数据操作
- 作用是建立数据源与目的地的数据输送通道
2. 分类
根据数据流向分为输入流、输出流
按照数据单位分为字节流 8bit(非文本)、字符流 16bit
根据角色分为节点流(直接作用于文件上也称为文件流)、处理流(作用在已有流的基础上,对已存在的流进行包装)
- 四个抽象基类,子类根据具体情况分派角色
- 处理数据单位划分
名称 | 特性 | 实例 |
---|---|---|
字节流 | 每次读写一个字节,有中文时会出现乱码 | InputStream/OutputStream |
字符流 | 每次读写两个字节(一个字符),可正确显示中文 | Reader/Write |
- 功能划分
名称 | 特性 | 实例 |
---|---|---|
节点流 | 从特定节点读写数据 | FileInputStream |
处理流 | 对已存在的流的连接与封装,通过封装的流的功能进行读写 | BufferReader |
3. 应用实例
流的操作一般分为4步
- File类的实例化
- 相应流的实例化
- 读入/写出操作
- 资源关闭
3.1 文件流
- File类
- FileInputStream/FileOutputStream以字节方式读写文件
- FileReader/FileWrite以字符方式读写文件
- 将硬盘文件以字符流形式读入内存
File file = new File("hello.txt");
try {if (!file.exists()){file.createNewFile();}
} catch (IOException e) {e.printStackTrace();
}//创建字符读取流
FileReader reader = null;
try {reader = new FileReader(file);//数据读入,若到文件末尾返回-1int data = reader.read();while (data!=-1){System.out.print((char) data);//类似迭代器循环data = reader.read();}
} catch (FileNotFoundException e) {e.printStackTrace();
} catch (IOException e) {e.printStackTrace();
} finally {//关闭流,必须手动关闭,未关闭会导致内存泄漏等问题try {if (reader!=null) {reader.close();}} catch (IOException e) {e.printStackTrace();}
}
FileReader fileReader = null;
File file = new File("hello.txt");fileReader = new FileReader(file);char[] ch = new char[5];int len;
while ((len = fileReader.read(ch)) != -1) {//这里注意 i<len 否则数组五个空间覆盖时只会覆盖前三个,后面输出还是五个,会带着上一个数组中的后两个元素for (int i = 0; i < len; i++) {System.out.print(ch[i]);}
}
if (fileReader!=null){fileReader.close();
}
- 将内存文件写出到硬盘,纯文本文件使用字符流,非文本文件使用字节流
/** 写出的话文件不存在会自动帮我们创建* 存在的话会对原有文件进行覆盖,因为默认追加append是false*/FileWriter fileWriter = null;File file = new File("hello.txt");
// fileWriter = new FileWriter(file);//表示是否在原有文件内容后进行追加写入fileWriter = new FileWriter(file,true);String str = "abcdefg";fileWriter.write(str + "\n");fileWriter.write(str);if (fileWriter != null) {fileWriter.close();}
//图片视频是字节数据,需要使用字节流处理,字符流转为字节流即将char 改为 byte
//复制图片
//使用字节流复制文本文件是可以的,但也只是单纯的复制,在内存中读的时候会出现乱码File img1 = new File("1.jpg");
File img2 = new File("2.jpg");FileInputStream inputStream = new FileInputStream(img1);
FileOutputStream outputStream = new FileOutputStream(img2);byte[] b = new byte[10];
int len;
while ((len=inputStream.read(b))!=-1){for (int i = 0; i < len; i++) {System.out.println(b[i]);outputStream.write(b[i]);}
}
inputStream.close();
outputStream.close();
3.2 缓冲流
- BufferedInputStream/BufferedOutputStream字节缓冲流
- BufferedReader/BufferedWrite字符缓冲流
- flush()方法,缓冲区数据写入流,先调用flush再调用close
- 处理流的一种是缓冲流Buffered…
真实开发时不会采用基本的文件节点流,因为效率较差,往往采用缓冲流进行处理,提高流的读取写入速度
原因是内部提供了一个8192字节缓冲区常量
File file1 = new File("1.jpg");File file2 = new File("2.jpg");FileInputStream inputStream = new FileInputStream(file1);FileOutputStream outputStream = new FileOutputStream(file2);//不可直接作用于文件上,只可以作用于已存在的流上BufferedInputStream bufferedInputStream = new BufferedInputStream(inputStream);BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(outputStream);//具体读取写入过程byte[] b = new byte[10];int len;while ((len=bufferedInputStream.read(b))!=-1){for (int i = 0; i < len; i++) {bufferedOutputStream.write(b[i]);}}//关闭时先关闭外层流,再关闭内层的流,因为处理流是包着节点流的bufferedInputStream.close();bufferedOutputStream.close();//其实在关闭外层流的同时,内层流也会自动关闭,所以可以省略不写
// inputStream.close();
// outputStream.close();
3.3 转换流
- InputStreamReader字节流中读取字符
- OutputStreamWrite字符写入字节流
- 转换流(处理流的一种)
提供字节流和字符流之间的一个转换
解码:字节—>字符(看不懂—>看得懂)
/** 转换流使用,属于字符流,操作 char 型数组* InputStreamReader 将字节的输入流转换为字符的输入流* OutputStreamWriter 将字符的输出流转换为字节的输出流*/File file = new File("hello.txt");File outhello = new File("outhello.txt");FileInputStream fileInputStream = new FileInputStream(file);FileOutputStream fileOutputStream = new FileOutputStream(outhello);//系统默认字符集看当前IDE设定,实际编码应该按照文件存储时的字符集编码来设定参数InputStreamReader inputStreamReader = new InputStreamReader(fileInputStream, "UTF-8");OutputStreamWriter outputStreamWriter = new OutputStreamWriter(fileOutputStream,"gbk");char[] ch = new char[20];int len;while ((len = inputStreamReader.read(ch)) != -1) {// for (int i = 0; i <len ; i++) {// System.out.println(ch[i]);
// }String str = new String(ch, 0, len);System.out.print(str);outputStreamWriter.write(str);}inputStreamReader.close();outputStreamWriter.close();
3.4 标准输入输出流
System.in//键盘输入
System.out//控制台输出
3.5 打印流
打印只能是输出
PrintStream
PrintWriter
3.6 数据流
用于读写基本数据类型的变量或字符串
DataInputStream
DataOutputStream
3.7 对象流
对象序列化机制:允许把内存中的Java对象转换成与平台无关的二进制流,从而允许把这种二进制流持久地保存在磁盘上,或通过网络将这种二进制流传输到另一个网络节点。当其它程序获取了这种二进制流,就可以恢复成原来的Java对象
序列化的好处在于可将任何实现了 Serializable接口的对象转化为字节数据,使其在保存和传输时可被还原
序列化是RMI(Remote Method Invoke-远程方法调用)过程的参数和返回值都必须实现的机制,而RMI是 JavaEE的基础。因此序列化机制是JavaEE平台的基础
如果需要让某个对象支持序列化机制,则必须让对象所属的类及其属性是可序列化的 (基本数据类型都是可序列化的),为了让某个类是可序列化的,该类必须实现如下两个接口之一。否则,会抛出 NotSerializableEXception异常
Serializable
Externalizable
凡是实现 Serializable接口的类都有一个表示序列化版本标识符的静态变量serialVersionUID用来表明类的不同版本之间的兼容性。简言之,其目的是以序列化对象进行版本控制,有关各版本反序列化时是否兼容。
如果类没有显示定义这个静态变量,它的值是Java运行时环境根据类的内部细节自动生成的,一旦类原始类进行调整,则无法再反序列化。
若类的实例变量做了修改,serialVersionUID可能发生变化。故建议,进行显式声明。
简单来说,Java的序列化机制是通过在运行时判断类的serialVersionUID来验证版本一致性的。在进行反序列化时,JVM会把传来的字节流中的serialVersionUID与本地相应实体类的 serialVersionUID进行比较,如果相同就认为是一致的,可以进行反序列化,否则就会出现序列化版本不一致的异常。(InvalidCastException)
/** 序列化时一定要先实现Serializable接口(标识接口)* 必须实现进入的一个全局常量属性,序列版本号,设定唯一标识防止还原识别时混乱,详情见Serializable源码说明*/
public class Person implements Serializable {//序列版本号,自定义一个long类型值public static final long serialVersionUID = 4752525455642L;private String name;private int age;public Person() {}public Person(String name, int age) {this.name = name;this.age = age;}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}@Overridepublic String toString() {return "Person{" + "name='" + name + '\'' + ", age=" + age + '}';}
}
/** 将对象读出写入到数据源中* 序列化:ObjectOutputStream保存内存中的Java对象或基本数据类型到磁盘中* 反序列化:ObjectInputStream从磁盘中读取Java对象或基本数据类型到内存中* 对于声明为 static 和 transient无效*///序列化操作ObjectOutputStream objectOutputStream = new ObjectOutputStream(new FileOutputStream("data.dat"));// objectOutputStream.writeObject("你好世界");
// //刷新操作
// objectOutputStream.flush();objectOutputStream.writeObject(new Person("tylt", 18));objectOutputStream.flush();objectOutputStream.close();//反序列化操作ObjectInputStream objectInputStream = new ObjectInputStream(new FileInputStream("data.dat"));Object readObject = objectInputStream.readObject();// String str = (String) readObject;
// System.out.println(str);Person p = (Person) readObject;System.out.println(p);objectInputStream.close();
3.8 随机存取文件流
RandomAccessFile
直接继承Object,既可作为输入流也可输出流
/** r:只读(不会创建文件,只会读取已经存在的文件)* rw:读写* rwd:读写+同步内容更新* rws:读写+同步内容更新+元数据更新*/File img = new File("1.jpg");
File outimg = new File("3.jpg");
RandomAccessFile accessFile = new RandomAccessFile(img,"r");
RandomAccessFile accessOutFile = new RandomAccessFile(outimg,"rw");byte[] b = new byte[1024];
int len;
while ((len=accessFile.read(b))!=-1){for (int i = 0; i < len; i++) {System.out.println(b[i]);accessOutFile.write(b[i]);}}
accessFile.close();
accessOutFile.close();
4. Java NIO
Java NIO(New IO,Non-Blocking IO) NIO将以更加高效的方式进行文件的读写操作,因为IO是面向流的,而NIO是面向缓冲区的
Java API中提供了两套NIO,一套是针对标准输入输出NIO,另一套就是网络编程NIO
早期的Java只提供了一个File类来访问文件系统,但File类的功能比较有限,所提供的方法性能也不高。大多数方法在出错时仅返回失败,并不会提供异常信息。
NIO.2为了弥补这种不足,引入了Path接口,代表一个平台无关的平台路径,描述了目录结构中文件的位置。Path可以看成是File类的升级版本,实际引用的资源也可以不存在。
/** Files、Paths工具类* k*/
Path path = Paths.get("hello.txt");
System.out.println(path);
I/O流(Input、Output)相关推荐
- 关于OSD::mkfs: ObjectStore::mkfs failed with error (5) Input/output error问题的解决
环境: ceph L版本12.2.1升级到12.2.12 这个问题是由于升级后进行12.2.12环境中的使用ceph-disk 进行osd部署时出现如下问题,执行命令 ceph-disk -v pre ...
- 报错解决transmission: Error: Input/Output error和ls: reading directory '': Input/output error
transmission: Error: Input/Output error 晚上想用transmission下载新的种子时报错:Error: Input/Output error. 我很奇怪,先运 ...
- python3 报错 [Errno 5] Input/output error 没有stdout时使用了print
过程描述 刚不久用 Tornado 写了一个项目,本打算部署在 Nginx 上,但是因为公司的一些原因就没有使用 Nginx,直接在命令行中启动 当我从命令行以后台的方式启动以后,是可以正常访问的 p ...
- colab出现input output error问题
原因是文件太多,清理一下回收站,尝试用先从 !cp path/to/data.csv local.csv 为什么 drive.mount() 有时会失败,并提示"超时"?为什么在通 ...
- Debug Tensorflow: TypeError: Cannot convert a symbolic Keras input/output to a numpy array.
问题 'Cannot convert a symbolic Keras input/output to a numpy array. ' TypeError: Cannot convert a sym ...
- Angular中父子组件传值@Input @Output @ViewChild最全面最简单的总结
父组件传递给子组件: 值传递方式:@Input既可以传递数据也可以传递方法 传递数据(不举例了) 传递方法 // 父组件定义方法 parentRun(){alert('这是父组件的 run 方法'); ...
- html5 填表 表单 input output 与表单验证
1.<output> Js计算结果 <form οninput="res.value = num1.valueAsNumber*num2.valueAsNumber ...
- linux-x86_64 error,Linux-x86_64 Error: 5: Input/output error的问题
今天朋友的测试库报错, ORA-27072: File I/O error, Linux-x86_64 Error: 5: Input/output error,数据块已经不能正常启动,看到 Linu ...
- docker中java应用new FileOutputStream直接报Input/output error
为什么80%的码农都做不了架构师?>>> 一个docker容器中跑着java应用,是一个定时任务,每天拉取远端文件包存到本机,命名为:decrypt-20181020 就在这一 ...
- 硬盘故障时如何强制关机:Input/output error
如果硬盘可能会出现锁死或坏道的故障,会造成SHELL命令的失效,包括 reboot,powoff,,shutdown,用正常的命令是没法完成重启的. 执行这些命令,会出现如下IO报错: reboot ...
最新文章
- JVM怎么判断对象是否存活
- seaborn 笔记:load_dataset
- [原]Java程序员的JavaScript学习笔记(12——jQuery-扩展选择器)
- html js坐标图,javascript – HTML5 Canvas沿着带坐标的路径拖动图像
- relation does not exist报错是什么意思_为什么Zookeeper天生就是一副分布式锁的胚子?...
- Java大数据处理的流行框架
- 隐藏/显示jeecg-boot 后端管理页面的右侧的系统设置
- 人走茶凉!三星关闭最后一家中国手机工厂 因为打不过其他国产厂商?
- Docker教程:使用docker配置python开发环境
- Java基础零碎知识点总结(持续补充)
- NDK编译doubango时出现错误:undefined reference to ‘stderr‘
- 在eclipse中修改android源码
- Java根类--Object类
- ST25读FeliCa卡记录
- Windows Server 2016 安装.NET Framework 3.5 错误处理
- 早晨随笔_早上如何调试
- 第一天:2个法则,你的第一桶金可以这么来
- java俄罗斯方块七中图形类_俄罗斯方块shell 实现
- 微信公众号开发:获取openId和用户信息(完整版)
- Python编写数字转换成中文大写
热门文章
- python sendkeys用法_Python Selenium 文件上传之SendKeys
- 三菱fx2n64mr说明书_FX2N-64MR-DS手册三菱可编程控制器FX2N-64MR-DS使用说明书 - 广州凌控...
- Protobuf的奇怪问题解决--Expected top - level statement (e.g message)
- 设置win7文件夹背景和图标
- Sophos XG Firewall:如何使用Windows Server 2012为企业无线身份验证配置RADIUS
- AYITOJ ROUND #1题解
- 如何把新加的分区挂载到/根目录
- 【FPGA——工具篇】:Xilinx_ISE_12.4安装包下载百度云网盘
- 一物一码二维码红包系统介绍
- 9.3 开发经验和屁股的关系——《逆袭大学》连载