IO流的总结和File类的总结

IO流

一.为什么要学习IO流?

  1. 我们以前的数据都是存放在内存里的—程序一旦关闭,数据就会丢失.
  2. 我们可以通过IO远程传输数据(网络编程).

内存:不能永久存储数据,断电后(或关闭程序后),内存的数据就会被擦除.

硬盘:数据存储的一种介质,只要硬盘不坏,数据就会永久保存.

File类

用来描述文件(或者文件夹),文件是否是可执行文件,文件是否可读,是否只写,文件多少个字节,文件的名称,文件的绝对路径,还可以操作文件或者文件夹 新建文件,新建文件夹.等等…File类只能操作文件或者文件夹本身(修改名称,创建文件夹…),但是不能操作文件里面的内容.写数据和读数据需要使用IO流

一.文件路径:绝对路径,相对路径

  1. 绝对路径:从盘符名开始计算的一个路径.
  2. 相对路径:相对参照物的一个路径,例如本身在文件夹aa中,如果路径是bb.txt,表示你是aa/bb.txt.
//File对象创建---并不是创建了一个文件,而是创建一个代表文件的对象.
File file1 = new File("路径");
File file2 = new File("半截路径","半截路径");
IO流

一.IO:input输入,output输出.流(Stream)

  1. 输入:把外部数据(硬盘,网络)读入程序为输入.
  2. 输出:把程序中的数据写到硬盘或者网路,称为输出.

二.IO流的分类:

  1. 根据流向划分:输入流,输出流
  2. 根据传输内容的单位:字节流(byte 1字节) 字符流(char 2字节)
  3. 根据功能划分:缓冲流,普通流,转换流.

在存储的时候都是以2进制的形式存放,所以任何文件都可以以字节流的方式读取或者写入.因为电脑有大量的文本文档.为了方便,提供字符流.

一.InputStream字节输入流是抽象类

  • FileInputStream 文件输入流这个类。

一.这个类由若干个构造方法,其中两个比较常用,罗列如下:

  1. FileInputStream(String filename) : 通过文件路径,获得文件输入流
  2. FileInputStream(File file) :通过文件对象,获得文件输入流。

需要注意的是,FileInputStream 在创建对象的时候,当要读取的文件不存在时,就会抛出异常:FileNotFoundException。由于这是一个已检查异常,因此必须要处理。

  1. available()//获取文件的字节数.
  2. close()//关闭流.创建流之后必须关闭.
  3. read()//一次读取一个字节没有内容返回-1.可以写一个循环,条件是(((n = fis.read)) != -1).要有光标的概念.
  4. read(byte[] b)//将文件中的内容读到数组中,并返回读了几个字节.如果没有内容可读,会返回-1.
  5. skip(2);//跳过指定数量的字节.

二.输入流的用法:

  1. 创建输入流对象.FileInputStream fis = new FileInputStream (“路径”)
  2. read方法读取内容 int length = fis.read(xxx);
  3. 关闭流.

二.OutputStream字节输出流是抽象类

把程序中的数据,写入到文件(或者网络).

一.想要从程序输出内容到文件步骤:

  1. 创建一个FileOutputStream(需要指定一个路径)
  2. 通过write方法把数据写入文件
  3. 关闭流.
  • FileOutputStream文件输出流

文件输出流—把程序中的数据写入文件.

//后面是true,对内容进行追加.不写或者写成false就是覆盖.
FileOutputStream fos = new FileOutputStream(file, true);
fos.write(内容)//把输入的内容全部写入文件.

//实现文件拷贝

//思路:首先有一个目标(你要拷贝谁,其实就是要把谁读入程序,其次,要把内容写到哪)
String originFilePath = "aaa.txt";
String destFilePath = "bbb.txt";
//创建输入流
FileInputStream fis = new FileInputStream ("originFilePath");
//创建输出流
FileOutputStream fos = new FileOutputStream(destFilePath, true);
byte[] arr = new byte[1024];
int length = 0;
while((length = fis.read(arr)) > 0){
    //一共读了多少次
    System.out.println(length);
    String str = new String(arr,0,length);
    //输出到控制台
    System.out.println(str);
}
fis.close();
fos.close();

