Java基础之详谈IO流
前言
- 这次时跟着B站的动力节点视频学习的
- 当记录个笔记方便日后学习
- 同时将重点内容整理一下放在这里。
一、对IO的了解

1.1IO流的分类
- 有多种分类方式:
- 一种方式时按照流的方向进行分类:以内存作为参照物
- 往内存中去,叫做输入(Input),或者叫读(Read)
- 从内存中出来,叫做输出(Output),或者叫写(Write)
- 另一种方式是按照读取数据方式不同进行分类:
- 字节流:有的流是按照字节的方式读取数据,一次读取1个字节byte,等同于一次读取8个二进制位。这种流是万能的,什么类型的文件都可以读取。
- 字符流:有的流是按照字符方式读取数据的,一次读取一个字符,方便读取普通文本文件而存在的。不能读取图片、声音、视频等文件。
- 综上所述:流的分类
- 输入流、输出流
- 字节流、字符流
1.2Java IO流四大家族
- java.io.InputStream字节输入流
- java.io.OutputStream字节输出流
- java.io.Reader字符输入流
- java.io.Writer字符输出流
- 注意:在java中只要类名以"Stream"结尾的都是字节流。以"Reader/Writer"结尾的都是字符流。
- 所有的流都实现了java.io.Closeable接口,都是可关闭的,都有close()方法。
- 所有的输出流都实现了java.io.Flushable接口,都是可刷新的,都有flush()方法。养成一个好习惯,输出流在最后一定要flush()刷新一下,这个刷新表示将管道当中剩余未输出的数据强行输出完,清空管道。
- 如果没有flush()可能会导致丢失数据。
1.3java.io包下需要掌握的流
- 文件专属:
- java.io.FileInputStream
- java.io.FileOutputStream
- java.io.FileReader
- java.io.FileWrite
- 转换流:(将字节流转换成字符流)
- java.io.InputStreamReader
- java.io.OutputStreamWriter
- 缓冲流:
- java.io.BufferedReader
- java.io.BufferedWriter
- Java.io.BufferedInputStream
- Java.io.BufferedOutputStream
- 数据流:
- java.io.DataInputStream
- java.io.DataOutputStream
- 对象专属流:
- java.io.ObjectInputStream
- java.io.ObjectOutputStream
- 标准输出流
- java.io.PrintWriter
- java.io.PrintStream
二、java.io.FileInputStream
2.1如何使用FileInputStream
/*
*java.io.FileInputStream:
* 1、文件字节输入流,万能的,任何类型的文件都可以采用这个流来读。
* 2、字节的方式,完成输入的操作,完成读的操作(硬盘--->内存)
*/
public class Test1 {
public static void main(String[] args) {
FileInputStream file = null;
try {
//创建文件字节输入流对象
//idea会自动把\编辑\\。一个\表示转义
file = new FileInputStream("D:\\demo.txt");
//开始读
int readData = 0;
while((readData = file.read()) != -1)
System.out.println((char) readData);
} catch (Exception e) {
e.printStackTrace();
} finally {
if(file != null) {//关闭流
try {
file.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}

- 这是文件中字节流读取指针移动的方式。
file = new FileInputStream("D:\\demo.txt");//这是使用byte数组一次性读取,效率更高
byte[] bytes = new byte[4];
int read = 0;
while((read = file.read(bytes)) != -1) {//返回的是读取数量
System.out.println(new String(bytes,0,read));
}
2.2FileInputStream常用方法
- int available():返回流当中剩余的没有读到的字节数量
- 我们可以直接上来查看文件中的字节数量
file.available(),然后将我们的byte数组长度设为这个,这样就不必使用循环了,一次性全部读完。但是此方式并不适合太大的文件。 - long skip(long n):跳过几个字节不读
三、java.io.FileOutputStream
3.1如何使用FileOutputStream
public class FileOutputStream02 {
public static void main(String[] args) {
FileOutputStream file = null;
try {
//文件不存在时,会自动新建。在文件末尾追加、
//如果没有true,则会将文件清空后写入
file = new FileOutputStream("D:\\demo.txt",true);
byte[] bytes = new byte[]{99,100,101};
file.write(bytes);//将bytes数组全部写出
file.flush();
//学会了输入流,这个输出流大同小异,比较简单了
}
3.2文件复制
-先看图

public class FileOutputStream02 {
public static void main(String[] args) {
FileInputStream fileInput = null;
FileOutputStream fileOutput = null;
try {
fileInput = new FileInputStream("D:\\demo.txt");
fileOutput = new FileOutputStream("D:\\de.txt");
byte[] bytes = new byte[1024*1024];
int read = 0;
while((read = fileInput.read(bytes)) != -1) {
fileOutput.write(bytes,0,read);//读了多少就写多少
}
fileOutput.flush();
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
fileInput.close();
} catch (IOException e) {
e.printStackTrace();
}
try {
fileOutput.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
四、其他流的使用
4.1FileReader和FileWriter的使用
- 这两个时字符输入输出流
- 用法和上面没有什么区别,只不过是把数组byte变成了char型的,其他无异。
- 输出流时支持直接使用字符串。
out.write("我是渔夫会扎蛙!");
4.2BufferedReader缓冲流的使用
public class BufferedReaderText01 {
public static void main(String[] args) throws Exception {
FileReader fileReader = new FileReader("D:\\demo.txt");
//当一个流的构造方法中需要一个流时,这个被传递进来的流叫做:节点流
//外部负责包装的这个流叫做:包装类/处理流
//这个FileReader就是一个节点流。BufferedReader就是一个包装流
BufferedReader br = new BufferedReader(fileReader);
String firstLine = br.readLine();
System.out.println(firstLine);
//对于包装流来说,只需要关系包装流,里面的节点流会自动关闭
br.close();
}
}
4.3BufferWriter缓冲流的使用
public class BufferedWriterTest01 {
public static void main(String[] args) throws IOException {
BufferedWriter out = new BufferedWriter(new FileWriter("D:\\demo.txt"));
//将字节流转成字符流使用
BufferedWriter out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream("D:\\demo.txt")));
out.write("\n");
out.write("hello world!");
out.flush();//记得刷新管道
out.close();//记得关闭
}
}
4.4标准输出流PrintStream
public class PrintStreamTest {
public static void main(String[] args) throws FileNotFoundException {
PrintStream log = new PrintStream(new FileOutputStream("log"));
System.setOut(log);//将不在控制台输出,改变了输出方向,输出到log文件中
System.out.println("hello world!");
System.out.println("hello lllxxxx!");
}
}
五、java.io.File类
5.1了解File类
- File类并不是流,所以不能完成读和写的操作
- File对象代表:文件和目录路径名的抽象表示形式
- 一个File对象有可能是目录,也有可能是文件
- 需要掌握File类中常用的方法
public class FileTest01 {
public static void main(String[] args) {
//创建一个File对象
File file = new File("D:\\demo.txt");
//判断是否存在
System.out.println(file.exists());
file.createNewFile();//以文件的方式创建
file.mkdir();//以目录的形式创建
}
}
5.2File常用方法
- 获取文件名:getName()
- 判断是否是一个文件:isFile()
- 判断是否是一个目录:isDirectory()
- 获取文件最后一个修改时间:lastModified()//从1970年到现在的总毫秒数
- 获取文件大小:length()
六、序列化和反序列化

- 参与序列化和反序列化的对象,必须实现Serializable接口
public class Student implements Serializable {
//Serializable起到一个标记的作用,java虚拟机看到这个类实现了这个接口,会有不一样的感觉
private int no;
private String name;
public Student() {
}
public Student(int no, String name) {
this.no = no;
this.name = name;
}
@Override
public String toString() {
return "Student{" +
"no=" + no +
", name='" + name + '\'' +
'}';
}
}
public class ObjectOutputStreamTest01 {
public static void main(String[] args) throws Exception {
Student lx = new Student(1, "lx");
//序列化
//有个关键字transient表示游离的,不支持序列化
ObjectOutputStream students = new ObjectOutputStream(new FileOutputStream("students"));
//序列化对象
students.writeObject(lx);
students.flush();
students.close();
}
- 实现了Serializable这个接口,java虚拟机会自动提供给你一个序列号。用于区分类
- 缺陷:就是不能更改代码,因为只要修改代码,则将会重新编译,则java虚拟机会认为这是个全新的类。
- 建议:凡是一个类实现了Serializable接口,建议给该类提供一个固定不变的序列化版本号,即使修改了类中的内容,java虚拟机也不会认为这是全新的类。
七、IO和Properties的联合使用
- IO流:文件的读和写
- Properties:是一个Map集合,key和value都是String类型
- 以后我们使用数据库时,会使用此方法。
public class IoPropertiesTest {
public static void main(String[] args) throws IOException {
FileInputStream file = null;
file = new FileInputStream("D:\\demo.txt");
//新建一个Map集合
Properties properties = new Properties();
//文件中的数据顺着管道流加载到Map集合中,其中等号=左边做key,右边做value
properties.load(file);
//通过key获取value
String username = properties.getProperty("username");
System.out.println(username);
}
}
- 我们通常将存信息的文件称为配置文件
- 并且当配置文件中的内容格式是key1=value时候,我们把这种配置文件叫做属性配置文件。
- Java规范中要求:属性配置文件建议以.properties结尾,但不不是必须的。
六、结尾
- 对于JavaIO内容就总结这么多,若想深入学习等待后续更新,基础部分掌握这些足矣。如果有不足之处,希望大家多多包涵,多多支持。如果有不懂的地方可以直接私信问我,欢迎来访!
- 我将会继续更新关于Java的学习知识,感兴趣的小伙伴可以关注一下。
- 文章写得比较走心,用了很长时间,绝对不是copy过来的!
- 尊重每一位学习知识的人,同时也尊重每一位分享知识的人。
- 你的点赞与关注,是我努力前行的无限动力。
Java基础之详谈IO流的更多相关文章
- Java基础教程:IO流与文件基础
Java:IO流与文件基础 说明: 本章内容将会持续更新,大家可以关注一下并给我提供建议,谢谢啦. 走进流 什么是流 流:从源到目的地的字节的有序序列. 在Java中,可以从其中读取一个字节序列的对象 ...
- Java基础系列8——IO流超详细总结
该系列博文会告诉你如何从入门到进阶,一步步地学习Java基础知识,并上手进行实战,接着了解每个Java知识点背后的实现原理,更完整地了解整个Java技术体系,形成自己的知识框架. 在初学Java时,I ...
- java基础11(IO流)-字符流
转换流 由于字节流操作中文不是特别方便,所以java中提供了转换流 编码表:由现实世界的字符和对应的数值组成的一张表 编码:把看得懂的变成看不懂的(String-------byte[]) 解码:把看 ...
- java基础10(IO流)-字节流
IO流 输入与输出[参照物是程序] 如果从键盘.文件.网络甚至是另一个进程(程序或系统)将数据读入到程序或系统中,称为输入 如果是将程序或系统中的数据写到屏幕.硬件上的文件.网络上的另一端或者是一个进 ...
- Java基础12一IO流
1.IO流的原理 利用数据通道实现程序和数据源之间数据的的读写操作. 2.IO流分类 输入流.输出流.字节流.字符流.节点流.过滤流 3.InputStream 字节输入流 实现类FileInpu ...
- Java基础之(IO流)
简介: 流是一组有顺序的,有起点和终点的字节集合,是对数据传输的总称或抽象.即数据在两设备间的传输称为流,流的本质是数据传输,根据数据传输特性将流抽象为各种类,方便更直观的进行数据操作. 一.File ...
- 【java基础学习】IO流
IO流 字节流InputStream和OutputStream 字符流Writer和Reader 装饰模式
- java基础9(IO流)-File类
File类 File:文件和目录路径名的抽象表示形式.即java中把文件或者目录都封装成File对象 代码练习1 import java.io.File; public class FileDemo1 ...
- 【Java基础总结】IO流
字节流 1. InputStream 字节输入流 代码演示 InputStream in = System.in; System.out.println("int read(byte b) ...
随机推荐
- ArcMap操作随记(7)
1.栅格分辨率调整 [重采样] 2.点集数据对插值模型精度检验 test数据→[子集要素](地统计分析)→train→[插值]→[多值提取至点]→[字段计算器](Abs([value]-[spline ...
- Redis pub/sub
list 类型, lpush + rpop 或 lpush + brpop 用作消息队列时,消息只能消费一次,且不支持多个消费者(消息只能消费一次),并且在客户端崩溃时容易丢失消息.而 pub/sub ...
- 算法 | Java 常见排序算法(纯代码)
目录 汇总 1. 冒泡排序 2. 选择排序 3. 插入排序 4. 快速排序 5. 归并排序 6. 希尔排序 6.1 希尔-冒泡排序(慢) 6.2 希尔-插入排序(快) 7. 堆排序 8. 计数排序 9 ...
- django处理跨域
django处理Ajax跨域访问时使用javascript进行ajax访问的时候,出现如下错误 出错原因:javascript处于安全考虑,不允许跨域访问.下图是对跨域访问的解释: 概念: 这里说的j ...
- 《手把手教你》系列基础篇(八十一)-java+ selenium自动化测试-框架设计基础-TestNG如何暂停执行一些case(详解教程)
1.简介 在实际测试过程中,我们经常会遇到这样的情况,开发由于某些原因导致一些模块进度延后,而你的自动化测试脚本已经提前完成,这样就会有部分模块测试,有部分模块不能进行测试.这就需要我们暂时不让一些t ...
- 基于COLA架构的电商财务系统-总
财务 清算-clearing 对账-check 结算-settle 平账-correct 划拨-remit 包划分 按照COLA规则进行划分,综合考虑功能和领域两个维度包结构定义 技术参考 dddpl ...
- 如何快速开发基于Winform的应用系统
在我们实际业务开发中,从头开发一个应用系统,不管是基于BS的前端项目,还是基于Winform的CS应用系统,都是由容易到复杂,逐步演化的一个开发过程,如果我们基于一定基础上,并配合一些配套的开发工具, ...
- 什么是Ribbon?
ribbon是一个负载均衡客户端,可以很好的控制htt和tcp的一些行为.feign默认集成了ribbon.
- SpringMvc中函数的返回值是什么?
返回值可以有很多类型,有String, ModelAndView.ModelAndView类把视图和数据都合并的一起的,但一般用String比较好.
- Spring框架中有哪些不同类型的事件?
Spring 提供了以下5种标准的事件: (1)上下文更新事件(ContextRefreshedEvent):在调用ConfigurableApplicationContext 接口中的refre ...