您的位置:首页 > 游戏 > 手游 > Java高级编程—I/O流(包括字节输入流、字节输出流、字符输出流、字符输入流、缓冲流、序列化流、反序列化流等,详解 附有代码+案例)

Java高级编程—I/O流(包括字节输入流、字节输出流、字符输出流、字符输入流、缓冲流、序列化流、反序列化流等,详解 附有代码+案例)

2024/10/6 8:28:21 来源:https://blog.csdn.net/weixin_54555405/article/details/141893377  浏览:    关键词:Java高级编程—I/O流(包括字节输入流、字节输出流、字符输出流、字符输入流、缓冲流、序列化流、反序列化流等,详解 附有代码+案例)

文章目录

  • 二十七.I/O流
    • 27.1概述
    • 27.2 分类
    • 27.3 字节输出流
      • 27.3.1 数据写入本地文件
      • 27.3.2 换行、续写
    • 27.4字节输入流
      • 27.4.1 读取数据到程序
      • 27.4.2 循环读取
      • 27.4.3 拷贝数据
      • 27.4.4 一次读取多个
    • 27.6 字符输入流
      • 27.6.1 FileReader的使用
    • 27.7 字符输出流
    • 27.8. 缓冲流
      • 27.8.1 字节缓冲流
        • 27.8.1.1拷贝文件(一)
        • 27.8.1.2 拷贝文件(二)
      • 27.8.2字符缓冲流
        • 27.8.2.1字符缓冲输入流
        • 27.8.2.2 字符缓冲输出流
      • 27.8.3 Test
    • 27.9 转换流
      • 27.9.1概述
      • 27.9.2Test
        • 27.9.2.2 test02
        • 27.9.2.3 test03
        • 27.9.2.4 test04
    • 27.10 序列化流
    • 27.11 反序列化流

二十七.I/O流

(遇见异常直接抛,默认采用alt+enter提示的第一种方式处理异常)

27.1概述

什么是I/O流:存储和读取数据的解决方案

作用:用于读写数据

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

27.2 分类

按照流向区分:

  • 输入流 :把数据从其他设备上读取到内存中的流。
  • 输出流 :把数据从内存 中写出到其他设备上的流。

在这里插入图片描述

按照操作文件的类型分:

  • 字节流:操作所有类型的文件,以字节为单位,读写数据的流。
  • 字符流:只能操作纯文本文件,以字符为单位,读写数据的流。

用windows系统自带的记事本打开且能读懂的文件为纯本文文件,包括txt文件,md文件,xml文件,lrc文件,等等…

在这里插入图片描述

27.3 字节输出流

FileOutStream:字节输出流

27.3.1 数据写入本地文件

FileOutStream:可以把程序中的数据写到本地文件上,是字节流的基本流。

  • 创建字节输出流对象

    细节1:参数是字符串表示的路径或者是File对象都是可以的
    细节2:如果文件不存在会创建一个新的文件,但是要保证父级路径是存在的。
    细节3:如果文件已经存在,则会清空文件.(如果文件已经存在内容,则会清空文件原有内容,然后写入的新内容)
    
  • 写数据

    write方法的参数是整数,但是实际上写到本地文件中的是整数在ASCII上对应的字符

  • 释放资源

    每次使用完流之后都要释放资源,解除占用

