IO流详解
定义:什么是IO流?简单来说就是输入输出流,就是读取与写入,什么又是流呢?
io流大致分类:
按流向分:输入流、输出流
按流类型分:字节流、字符流
什么是字节流、字符流呢?他们之间的异同点呢?
字节流,字面上含义,用字节传输,不管是读取还是写入,都是用字节传输,范围很广,如音频、视频、文本文件等,而字符流,就是用字节读取和写入,只能读取文本文件。
先说说字节流?
InputStream是字节输入流(读取),OutputStream是字节输出流(写入),这两个类都是抽象类,不能实例化对象,通过子类实现其功能。先看看他们的子类有哪些常用的?
io流代码展示
1.字节流
效果都是实现复制(先读取,后写入)
- 字节输入流:用法与输出可以对照 * java.io.inputstream *作用:读取任意文件,每次只读取1个字节 *
读取方法:read * int read() 读取1个字节 * int read(byte[] b) 读取一定量的字节数组
```java
/**
* 功能简述:FileInputStream 读取文件
* 构造方法:为这个流对象绑定数据源
* 参数:
* File 类型对象
* String 对象
* 输入流读取文件的步骤:
* 1.创建字节输入流的子类对象
* 2.调用读取方法read
* 3.释放资源
* read方法:
* read()执行一次就会自动读取下一个字节
* 返回值,返回的是读取的字节
*/
public class FileInputStreamDemo {
@Test
public void test1() {
FileInputStream fis = null;
try {
fis = new FileInputStream("F:\\桌面\\java\\output.txt");
//读取一个字节,调用方法read,返回int
/*int i = fis.read();
System.out.println(i);
i = fis.read();
System.out.println(i);
i = fis.read();
System.out.println(i);
i = fis.read();
System.out.println(i);*/
//使用循环方式,读取文件,循环结束条件 read() 方法 返回 -1
int len = 0;//接受read返回的值
while((len = fis.read()) != -1){
System.out.print((char)len);//默认输出AscII码值
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
//关闭资源
finally {
try {
if (fis != null) fis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
/**
* read(byte[] bytes) 读取字节数组
* 数组重用:缓冲作用
* read 返回的int 表示含义:读取有效字节的个数
*/
@Test
public void test2(){
FileInputStream fis = null;
try {
fis = new FileInputStream("F:\\桌面\\java\\output.txt");
byte[] bytes = new byte[1024];//一次性读取多少字节,读取时,将字节放入数组中,每次都覆盖之前的
/* int len = fis.read(bytes);//返回读取有效字节个数
String str = new String(bytes);
System.out.println(str);*/
//循环读取效率高
int len = 0;
while ((len = fis.read(bytes)) != -1){//0表示从0开始索引,len每次截取有效字节
System.out.println(new String(bytes,0,len));//将new String(bytes),bytes打印是地址,后者是打印数组内容
}
} catch (FileNotFoundException e) {
e.printStackTrace();
}catch (IOException e) {
e.printStackTrace();
}
//关闭资源
finally {
try {
if (fis != null) fis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
功能简述: * * 字节输出流: * *java.io.outputstream 所有字节输出流的超类 * *
作用:从java程序,写出文件 * * 字节:这样流每次自操作文件中的1个字节 * * 写任意文件 * * 方法都是写入的方法
- write(int b) 写入1个字节 * * write (byte[] b) 写入字节数组 * * write(byte[] b,int set,int len)写入字节数组,开始写入的索引,以及写几个 * *
close(),关闭对象,释放与此流相关的资源 * * 流对象,操作文件的时候,自己不做,依赖操作系统。
/**
* * 功能简述:
* @author 23801
* @version 1.0.0
* @create 2020/7/12
* @Date 2020/7/12 16:52
*/
public class FileOutputStreamDemo {
/**
* * 功能简述:
* *FileOutputStream
* * 写入数据文件,学习父类方法,使用子类对象
* * 子类的构造方法:作用:绑定输出的输出的目的
* * 参数:
* * file 封装文件
* * string 字符串的文件名
* * 流对象的使用步骤
* * 1.创建流子类的对象,绑定数据目的
* * 2.调用流对象的write方法
* * 3.close关闭资源
* *
* * 流对象的构造方法,没有即创建,有即覆盖
*/
@Test
public void test1() {
FileOutputStream fos = null;
try {//try外面声明变量,里面建立对象
fos = new FileOutputStream("F:\\桌面\\java\\output.txt");
//流对象的方法write写数据
//写一个字节
// fos.write(100);//将100转为二进制输出到out.txt,out.txt对照AsCii码
//一个数字一个字节,一个汉字两个字节,一个字节八位二进制
byte[] bytes = {89,78,49,48,56};
//fos.write(bytes); //字节数组写出
//fos.write(bytes,1,2);//写出字节数组一部分
// fos.write("hello".getBytes());
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
System.out.println(e.getMessage());
throw new RuntimeException("文件写入失败,重试");
}
//关闭资源,抛出异常后,一案执行
finally {
try {
if(fos != null)
fos.close();
} catch (IOException e) {
throw new RuntimeException("关闭资源失败,重试");
}
}
}
/**
* 功能描述:
* fileoutputstream 文件的续写和换行
* 续写:fileoutputstream(file/string,boolean) 第二个参数,加入 true
* 换行:符号换行\r\n,
* @param :
* @return:
* @Author:
* @Date:
*/
@Test
public void test2(){
File file = new File("F:\\桌面\\java\\output.txt");
FileOutputStream fos = null;
try {
fos = new FileOutputStream(file,true);
fos.write("hello".getBytes());
fos.write("\r\nfileoutputstream".getBytes());
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
throw new RuntimeException("写入文件失败,重试");
}
//关闭资源,抛出异常后,一案执行
finally {
try {
if(fos != null)
fos.close();
} catch (IOException e) {
throw new RuntimeException("关闭资源失败,重试");
}
}
}
/**
* 功能描述:
* Io流的异常处理:
* try catch finally
* 细节:
* 1.保证流对象变量,作用域足够
* 2.catch里面,怎么处理异常:输出异常信息,目的查看问题所在
* 停下程序,重新尝试
* 3.假如流对象建立失败,不需要关闭资源
* 所以释放资源时,对流对象判断是否null
* @param :
* @return:
* @Author:
* @Date:
*/
public void testIOException() {
}
实现文件复制效果代码
@Test
public void copyUtils(){
FileInputStream fis = null;
FileOutputStream fos = null;
try {
fis = new FileInputStream("F:\\桌面\\java\\input.txt");
fos = new FileOutputStream("F:\\桌面\\java\\output.txt");
int len = 0; //读取一个字节就写入一个字节
while((len = fis.read()) != -1){
fos.write(len);//int就是其对应的AscII码
System.out.println((char)len);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
throw new RuntimeException("文件复制失败");
}
//释放资源
finally {
if(fis != null) {
try {
fis.close();
} catch (IOException e) {
throw new RuntimeException("输入流关闭失败");
}
//即使输入流关闭失败,也要执行finally
finally {
if(fos != null) {
try {
fos.close();
} catch (IOException e) {
throw new RuntimeException("输出流关闭失败");
}
}
}
}
}
}
2.字节流
- 功能简述: *字符输入流:读取文本文件,所有的字符输入流的超类 * java.io.reader *读取方法: * int
read() 读取一个字符 * int read(char[] c)读取字符数组 * * Reader抽象类,其子类对象
FileReader * 构造方法:绑定数据源 * 参数: * file 类型对象 * string
字符串
/**
* 功能简述:
*
* @author 23801
* @version 1.0.0
* @create 2020/7/12
* @Date 2020/7/12 19:50
*/
public class FileReaderDemo {
@Test
public void test() throws IOException {
FileReader fr = null;
fr = new FileReader("F:\\桌面\\java\\output.txt");
int len = 0;
while((len = fr.read()) != -1){
System.out.print((char)len);
}
fr.close();
}
/**
* 采用字符数组提高效率
* @throws IOException
*/
@Test
public void test2() throws IOException{
FileReader fr = null;
char[] c = new char[1024];
fr = new FileReader("F:\\桌面\\java\\output.txt");
int len = 0;
while((len = fr.read(c)) != -1){
System.out.print(new String(c,0,len));
}
fr.close();
}
/**
* 采用字节数组缓冲提高效率
* 文本,音频,图片,文件
*/
@Test
public void copyUtisBuffer(){
FileInputStream fis = null;
FileOutputStream fos = null;
try {
fis = new FileInputStream("E:\\computernecessarysoft\\bandzip\\BANDIZIP-SETU-6.13.0.1.EXE");
fos = new FileOutputStream("F:\\桌面\\java\\BANDIZIP-SETU-6.13.0.1.EXE");
int len = 0; //读取一个字节就写入一个字节
byte[] bytes = new byte[1024];
while((len = fis.read(bytes)) != -1){
fos.write(bytes);//int就是其对应的AscII码
//System.out.println(new String(bytes,0,len));
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
throw new RuntimeException("文件复制失败");
}
//释放资源
finally {
if(fis != null) {
try {
fis.close();
} catch (IOException e) {
throw new RuntimeException("输入流关闭失败");
}
//即使输入流关闭失败,也要执行finally
finally {
if(fos != null) {
try {
fos.close();
} catch (IOException e) {
throw new RuntimeException("输出流关闭失败");
}
}
}
}
}
}
}
- 功能简述: * 字符输出流: * java.io.writer 所有字符输出类的超类 * 只能用于文本文件,写文件, * 写的方法 writer
- writer(int c ) 写一个字符
- writer(char[] c) 字符数组
- writer(char[] c,int set,int len)字符数组一部分,开始索引,截取长度
- writer(string s) 写入字符串
- writer类的子类对象FileWriter *构造方法:写入的数据目的 * File 类型对象 * string 文件名
/**
* 功能简述:
*
* @author 23801
* @version 1.0.0
* @create 2020/7/12
* @Date 2020/7/12 19:36
*/
public class FileWriterDemo {
/*
字符输出流写数据的时候,必须要先刷新
*/
@Test
public void test(){
FileWriter fw = null;
try {
fw = new FileWriter("F:\\桌面\\java\\output.txt");
//写一个字符
/* fw.write(48);
fw.flush();*/
//写入字符数组
//char[] c = {'a','b','c','d'};
/*fw.write(c);
fw.flush();*/
//写入一部分数组
/* fw.write(c,0,2);
fw.flush();*/
//写入字符串
fw.write("hello");
fw.flush();
} catch (IOException e) {
e.printStackTrace();
}finally {
if(fw != null) {
try {
fw.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
实现文本文件效果图复制
/**
* 使用字符数组复制文本文件
*/
@Test
public void copyUtisChars(){
FileWriter fw = null;
FileReader fr = null;
try {
fw = new FileWriter("F:\\桌面\\java\\input.txt");
fr = new FileReader("F:\\桌面\\java\\output.txt");
char[] ch = new char[1024];
int len = 0;
while((len = fr.read(ch)) != -1){
fw.write(ch);
fw.flush();
System.out.print(new String(ch));
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} //释放资源
finally {
if(fr != null) {
try {
fr.close();
} catch (IOException e) {
throw new RuntimeException("输入流关闭失败");
}
//即使输入流关闭失败,也要执行finally
finally {
if(fw != null) {
try {
fw.close();
} catch (IOException e) {
throw new RuntimeException("输出流关闭失败");
}
}
}
}
}
}
2.转换流
/**
- 功能简述: * InputStreamReader 读取文件 *
OutputStreamWriter(OutputStream out) 接收所有的字节输出流 *
InputStreamReader(InputStream input) 接收所有的字节输入流 * 可以传递的字节输入流
:FileInputStream * InputStreamReader(InputStream in,String
charsetName) 传递编码表名字
public class InputStreamReaderDemo {
/**
* 采用默认编码表GBK
* @throws IOException
*/
@Test
public void ReaderGBK() throws IOException {
FileInputStream fis = new FileInputStream("F:\\桌面\\java\\input.txt");
InputStreamReader isr = new InputStreamReader(fis);
int len = 0;
char[] str = new char[10];
while((len = isr.read(str)) != -1){
System.out.print(new String(str).getBytes().length);
}
isr.close();
}
@Test
public void ReaderUTF() throws IOException {
FileInputStream fis = new FileInputStream("F:\\桌面\\java\\input.txt");
InputStreamReader isr = new InputStreamReader(fis,"UTF-8");
int len = 0;
char[] str = new char[1024];
while((len = isr.read(str)) != -1){
System.out.print(new String(str).getBytes().length);
}
isr.close();
}
- 功能简述:转换流(可以修改编码表) * *字符通向字节的桥梁,查码表,将字符流转字节流)() * outputStreamwriter 使用方式 继承Writer * 构造方法: *
outputstreamWriter(outputStream out)接收所有的字节输出流 *
但是:字节输出流:FileOutputStream * outputStreamWriter(outputstream out,
String charsetName) * String charsetName 传递编码表名字GBK, UTF-8 * *
outputStreamWriter 有个子类 FileWriter(需要手动flush,常用)默认FileReader与操作系统一样
public class OutputStreamWriterDemo {
/**
* 转换流对象OutputStreamWriter写文本
* 文本采用GBK的形式写入
* @throws FileNotFoundException
*/
@Test
public void WriterGBK() throws IOException {
//创建字节输出流,绑定数据目的
FileOutputStream fos = new FileOutputStream("F:\\桌面\\java\\input.txt");
//创建转换流对象,构造方法,绑定字节输出流,使用GBK编码类
OutputStreamWriter osw = new OutputStreamWriter(fos);
//转换流写数据
osw.write("你好");
osw.close();//关闭osw后,自动给关闭fos
}
/**
* 转换流对象OutputStreamWriter写文本
* 文本采用GBK的形式写入
* @throws FileNotFoundException
*/
@Test
public void WriterUTF() throws IOException {
//创建字节输出流,绑定数据目的
FileOutputStream fos = new FileOutputStream("F:\\桌面\\java\\input.txt");
//创建转换流对象,构造方法,绑定字节输出流,使用Utf编码类
OutputStreamWriter osw = new OutputStreamWriter(fos,"UTF-8");
//转换流写数据
osw.write("你好");
osw.close();//关闭osw后,自动给关闭fos
}
}
3.缓冲流
4.序列化与反序列化
5.打印流