所有文件(rar,mp3,mp4…)都可以靠字节流读取以及写入,因为数据在硬盘上保存成二进制的.8个二进制位一个字节.

由于文本文件非常常见(.Java, .txt, .md …),所以系统专门提供合理字符的输入输出.

字节流是万能的,但是字符流只能读写文本文件.

三.Reader字符输入流

用于读取字符流的抽象类.

  • FileReader文件字符输入流

是Reader的子类,他可以从文件中读取字符.

一.字符输入流的使用步骤:

  1. 创建输入流对象.FileReader fr = new FileReader(“路径”).
  2. read方法读取内容 int length = fr.read(xxx);
  3. 关闭流.

char[] arr = new char[1024];//创建字符数组保存

int length = fr.read(arr);//把内容读到arr数组中,并返回读了多少个字符.

String str = new String(arr, 0, length);//转换成字符串中.

四.Writer字符输出流

主要作用就是往文件里面写入字符,字符流的优势可以写入.

  • FileWriter文件字符输出流

一.字符输出流的使用步骤:

  1. 创建输入流对象.FileWriter fw = new FileWriter(“路径”).
  2. read方法读取内容 int length = fr.write(xxx);
  3. 关闭流.fw.close();

如果想要通过字符流写入数据到文件

fw.write(内容);写入文件中的内容.

fw.append(内容);末尾追加.

五.缓冲输入流

缓冲流:对咬传输的数据进行缓冲,可以提高效率.

缓冲输入流:会有一个缓冲区(你可以认为是一个数组,这个数组默认是8k),如果是字节流byte[8192] 字符流char[8192],当你需要读取内容的时候,限度如这个缓冲区(读入这个数组),如果你写的代码要读1024.它会从8192里给你提取1024,这样做的好处就是减少程序频繁读文件.内存的速度是硬盘的几百倍甚至是几千倍.

//缓冲的输出流:会有一个缓冲区(你可以认为是一个数组,这个数组默认是8k),如果是字节流byte[8192] 字符流char[8192],当你需要写入内容的时候,这个时候没有真正的往文件写入,而是写入到了这个缓冲区(写入到了数组),当缓冲区满的时候,会往文件里面写,或者强制写(flush()),这样坚守了写入文件的频率.

缓冲流4个:

  • 字节BufferedInputStream 字节缓冲输入流
  • 字节BufferedOutputStream字节缓冲输出流
  • 字符BufferedReader 字符缓冲输入流
  • 字符BufferedWriter字符缓冲输出流

缓冲流要对其他流进行包装,增强他们的功能,能让他们有缓冲的功能,提高效率.

平时我们不会直接使用FileInputStream,也不会直接使用FileOutputStream .我们会拿字节BufferedInputStream 字节缓冲输入流和BufferedOutputStream字节缓冲输出流,提高读写速率.

缓冲区不满的时候,是不会给你写入的,慢的时候才会给你写入,如果想在不满就写入可以调用flush方法.

根据流向分为 输入流和输出流
根据传输的内容: 字符流 和字节流
字符输入流Reader(抽象类) 字符输出流Writer(抽象类)
文件字符输入流FileReader 文件字符输出流FileWriter
缓冲字符输入流BufferedReader 缓冲字符输出流BufferedWriter
缓冲流要包装普通流(普通流是缓冲流的参数)
读内容 read
写内容write

字节输入流InputStream(抽象类) 字节输出流OutputStream(抽象类)
文件字节输入流FileInputStream 文件字节输出流FileOutputStream
缓冲字节输入流BufferedInputStream 缓冲字节输出流BufferedOutputStream
缓冲流要包装普通流(普通流是缓冲流的参数)
读内容 read
写内容write

六.数据流

  • 字节数据输入流DataInputStream dis = new DataInputStream();

