第十二章 流(Stream)、IO和文件(File)

文章目录

  • 第十二章 流(Stream)、IO和文件(File)
  • 一、流(Stream)
    • 1.什么是流
    • 2.流的分类
  • 二、IO流
    • 1.字节输入流(InputStream)
    • 2.字符输入流(Reader)
    • 3.字节输出流(OutputStream)
    • 4.字符输出流(Writer)
  • 三、文件(File)

一、流(Stream)

1.什么是流

流是个抽象的概念,是对输入输出设备的抽象
当程序需要从某个数据源读入数据的时候,就会开启一个输入流,数据源可以是文件、内存或网络等等。相反的,需要写出数据到某个数据源目的地的时候,也会开启一个输出流,这个数据源目的地也可以是文件、内存或网络等等

一个流可以理解为一个数据的序列。输入流表示从一个源读取数据,输出流表示向一个目标写数据
也可以将流想象成一个 ”水流管道“ ,水流在管道中形成了,自然就出现了流动和流动方向

2.流的分类

按照流的方向不同:分为输入流和输出流
按照处理数据单位的不同:分为字节流(8 位)和字符流(16 位)
按照功能不同:分为节点流和处理流

  • 节点流:
    是可以从一个特定的数据源(节点)读写数据的流(例如文件、内存)。就像是一条单一的管道接到水龙头上放水
  • 处理流:
    ”连接“ 在已经存在的流(节点流或处理流)之上,通过对数据的处理,为程序提供更为强大的读写功能。就像在已经接了一条管道(节点流)的基础上,又套上几条具有特殊功能的管道(处理流),对流水做进一步处理

输入流和输出流的类层次图:

二、IO流

1.字节输入流(InputStream)

InputStream这个抽象类是所有基于字节的输入流的超类

FileInputStream(操作文件的字节输入流)
直接插在文件上,直接读取文件数据

//方法 1 用于测试普通字节流的读取private static void method(){InputStream in = null;//1.创建字节输入流对象用于读取//InputStream in = new InputStream();// 抽象父类不可以创建对象!创建的是子类 FIS 的对象//IO 操作可能会发生异常,所以需要 try-catchtry {//InputStream in2 = new FileInputStream(new File("C:\\Users\\admin\\Desktop\\项目文件\\个人项目\\ready\\1.txt"));in = new FileInputStream("C:\\Users\\admin\\Desktop\\项目文件\\个人项目\\ready\\1.txt");//            //使用流对象
//            /**read() 一次读取一个字节,如果没有数据了,返回 -1*///2.1测试复杂的读法
//            System.out.println(in.read());//97-a
//            System.out.println(in.read());//98-b
//            System.out.println(in.read());//99-c
//            System.out.println(in.read());//-1
//            System.out.println(in.read());//-1//改造:需要循环读取文件中的所有内容//2.2定义变量,记录读到的数据int b;while((b = in.read()) != -1){System.out.println(b);}} catch (IOException e) {e.printStackTrace();//打印错误信息} finally {//3.关闭流资源try {in.close();} catch (IOException e) {e.printStackTrace();}}}

BufferedInputStream(缓冲/高效字节流)
流操作的特性是数据传输(只能往前进,而不能往后退),而数据传输速度和数据处理的速度存在不平衡,这种不平衡使得数据传输过程中进行缓存处理而释放数据处理器的资源是一种提高程序效率的机制。比如,厕所的抽水马桶,我们不会用一滴滴的水进行冲洗,而是等到水达到一定的量再进行冲洗。在数据流处理时,CPU也不会等待内存读取数据后就立即处理,而是在内存数据到达一定的量后在进行处理,从而腾出CPU的处理时间。在java.io读写文件时,常常使用缓存进行操作,而不是按部就班的逐个字节读取处理

BufferedInputStream 为另一个输入流添加一些功能,即缓冲输入以及支持 mark 和 reset 方法的能力。在创建 BufferedInputStream 时,会创建一个内部缓冲区数组(默认8k大小)。在读取或跳过流中的字节时,可根据需要从包含的输入流再次填充该内部缓冲区,一次填充多个字节

//方法 2 用于测试高效字节流的读取private static void method2(){BufferedInputStream in = null;try {//1.创建流对象in = new BufferedInputStream(new FileInputStream("C:\\Users\\admin\\Desktop\\项目文件\\个人项目\\ready\\1.txt"));//2.使用流int b;while((b = in.read()) != -1){System.out.println(b);}} catch (IOException e) {e.printStackTrace();} finally {try {in.close();} catch (IOException e) {e.printStackTrace();}}}