方法名说明
void write(int b)一次写一个字节数据
void write(byte[] b)一次写一个字节数组数据
void write(byte[] b, int off, int len)一次写一个字节数组的部分数
import java.io.FileOutputStream;
import java.io.IOException;public class Test01 {public static void main(String[] args) throws IOException {FileOutputStream fos = new FileOutputStream("code_java02\\kwh.txt");byte[] bytes = {97,98,99};fos.write(97);// afos.write(bytes);// a b c fos.write(bytes,0,2);// a bfos.close();}
}

27.3.2 换行、续写

import java.io.FileOutputStream;
import java.io.IOException;public class Test02 {public static void main(String[] args) throws IOException {//默认false:关闭续写,会清空文件// true:打开续写开关,不会清空文件FileOutputStream fos = new FileOutputStream("code_java02\\kwh.txt",true);String str = "nihao";// 将字符串编程字节数组byte[] bytes1 = str.getBytes();fos.write(bytes1);// 换行String str2 = "\r\n";byte[] bytes2 = str2.getBytes();fos.write(bytes2);String str3 = "tianqihenhao";byte[] bytes3 = str3.getBytes();fos.write(bytes3,0,bytes3.length);fos.close();}
}

27.4字节输入流

FileInputStream:字节输入流

27.4.1 读取数据到程序

操作本地的字节输入流,把本地文件的数据读取到程序中。

  • 创建字节输入流对象

    如果文件不存在,就直接报错。

  • 读数据

    一次读一个字节,读出来的是数据在ASCII上对应的数字

    读到文件末尾处没有数据,read方法返回-1

  • 释放资源

import java.io.FileInputStream;
import java.io.IOException;public class Test03 {public static void main(String[] args) throws IOException {// 创建字节输入流对象;    kwh.txt里有abcFileInputStream fis = new FileInputStream("code_java02\\kwh.txt");// 读数据int read = fis.read();System.out.println(read);//97fis.close();}
}

27.4.2 循环读取

一次循环读取一个字节

import java.io.FileInputStream;
import java.io.IOException;public class Test04 {public static void main(String[] args) throws IOException {// 创建对象  kwh.txt里有abcFileInputStream fls = new FileInputStream("code_java02\\kwh.txt");// 定义变量,记录读取的数据int b ;// b =fls.read();// System.out.println(b);//97// 循环读取//read :表示读取数据,而且是读取一个数据就移动一次指针while ((b =fls.read()) != -1){System.out.print((char) b);}// 释放资源fls.close();}
}

27.4.3 拷贝数据

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;public class Test05 {public static void main(String[] args) throws IOException {FileInputStream fis = new FileInputStream("E:\\software\\ideak\\ideapro\\kwhcode\\code_java02\\kkk.txt");FileOutputStream fos = new FileOutputStream("code_java02\\www.txt");// 定义变量,记录读取的数据int b;// 边读边写//一次读写一个字节while ((b= fis.read()) != -1){fos.write(b);}// 释放资源fis.close();fos.close();}
}

27.4.4 一次读取多个

方法说明
public in read()一次读取一个字节
public int read(byte[] buffer)一次读一个字节数组数据
import java.io.FileInputStream;
import java.io.IOException;public class Test06 {public static void main(String[] args) throws IOException {// kwh.txtl里有abcFileInputStream fis = new FileInputStream("code_java02\\kwh.txt");// 定义一个长度为2的字符数组,表示每次读取2个字节//将读到的数据再返回到数组bytes中byte[] bytes = new byte[2];//一次读取多个字节数据,具体读多少,跟数组的长度有关//返回值:本次读取到了多少个字节数据int len1 = fis.read(bytes);System.out.println(len1);//2//将bytes数组从0索引开始,一共把len1个字节变成字符串String str1 = new String(bytes,0,len1);System.out.println(str1);//abint len2 = fis.read(bytes);System.out.println(len2);// 1String str2 = new String(bytes,0,len2);System.out.println(str2);//c// int len3 = fis.read(bytes);// System.out.println(len3);//-1// String str3 = new String(bytes);// System.out.println(str3);//cbfis.close();}
}
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;public class Test07 {public static void main(String[] args) throws IOException {FileInputStream fis = new FileInputStream("E:\\software\\ideak\\ideapro\\kwhcode\\code_java02\\hhh.txt");FileOutputStream fos = new FileOutputStream("code_java02\\hhh02.txt");byte[] bytes = new byte[1024 * 1024 * 5];// 定义要读取的数据的长度,即字节数int len;while ((len = fis.read(bytes)) != -1){// 都多少写多少fos.write(bytes,0 ,len);}//释放资源fos.close();fis.close();}
}

27.6 字符输入流

FileReader:字符输入流

使用场景:对纯文本文件进行读写操作。

字符流的底层就是字节流

字符流 = 字节流+字符集

特点:

  • 输入流:一次读一个字节,遇到中文时,一次读多个字节。
  • 输出流:底层会把数据按照指定的编码方式进行编码,变成字节再写到文件中。

27.6.1 FileReader的使用

  • 创建字符输入流对象

    构造方法说明
    public FileReader(File file)创建字符输入流关联本地文件
    public FileReader(String Path)创建字符输入流关联本地文件

    如果文件不存在,就直接报错。

  • 读取数据

    成员方法说明
    public int read()读取数据,读到末尾返回-1
    public int read(char[] buffer)读取多个数据,读到末尾返回-1

    细节1: 按照字节进行读取,遇到中文,一次读多个字节。读取后解 码。返回一个整数。

    细节2: 读到文件末尾,read方法返回-1

  • 释放资源

import java.io.FileReader;
import java.io.IOException;public class Test09 {public static void main(String[] args) throws IOException {// 创建字符输入流对象FileReader fr = new FileReader("code_java02\\a.txt");// 定义读取的字节数//  // 记录读取的汉字解码后的十进制数int ch;//2.读取数据 read()//字符流的底层也是字节流,默认也是一个字节一个字节的读取的。//如果遇到中文就会一次读取多个,GBK一次读两个字节,UTF-8一次读三个字节//read()细节://1.read():默认也是一个字节一个字节的读取的,如果遇到中文就会一次读取多个//2.在读取之后,方法的底层还会进行解码并转成十进制。//  最终把这个十进制作为返回值//  这个十进制的数据也表示在字符集上的数字//  英文:文件里面二进制数据 0110 0001//          read方法进行读取,解码并转成十进制97//  中文:文件里面的二进制数据 11100110 10110001 10001001//          read方法进行读取,解码并转成十进制27721// 想看到中文汉字,就是把这些十进制数据,再进行强转就可以了// 循环读取while ((ch = fr.read()) != -1){// System.out.println(ch);十进制数//把解码出的十进制数强转成对应的字符System.out.print((char) ch);}// 释放资源fr.close();}
}
import java.io.FileReader;
import java.io.IOException;public class Test10 {public static void main(String[] args) throws IOException {FileReader fr = new FileReader("code_java02\\a.txt");// 记录读取的个数int len;// 一次读取两个,并把数据返回到chars数组里char[] chars = new char[2];//read(chars):读取数据,解码,强转三步合并了,把强转之后的字符放到数组当中//相当于空参的read + 强转类型转换while ((len = fr.read(chars)) != -1){// System.out.println(len);//2// 将读取的数据放到chars数组后变成字符串输出System.out.print(new String(chars));}fr.close();}
}

27.7 字符输出流

FileWriter:字节输出流

构造方法说明
public FileWriter(File file)创建字符输出流关联本地文件
public FileWriter(String pathname)创建字符输出流关联本地文件
public FileWriter(File file, boolean append)创建字符输出流关联本地文件,续写
public FileWriter(String pathname, boolean append)创建字符输出流关联本地文件,续写
成员方法说明
void write(int c)写出一个字符
void write(String str)写出一个字符串
void write(String str, int off, int len)写出一个字符串的一部分
void write(char[] cbuf)写出一个字符数组
void write(char[] cbuf, int off, int len)写出字符数组的一部分
import java.io.FileWriter;
import java.io.IOException;public class Test11 {public static void main(String[] args) throws IOException {FileWriter fw = new FileWriter("code_java02\\a.txt",true);//根据字符集进行编码,编码成三个字节写入文件fw.write(25105);fw.write("你好");char[] chars = {'今','天','好'};fw.write(chars);fw.write(chars,0,1);fw.write(chars,1,2);String str = "苹果葡萄";fw.write(str,0,2);fw.close();}
}

27.8. 缓冲流

高级流

在这里插入图片描述

27.8.1 字节缓冲流

原理:底层自带了长度为8192的缓冲区提高性能。

方法名称说明
public BufferedInputStream(InputStream is)把基本流包装成高级流,提高数去数据性能
public BufferedOutputStream(OutputStream os)把基本流包装成高级流,提高数去数据性能
字节缓冲输入流的构造方法:
public BufferedInputStream(InputStream is)字节缓冲输出流的构造方法:
public BufferedOutputStream(OutputStream os)
27.8.1.1拷贝文件(一)

一次读写一个字节

import java.io.*;public class Test01 {public static void main(String[] args) throws IOException {//利用字节缓冲流拷贝文件//将a.txt里的内容写到aa.txt,aa.txt不存在BufferedInputStream bis = new BufferedInputStream(new FileInputStream("code_java02\\filedemo\\a.txt"));BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("code_java02\\filedemo\\aa.txt"));// 记录读取的数据,一次读写一个字节int b;// 循环读取,读取的是缓冲区中数据,一次性读取8192个字节数据while ((b= bis.read()) != -1){// 将读取的数据再写入目的地bos.write(b);}// 关闭流bos.close();bis.close();}
}
27.8.1.2 拷贝文件(二)

一次读写多个字节

package bufferedstreamdemo;import java.io.*;public class Test02 {public static void main(String[] args) throws IOException {// 创建缓冲流对象BufferedInputStream bis = new BufferedInputStream(new FileInputStream("code_java02\\filedemo\\a.txt"));BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("code_java02\\filedemo\\a2.txt"));// 定义数组,将读取的数据存入字节数组//一次读取多个字节byte[] bytes = new byte[1024];//记录读取的数据(字节)int len;// 循环将读取的字节数据写入字节数组while ((len = bis.read(bytes)) != -1){// 写入目的文件,一次写一个字节数组bos.write(bytes,0,len);}// 关闭流bos.close();bis.close();}
}

27.8.2字符缓冲流

构造方法

方法名称说明
public BufferedReader(Reader r)把基本流变成高级流
public BufferedWriter(Writer r)把基本流变成高级流
27.8.2.1字符缓冲输入流
构造方法:public BufferedReader(Reader r)
特有方法:public String readLine()   读一整行
package bufferedstreamdemo;import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;public class Test03 {public static void main(String[] args) throws IOException {// 创建字符缓冲输入流对象BufferedReader br = new BufferedReader(new FileReader("code_java02\\filedemo\\a.txt"));String line;while ((line = br.readLine()) != null){System.out.println(line);}// 释放资源br.close();}
}
27.8.2.2 字符缓冲输出流
构造方法:public BufferedWriter(Writer r)
特有方法:public void newLine()      跨平台的换行
package bufferedstreamdemo;import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;public class Test04 {public static void main(String[] args) throws IOException {// 创建字符输出流对象//a3.txt 不存在则会直接创建FileWriter fw = new FileWriter("code_java02\\filedemo\\a3.txt",true);BufferedWriter bw = new BufferedWriter(fw);// 写入内容bw.write("数风流人物,还看今朝。");// 换行bw.newLine();bw.write("俱往矣");// 释放资源bw.close();}
}

27.8.3 Test

27.9 转换流

高级流

字符转换输入流:InputStreamReader

字符转换输出流:OutputStreamWriter

27.9.1概述

是字符流和字节流之间的桥梁。

在这里插入图片描述

将字节流转换成字符流就可以拥有字符流的特性,同时字节流可以使用字符流中的方法。

字符流特性,比如:

  • 不会乱码
  • 根据字符集一次读取多个数据

示意图:

在这里插入图片描述

27.9.2Test

27.9.2.1test01

利用转换流按照指定字符编码读取

package convertstream;import java.io.*;public class Test01 {public static void main(String[] args) throws IOException {FileInputStream fis  = new FileInputStream( "code_java02\\filedemo\\gbkfile.txt");// 创建转换流对象InputStreamReader isr = new InputStreamReader(fis,"GBK");int b;while ((b = isr.read()) != -1){System.out.print((char) b);}isr.close();}
}
27.9.2.2 test02

利用转换流按照指定字符编码写出

package convertstream;import java.io.*;public class Test03 {public static void main(String[] args) throws IOException {// gbkfile02.txt 不存在则创建FileOutputStream fos  = new FileOutputStream("code_java02\\filedemo\\gbkfile02.txt",true);// 创建转换流对象OutputStreamWriter osw = new OutputStreamWriter(fos,"GBK");osw.write("吃了么");osw.close();}
}
27.9.2.3 test03

将本地文件中的GBK文件,转成UTF-8

package convertstream;import java.io.*;public class Test04 {public static void main(String[] args) throws IOException {// gbkfile03.txt 不存在 则创建// 创建转换流读出FileInputStream fis = new FileInputStream("code_java02\\filedemo\\gbkfile.txt");InputStreamReader isr = new InputStreamReader(fis,"GBK");// 创建转换流写入FileOutputStream fos = new FileOutputStream("code_java02\\filedemo\\gbkfile03.txt");OutputStreamWriter osw = new OutputStreamWriter(fos,"UTF-8");//一次读写一个字节// int b;// while ((b=isr.read()) != -1){//     osw.write(b);// }//一次读写多个字节char[] chars = new char[2];int b;while ((b = isr.read(chars)) != -1){osw.write(chars);}osw.close();isr.close();}
}
27.9.2.4 test04

利用字节流读取文件中的数据,每次读一整行,而且不能出现乱码

package convertstream;import java.io.*;public class Test05 {public static void main(String[] args) throws IOException {/*利用字节流读取文件中的数据,每次读一整行,而且不能出现乱码1.字节流在读取中文的时候,是会出现乱码的,但是字符流可以搞定2.字节流里面是没有读一整行的方法的,只有字符缓冲流才能搞定*/// 创建字节流对象FileInputStream fis = new FileInputStream("code_java02\\filedemo\\a.txt");// 将字节流转换成字符流InputStreamReader isr = new InputStreamReader(fis);// 将字符流包装成字符缓冲流BufferedReader br = new BufferedReader(isr);String line;while ((line = br.readLine()) != null){System.out.println(line);}// 释放资源br.close();}
}

27.10 序列化流

在这里插入图片描述

也叫 对象操作输出流

可以把Java中的对象写到本地文件中

高级流,也是用来包装基本流的

构造方法:public ObjectOutputStream(OutputStream out) 把基本流变成高级流成员方法:public final void writeObject(Object obj)                    把对象序列化(写出)到文件中去
//Student的标准JavaBean类
// Student实现Serializable接口
//Serializable接口里面是没有抽象方法,标记型接口一旦实现了这个接口,那  么就表示当前的Student类可以被序列化
//属性:学生姓名,学生年龄
=================================================//测试类
package objectstream.test01;import java.io.*;public class StudentTest {public static void main(String[] args) throws IOException {// 创建学生对象Student stu1 = new Student("小明",18);// 创建序列化流的对象ObjectOutputStream oos =  new ObjectOutputStream(new FileOutputStream("code_java02\\filedemo\\objfile.txt"));// 写出数据oos.writeObject(stu1);// 释放资源oos.close();}
}

27.11 反序列化流

也叫对象操作输入流,把序列化到本地文件中的对象读取到程序中。

构造方法:public ObjectInputStream(InputStream out) 把基本流变成高级流
成员方法:public Object readObject()              把序列化到本地文件中的对象,读取到程序中来
//同27.10中的JavaBean类
=================================================
package objectstream.test01;import java.io.FileInputStream;
import java.io.IOException;
import java.io.ObjectInputStream;public class StudentTest02 {public static void main(String[] args) throws IOException, ClassNotFoundException {// 创建反序列流对象ObjectInputStream ois = new ObjectInputStream(new FileInputStream("code_java02\\filedemo\\objfile.txt"));// 读出数据// Object o = ois.readObject();//想看到真正的对象需要强转Student stu   = (Student) ois.readObject();// 打印对象System.out.println(o);// 释放资源ois.close();}
}

化到本地文件中的对象读取到程序中。

构造方法:public ObjectInputStream(InputStream out) 把基本流变成高级流
成员方法:public Object readObject()              把序列化到本地文件中的对象,读取到程序中来
//同27.10中的JavaBean类
=================================================
package objectstream.test01;import java.io.FileInputStream;
import java.io.IOException;
import java.io.ObjectInputStream;public class StudentTest02 {public static void main(String[] args) throws IOException, ClassNotFoundException {// 创建反序列流对象ObjectInputStream ois = new ObjectInputStream(new FileInputStream("code_java02\\filedemo\\objfile.txt"));// 读出数据// Object o = ois.readObject();//想看到真正的对象需要强转Student stu   = (Student) ois.readObject();// 打印对象System.out.println(o);// 释放资源ois.close();}
}

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com