提供了一系列把数据读成基本数据类型的方法,也提供把数据读成合理字符串的方法

  • 字节数据输出流DataOutputStream dos = new DataOutputStream ();

提供了一系列基本数据类型存入文件的方法,也提供合理字符串存入文件的方法

读取顺序需要和存入数据一致.

七.对象流(字节流)

  • 对象输入流ObjectInputStream把文件中的数据读成Java对象.—反序列化.简单理解为解压苏.根据序列化规则,反向解析字节数据.
  • 对象输出流ObjectOutputStream把程序中的对象写入到文件—序列化(也称为归档).简单理解为压缩.在存入文件的时候对数据进行标记,标记的目的是为了以后能够正确的读出来.

ObjectOutputStream包含了DataOutputStream 全部的功能,而且还能写入对象.

第一个文件起始字节是几,结束字节是几.第二个文件文件起始字节是几,结束字节是几.

自定义对象必须实现Serializable接口,如果一个接口里面没有任何方法,那么这个接口称为标记型接口.如果我们要把容器(list,set,map)存入文件,容器里面的元素要实现Serializable接口.

八.转换流

  • InputStreamReader主要是将字节流输入流转换成字符输入流.
  • OutputStreamWriter主要是将字节流输出流转换成字符输出流.

被读的文件有一种编码格式,我们读取的时候,也会用一种编码格式读取.

解决方法:以字节流读取.

平时可以用FilerReader BufferedReader 读文件内容,如果文本内容出现乱码了,我们才使用转换流.先用字节流读文件, 再把字节流转换为字符流(转换的时候指定字符集,只要我们指定的字符集和文件本身的字符集一致,就不会出现乱码).

平时可以用FileWriter BufferedWriter 向文本内写入内容.如果别人双击打开出现乱码,说明我们写入时的字符集和他查看时使用的字符集不同.出现乱码之后, 我们可以修改程序,使用转换流先用字节流写文件, 再把字节流转换为字符流(转换的时候指定字符集,只要我们指定的字符集和查看文件时使用的字符集一致,就不会出现乱码).

九.打印流

  • printStream字节输出流
  • printWriter字符输出流继承于Writer类.所以Writer类中的方法都可以使用.除了继承的方法还有自己的方法.
  1. PrintWriter pw = new PrintWriter(“ccc.txt”);
  2. pw.format(%s 字符串, %d 整数, %.2f 显示小数点后两位); (%1 s , s, %2 s,s,“第一个占位符”,“第二位占位符”)
  3. pw.print()

Scanner类叫做扫描器类,作用是从指定输入源里提取文件.

无论使用那种流,都离不开一下步骤:

  1. 创建流对象,通常会有一个检查异常(编译器,非RuntimeException) FileNotFoundExecption
  2. 执行读或写.
  3. 关闭流.

流的创建一般写到try里面 ----FileNotFoundExecption IOException但是我们流的关闭通常不写try里面为什么呢?
因为有可能在close之前,出现异常,导致close执行不到.为了解决这个问题我们把流的关闭(close)写到finally里面.流有可能创建失败, 创建失败之后 fr它的值还是null br也是null 如果在br是null的时候 调用close方法 会出现空指针异常.所以说应该加个判断条件, 如果流对象不是null,才去关闭.这样太麻烦了.

如何优雅的关闭流—try with resource语法块(语法糖),他的实现逻辑是autoclose自动关闭.try with resource这个语法只能适用于Autocloseable接口.在整个Java体系里,凡是需要关闭的东西(流,连接,等等),都已经实现了Autocloseable接口,所以都能使用try with resource语法.

//把实现了Autocloseable接口对象的创建写到try的小括号里.但是只有实现了Autoclosable的对象才可以在try()的小括号里new
try(
    //在小括号里面创建需要关闭的对象,--就是流对象的创建写在小括号里面,
   // 写在小括号里的对象,用完之后,会自动关闭,相当与你自己写了一套完美的finally关闭流的代码,凡是写在try()小括号里的new都会被关闭
   ){
   //流的使用写在大括号里 
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值