2.字符输入流(Reader)

用于读取字符流的抽象类

FileReader(操作文件的字节流)

//创建一个普通字符流读取的方法private static void method() {//Reader 作为字符输入流的抽象父类,不可以被实例化//Reader in2 = new Reader();//1.创建一个在本方法中都生效的局部变量,初始值为 nullReader in = null;//2.完成 try - catch - finally 结构try {//3.创建 FileReader 流对象,参数:File/路径in = new FileReader("C:\\Users\\admin\\Desktop\\项目文件\\个人项目\\ready\\1.txt");//4.读取文件数据int b;while((b = in.read()) != -1){System.out.println(b);}} catch (IOException e) {//捕获异常e.printStackTrace();//捕获到异常后打印错误信息} finally {try {//5.关流in.close();} catch (IOException e) {e.printStackTrace();}}}

BufferedReader(缓冲/高效字符流)

//创建一个高效字符流读取的方法private static void method2() {//Reader 作为字符输入流的抽象父类,不可以被实例化//Reader in2 = new Reader();//1.创建一个在本方法中都生效的局部变量,初始值为 nullReader in = null;//2.完成 try - catch - finally 结构try {//3.创建 BufferedReader 流对象,参数:File/路径in = new BufferedReader(new FileReader("C:\\Users\\admin\\Desktop\\项目文件\\个人项目\\ready\\1.txt"));//4.读取文件数据int b;while((b = in.read()) != -1){System.out.println(b);}} catch (IOException e) {//捕获异常e.printStackTrace();//捕获到异常后打印错误信息} finally {try {//5.关流in.close();} catch (IOException e) {e.printStackTrace();}}}

3.字节输出流(OutputStream)

此抽象类是表示输出字节流的所有类的超类,输出流接受输出字节并将这些字节发送到某个接收器

FileOutputStream(操作文件的字节流)
直接插在文件上,直接写出文件数据

//创建一个用于测试普通字节输出流的方法private static void method() {//1.定义一个在方法中都生效的局部变量,初始值为 nullOutputStream out = null;try {//2.创建流对象/**可以使用两个参数的构造方法,来控制输出的数据是覆盖还是追加* 默认的方式是覆盖* 如果想要追加,第二个参数 append 应该设置为 true*/out = new FileOutputStream("C:\\Users\\admin\\Desktop\\项目文件\\个人项目\\ready\\1.txt",true);//3.使用流对象out.write(97);out.write(97);out.write(97);} catch (IOException e) {e.printStackTrace();} finally {try {//4.关流out.close();} catch (IOException e) {e.printStackTrace();}}}

BufferedOutputstream(缓冲/高效字节流)
该类实现缓冲的输出流,通过设置这种输出流,应用程序就可以将各个字节写入底层输出流中,而不必每次针对字节写出调用底层系统

//创建一个用于测试高效字节输出流的方法private static void method2() {//1.定义一个在方法中都生效的局部变量,初始值为 nullOutputStream out = null;try {//2.创建高效流对象/**可以使用两个参数的构造方法,来控制输出的数据是覆盖还是追加* 默认的方式是覆盖* 如果想要追加,第二个参数 append 应该设置为 true*/out = new BufferedOutputStream(new FileOutputStream("C:\\Users\\admin\\Desktop\\项目文件\\个人项目\\ready\\1.txt",true));//3.使用流对象out.write(97);out.write(97);out.write(97);} catch (IOException e) {e.printStackTrace();} finally {try {//4.关流out.close();} catch (IOException e) {e.printStackTrace();}}}

4.字符输出流(Writer)

写入字符流的抽象类

FileWriter操作文件的字符输入流)
用来写入字符文件的便捷类,此类的构造方法假定默认字符编码和默认字节缓冲区大小都是可接受的,如果需要自己自定义这些值,可以先在 FileOutputStream 上构造一个 OutputStreamWriter

private static void method() {Writer out = null;try {out = new FileWriter("C:\\Users\\admin\\Desktop\\项目文件\\个人项目\\ready\\1.txt",true);out.write(97);} catch (IOException e) {e.printStackTrace();} finally {try {out.close();} catch (IOException e) {e.printStackTrace();}}}

BufferedWriter(缓冲/高效字符流)
将文本写入字符输出流,缓冲各个字符,从而提供单个字符,数组和字符串的高效写入,可以指定缓冲区的大小,或者接受默认的大小,在大多数情况下,默认值就足够大了

private static void method2() {Writer out = null;try {out = new BufferedWriter(new FileWriter("C:\\Users\\admin\\Desktop\\项目文件\\个人项目\\ready\\1.txt",true));out.write(97);out.flush();//防止数据遗漏,刷数据} catch (IOException e) {e.printStackTrace();} finally {try {out.close();} catch (IOException e) {e.printStackTrace();}}}

三、文件(File)

文件可以理解为一种流的源头,和文件流不是一种概念
可以封装一个磁盘路径字符串,对这个路径可以执行一次操作
可以封装文件路径、文件夹路径和不存在的路径(指可以创建对象,无论磁盘中有没有文件)

package com.sisyphus.file;import java.io.File;
import java.io.IOException;
import java.util.Arrays;/**本类用于测试文件类的常用方法*/
public class TestFile {public static void main(String[] args) throws IOException {//0.需要自己手动创建一个 ready 目录,下有一个 1.txt文件//注意:如果系统没有显示后缀名/文件扩展名,文件名应该是 1//1.创建 File 对象File file = new File("C:\\Users\\admin\\Desktop\\项目文件\\个人项目\\ready\\1.txt");//2.测试常用方法System.out.println(file.length());//查看 file 的字节量System.out.println(file.exists());//检验 file 是否存在System.out.println(file.isFile());//判断 file 是否为文件System.out.println(file.isDirectory());//判断 file 是否为文件夹System.out.println(file.getName());//1.txt,获取文件名System.out.println(file.getParent());//获取父级路径System.out.println(file.getAbsoluteFile());//获取文件的绝对路径//2.2创建file = new File("C:\\Users\\admin\\Desktop\\项目文件\\个人项目\\ready\\2.txt");//创建 java 对象System.out.println(file.createNewFile());//真正创建一个2.txtfile = new File("C:\\Users\\admin\\Desktop\\项目文件\\个人项目\\ready\\a");System.out.println(file.mkdir());//创建单层文件夹file = new File("C:\\Users\\admin\\Desktop\\项目文件\\个人项目\\ready\\a\\b\\c");System.out.println(file.mkdirs());//创建多层文件夹//2.3测试删除/**注意:这个删除的方法只能删除空文件夹与文件*/System.out.println(file.delete());//只有 c 被删除了file = new File("C:\\Users\\admin\\Desktop\\项目文件\\个人项目\\ready\\a");System.out.println(file.delete());//false,因为文件夹不为空file = new File("C:\\Users\\admin\\Desktop\\项目文件\\个人项目\\ready\\2.txt");System.out.println(file.delete());//2.txt 删除成功//3.2文件列表测试file = new File("C:\\Users\\admin\\Desktop\\项目文件\\个人项目\\ready");String[] listName = file.list();System.out.println(Arrays.toString(listName));/**常用 listFiles() 因为返回值类型时 File[]* 可以拿到一个个的 File 对象做进一步操作*/File[] fs = file.listFiles();System.out.println(Arrays.toString(fs));System.out.println(fs[0].length());}
}

文件/文件夹属性

方法名 说明
length() 查看文件的字节量
exists() 是否存在,存在返回 true
isFile() 是否为文件,是文件返回 true
isDirectory() 是否为文件夹,是文件夹返回 true
getName() 获取文件/文件夹名
getParent 获取父文件夹的路径
getAbsolutePath() 获取文件的完整路径

创建与删除

方法名 说明
createNewFile() 新建文件,文件夹不存在会异常,文件已经存在返回 false
mkdir() 新建单层不存在的文件夹
mkdirs() 新建多层不存在的文件夹
delete() 删除文件/空文件夹

文件夹列表

方法名 说明
list() 返回 String[],包含文件名
listFiles() 返回 File[],包含文件对象

【JAVA SE】第十二章 流(Stream)、IO流和文件(File)相关推荐

  1. 疯狂JAVA讲义---第十二章:Swing编程(五)进度条和滑动条

    http://blog.csdn.net/terryzero/article/details/3797782 疯狂JAVA讲义---第十二章:Swing编程(五)进度条和滑动条 标签: swing编程 ...

  2. java se系列(十二)集合

    1.集合 1.1.什么是集合 存储对象的容器,面向对象语言对事物的体现,都是以对象的形式来体现的,所以为了方便对多个对象的操作,存储对象,集合是存储对象最常用的一种方式.集合的出现就是为了持有对象.集 ...

  3. JAVA SE(第n-1天)(IO流)

    目录 IO流 File类 绝对路径与相对路径 递归算法删除非空目录 IO流 IO流 File类 1.File类1.File类是Java为文件这块的操作(增删改查)而设计的相关类.2.File类的包名是 ...

  4. 怎么用stata打开dta文件_第三十二章、用c语言打开文件

    这一章我们先来了解一下文件是什么? 一个文件通常就是磁盘上的一段命名的存储区.如我们在C语言编程中经常引入的stdio.h就是一个包含一些有用信息的文件的名称.当然对于操作系统来说,文件就会更复杂一些 ...

  5. 深入理解Java虚拟机——第十二章——Java内存模型与线程

    硬件效率与一致性 处理器需要与内存交互,但处理器运算速度与对内存的I/O操作速度相差几个数量级,因此现代操作系统不得不加入尽可能接近处理器运算速度的高速缓存来作为内存与处理器之前的缓冲.这样处理器就不 ...

  6. java lambda表达式_凯哥带你从零学大数据系列之Java篇---第二十二章:Lambda表达式...

    温馨提示:如果想学扎实,一定要从头开始看凯哥的一系列文章(凯哥带你从零学大数据系列),千万不要从中间的某个部分开始看,知识前后是有很大关联,否则学习效果会打折扣. 系列文章第一篇是拥抱大数据:凯哥带你 ...

  7. 【Java数据结构与算法】第十二章 哈夫曼树和哈夫曼编码

    第十二章 哈夫曼树和哈夫曼编码 文章目录 第十二章 哈夫曼树和哈夫曼编码 一.哈夫曼树 1.基本术语 2.构建思路 3.代码实现 三.哈夫曼编码 1.引入 2.介绍 3.代码实现哈夫曼编码综合案例 一 ...

  8. 读书笔记-《ON JAVA 中文版》-摘要12[第十二章 集合]

    文章目录 第十二章 集合 1. 泛型和类型安全的集合 2. 基本概念 3. 添加元素组 4. 集合的打印 5. 列表List 6. 迭代器Iterators 6.1 Iterators 6.2 Lis ...

  9. CoreJava 笔记总结-第十二章 并发-2

    文章目录 第十二章 并发 `synchronized`关键字 同步块 监视器概念 `volatile`字段 `final`变量 原子性 死锁 线程安全的集合 阻塞队列 映射条目的原子更新 对并发散列映 ...

最新文章

  1. jQuery的Tab插件 Tabtastic
  2. 独家 | 在数据科学中需要多少数学技能?(附链接)
  3. HDOJ_ACM_折线分割平面
  4. 对当前JAVA流行框架的一些小感悟
  5. Android 事件分发,分发机制
  6. 普惠数据科学应用,九章云极携手伙伴共探智慧未来
  7. 【idea】idea快捷键(更新中....)
  8. (38)时钟延迟约束
  9. 如何在windows10电脑上创建ftp站点
  10. 升级Windows 10 正式版过程记录与经验
  11. Python检查批量URL是否可以正常访问
  12. 如何在工具类中注入Service
  13. Python 数独求解
  14. 我的计算机梦想作文,我的梦想作文600字
  15. Opencv4.2 DNN模块 终于支持Nividia GPU了!
  16. Key was created with errors:报错
  17. 微分与导数之一,切线
  18. USB 为什么一般选择48MHz
  19. 厦门八大美院墙绘 茶馆里的中国风墙绘壁画
  20. 分享一个无需账号完全免费的 ChatGPT-4 的方法

热门文章

  1. jmeter java 关联_使用Jmeter进行数据关联和并发用户
  2. java 实现一套流程管理、流转的思路(伪工作流) 【仅供参考】
  3. Qt之QToolButton
  4. POJ1993+矩阵相乘
  5. axios 超时_聊聊 Vue 中 axios 的封装
  6. ElasticSearch核心基础之索引管理
  7. (20)Xilinx PCIE中断调试成功(学无止境)
  8. (238)数字IC工程师核心技能树(一)
  9. (27)FPGA计数器设计(硬核实现)
  10. (54)Verilog HDL下升沿采样