文章目录
Java基础IO流
一、IO简介
1、什么是IO?
即输入输出(Input/Output)功能
输入(Input):核心含义是“读”,读取外部数据。
输出(Output):核心含义是“写”,将数据写出到外部系统。
2、数据源
提供数据的原始媒介。分为源设备、目标设备。
源设备:为程序提供数据,对应于输入流。
目标设备:程序数据的目的地,对应于输出流。
3、流的概念
流是一个抽象、动态的概念,是一连串连续动态的数字集合。
注意:输入/输出流的划分是相对于程序而言的,并不是相对于数据源。
4、Java中四大IO抽象类
字节流的输入和输出:InputStream/OutputStream
字符流的输入个输出:Reader/Writer
常用方法
由于抽象类不能实例化对象,所以不演示具体的代码
1)、InputStream类
①、读取一个字节的数据,返回字节的值(返回值的范围0-255),如果未读出字节返回-1:
int read()
②、关闭输入流对象:
void close()
2)、OutputStream类
①、向目的地中写入一个字节:
void write(int n)
②、关闭输出流对象:
void close()
3)、Reader类
①、读取一个字符的数据,返回字符的值(返回值的范围0-65535,即Unicode值),如果未读出字符则返回-1:
int read()
②、关闭流对象:
void close()
4)、Writer类
①、向输出流中写入一个字符:
void write(int n)
②、关闭流对象:
void close()
5、Java中流的概念细分
1)、按流的方法分类
输入流:数据流从数据源到程序(以InputSream、Reader结尾的流)。
输出流:数据流从程序到目的地(以OutputStream、Writer结尾的流)。
2)、按处理的数据单元分类
字节流:以字节为单位获取数据,命名上以Stream结尾的流一般都是字节流,如FileInputStream、FileOutputSream。一般处理二进制文件。
字符流:以字符为单位获取数据,命名上以Reader/Writer结尾的流一般是字符流,如FileReader、FileWriter。一般处理文本文件。
3)、按处理对象不同分类
节点流:直接从数据源或目的地读写数据,如FileInputSream、FileReader、DateInputSream。
处理流:不直接连接到数据源或目的地,如BufferedInputSream、BufferedReader,处理流也叫包装流。
6、Java中IO类的体系
1.InputStream/OutputStream
字节流的抽象类。
2.Reader/Writer
字符流的抽象类。
3.FileInputStream/FileOutputStream
节点流:以字节为单位直接操作“文件”。
4.ByteArrayInputStream/ByteArrayOutputStream
节点流:以字节为单位直接操作“字节数组对象”。
5.ObjectInputStream/ObjectOutputStream
处理流:以字节为单位直接操作”对象“。
6.DateInputStream/DataOutputStream
处理流:以字节为单位直接操作”基本数据类型与字符串类型“。
7.FileReader/FileWriter
节点流:以字符为单位直接操作”文本文件“(注意:只能读写文本文件)。
8.BufferedReader/BufferedWriter
处理流:将Reader/Writer对象进行包装,增加缓存功能,提高读写效率。
9.BufferedInputStream/BufferedOutputStream
处理流:将InputStream/OutputStream对象进行包装,增加缓存功能,提高读写效率。
10.InputStreamReader/OutputStreamWriter
处理流:将字节流对象转换成字符流对象。
11.PrintStream
处理流:将OutputStream进行包装,可以方便地输出字符,更加灵活。
二、IO流入门案例
1、第一个简单的IO流程序
在d盘创建一个命名为”a“txt文档,在里面输入“dcba",利用FileInputStream读取文件。
FileInputStream fileInput = null;
try {
//创建一个FileInputStream对象,参数传入文件的路径
fileInput = new FileInputStream("d:/a.txt");
//读取文件
int read1 = fileInput.read();
int read2 = fileInput.read();
int read3 = fileInput.read();
int read4 = fileInput.read();
int read5 = fileInput.read();
System.out.println(read1);
System.out.println(read2);
System.out.println(read3);
System.out.println(read4);
System.out.println(read5);
}catch(Exception e){
e.printStackTrace();
}finally {
try {
//关闭流对象
if(fileInput != null){
fileInput.close();
}
}catch (Exception e){
e.printStackTrace();
}
}
/*
运行结果:100
99
98
97
-1
*/
2、改进第一个程序
第一个程序在不知道文件内容大小时,效率较低。读取内容用while循环代替。并且把文件内容以char类型读取出来。
//创建FileInputStream流对象,把路径传入
fileInput = new FileInputStream("d:/a.txt");
StringBuffer buffer = new StringBuffer();
int temp = 0;
while ((temp = fileInput.read())!=-1){
System.out.println(temp);
buffer.append((char)temp);
}
System.out.println(buffer.toString());
/*
运行结果:100
99
98
97
dcba
*/
三、File类的使用
File类是Java提供的针对磁盘中的文件或目录转换对象的包装类。
一个File对象代表一个文件或目录
常用方法
1、针对文件操作的方法
①、创建新文件
boolean creatNewFile()
②、从磁盘删除文件
boolean delete()
③、查询磁盘中的文件是否存在
boolean exists()
④、获取绝对路径
String getAbsolutePath()
⑤、获取相对路径
String getPath()
⑥、获取文件名,相当于调用了一个toString方法
String getName()
⑦、判断是否是文件
boolean isFile()
⑧、查看文件中的字节数
long length()
⑨、测试文件是否这个抽象路径名是一个隐藏文件
boolean isHidden()
//创建一个file对象
File file = new File("d:/aaa.txt");
try {
System.out.println(file.createNewFile());//创建新文本文件
System.out.println(file.exists());//查询磁盘中的文件是否存在
System.out.println(file.getAbsolutePath());//获取绝对路径
System.out.println(file.getPath());//获取相对路径
System.out.println(file.getName());//获取文件名,相当于调用了一个toString方法
System.out.println(file.isFile());//判断是否是文件
System.out.println(file.length());//查看文件中的字节数
System.out.println(file.isHidden());//测试文件是否这个抽象路径名是一个隐藏文件
System.out.println(file.delete());//从磁盘删除文件
}catch(Exception e){
e.printStackTrace();
}
/*
运行结果:true
true
d:\aaa.txt
d:\aaa.txt
aaa.txt
true
0
false
true
*/
2、针对目录操作的方法
①、查询目录是否存在
boolean exists()
②、判断当前路径是否为目录
boolean isDirectory()
③、创建目录
boolean mkdir()
④、创建多级目录
boolean mkdirs()
⑤、获取当前目录的父级目录
File getParentFile()
⑥、返回一个字符串数组,包含目录中的文件和目录的路径名
String[] list()
⑦、返回一个File数组,表示用此抽象路径名表示的目录中的文件
File[] listFiles()
//创建file对象
File file = new File("d:/AAAA");
File file1 = new File("d:/aaaa/aaa/aa/a");
System.out.println(file.mkdir());
System.out.println(file1.mkdirs());
System.out.println(file.exists());//查询目录是否存在
System.out.println(file.isDirectory());//判断当前路径是否为目录
System.out.println(file.getParentFile());//获取当前目录的父级目录
System.out.println(file1.getParentFile());
File file2 = new File("d:/aaaa");
String[] arr = file2.list();//返回一个字符串数组,包含目录中的文件和目录的路径名
for (String temp :
arr) {
System.out.println(temp);
}
File[] arr2 = file2.listFiles();//返回一个File数组,表示用此抽象路径名表示的目录中的文件
for (File temp :
arr2) {
System.out.println(temp);
}
System.out.println(file.delete());
System.out.println(file1.delete());
/*
运行结果:true
true
true
true
d:\
d:\aaaa\aaa\aa
aaa
d:\aaaa\aaa
false
true
*/
四、常用流对象
1、文件字节流
1.1、文件字节输入和输出流
- FileInputStream通过字节的方式读取文件,适合所有类型的文件(图像、视频、文本文件等)。
- FileOutputStream通过字节的方式写数据到文件,适合所有类型的文件(图像、视频、文本文件等)。
FileInputStream fis = null;
FileOutputStream fos = null;
try {
//创建一个文件字节流对象
fis = new FileInputStream("d:/QQ/卢本伟牛逼.png");
fos = new FileOutputStream("d:/QQ/aaa.png");
int count = 0;
int temp = 0;
while ((temp = fis.read()) != -1){
count++;
fos.write(temp);
}
//刷新
fos.flush();
System.out.println("字节的个数为:" + count);
}catch(Exception e){
e.printStackTrace();
}finally {
try {
//关闭流对象
if(fis != null){
fis.close();
}
if(fos != null){
fos.close();
}
}catch (Exception e){
e.printStackTrace();
}
}
/*
运行结果:字节的个数为:491469
*/
1.2、通过缓冲区提高读写效率
1.2.1、方式一:
创建一个指定长度的字节数组作为缓冲区。注意:缓冲区的长度一定是2的整数幂,一般为1024长度。
方法的使用:
①、读取arr.length长度的字节。返回读取的字节数。如果是文件结尾则返回-1。
int read(byte[] arr)
②、将一个字节类型的数组arr中的从指定位置(off)开始的,len个字节写入到输出流。
void write(byte[] arr, int off, int len)
FileInputStream fis = null;
FileOutputStream fos = null;
try {
//创建一个文件字节流对象
fis = new FileInputStream("d:/QQ/卢本伟牛逼.png");
fos = new FileOutputStream("d:/QQ/bbb.png");
//增加缓冲区
byte[] arr = new byte[1024];
int temp = 0;
while ((temp = fis.read(arr)) != -1){
fos.write(arr,0,temp);
}
//刷新
fos.flush();
}catch(Exception e){
e.printStackTrace();
}finally {
try {
//关闭流对象
if(fis != null){
fis.close();
}
if(fos != null){
fos.close();
}
}catch (Exception e){
e.printStackTrace();
}
}
1.2.2、方式二:
创建一个字节数组作为缓冲区,数组长度是通过输入流对象的available()返回当前文件的预估长度来定义的。注意:不适合大文件
方法的使用:
返回当前文件的预估长度
int available()
FileInputStream fis = null;
FileOutputStream fos = null;
try {
//创建一个文件字节流对象
fis = new FileInputStream("d:/QQ/卢本伟牛逼.png");
fos = new FileOutputStream("d:/QQ/bbb.png");
//创建一个缓冲区
byte[] arr = new byte[fis.available()];
fis.read(arr);
fos.write(arr);
//刷新
fos.flush();
}catch(Exception e){
e.printStackTrace();
}finally {
try {
//关闭流对象
if(fis != null){
fis.close();
}
if(fos != null){
fos.close();
}
}catch (Exception e){
e.printStackTrace();
}
}
1.3、通过字节缓冲流提高读写效率
- 缓冲流是一种处理流。先将数据缓存起来,然后当缓存区存满后或者手动刷新时再一次性的读取到程序或写入目的地。
- 缓冲流中的byte数组长度默认是8192,即2的13次方。
- BufferedInputStream和BufferedOutputStream是缓冲字节流 。
- 创建对象时,先创建FileStream类再创建BufferedStream类,关闭时,”后开的先关闭“,即先关闭BufferedStream类
FileInputStream fis = null;
FileOutputStream fos = null;
BufferedInputStream bis = null;
BufferedOutputStream bos = null;
try {
fis = new FileInputStream("d:/QQ/卢本伟牛逼.png");
bis = new BufferedInputStream(fis);
fos = new FileOutputStream("d:/QQ/ddd.png");
bos = new BufferedOutputStream(fos);
int temp = 0;
//缓冲区byte数组的默认长度是8192
while((temp = bis.read()) != -1){
bos.write(temp);
}
//刷新
bos.flush();
}catch(Exception e){
e.printStackTrace();
}finally {
//关闭的原则:“先开后关”
try {
if(bis != null){
bis.close();
}
if(fis != null){
fis.close();
}
if(bos != null){
bos.close();
}
if(fos != null){
fos.close();
}
}catch (Exception e){
e.printStackTrace();
}
}
1.4、定义文件拷贝工具类
/**
*
* @param src 源文件的路径
* @param des 需要拷贝文件的路径
*/
public static void copyFile(String src, String des){
FileInputStream fis = null;
BufferedInputStream bis = null;
FileOutputStream fos = null;
BufferedOutputStream bos = null;
try {
fis = new FileInputStream(src);
bis = new BufferedInputStream(fis);
fos = new FileOutputStream(des);
bos = new BufferedOutputStream(fos);
int temp = 0;
while ((temp = bis.read()) != -1){
bos.write(temp);
}
bos.flush();
}catch (Exception e){
e.printStackTrace();
}finally{
try {
if(bis != null){
bis.close();
}
if(fis != null){
fis.close();
}
if(bos != null){
bos.close();
}
if(fos != null){
fos.close();
}
}catch (Exception e){
e.printStackTrace();
}
}
}
}
2、文件字符流
文件字节流可以处理所有文件。文件字符流可以处理文本文件,它以字符为单位进行操作。
2.1、文件字符输入流
FileReader frd = null;
try {
frd = new FileReader("d:/QQ/AAA/aaa.txt");
int temp = 0;
while((temp = frd.read()) != -1){
System.out.println((char)temp);
}
}catch (Exception e){
e.printStackTrace();
}finally{
try {
if(frd!=null){
frd.close();
}
}catch(Exception e){
e.printStackTrace();
}
}
/*
aaa.txt文件的内容为:“abc今年是2022年”
运行结果:
a
b
c
今
年
是
2
0
2
2
年
*/
2.2、文件字符输出流
- 如果多个FileWriter对象操作文件的话,默认是覆盖内容的。如果想要第二个文本内容进行追加处理,需要使用new FileWriter(“路径”, true)构造器创建对象。
- 换行处理使用转移字符"\r\n"
FileWriter fw = null;
FileWriter fw2 = null;
try {
fw = new FileWriter("d:/QQ/AAA/abc.txt");
fw.write("你好尚学堂\r\n");
fw.write("来到世界最高层理塘\r\n");
fw.flush();
fw2 = new FileWriter("d:/QQ/AAA/abc.txt",true);
fw2.write("呀,这不是丁真吗?\r\n");
fw2.write("看看远处的雪山吧,家人们\r\n");
fw2.flush();
}catch (Exception e){
e.printStackTrace();
}finally{
try {
if(fw!=null){
fw.close();
}
if(fw2!=null){
fw2.close();
}
}catch (Exception e){
e.printStackTrace();
}
}
2.3、使用字符流实现文本文件的拷贝处理
如果想使用缓冲区提高效率,创建一个char类型的数组,数组的长度可以赋给1024。注意:不同于字节输入流对象,字符输入流对象不能使用available()方法预估文件大小。
FileReader fr = null;
FileWriter fw = null;
try {
fr = new FileReader("d:/QQ/AAA/abc.txt");
fw = new FileWriter("d:/QQ/AAA/abc123.txt");
//创建缓冲区char类型数组,数组长度为1024
char[] arr = new char[1024];
int temp = 0;
while ((temp = fr.read(arr)) != -1){
fw.write(arr,0,temp);
}
fw.flush();
}catch(Exception e){
e.printStackTrace();
}finally {
try {
//关闭流对象
if(fr != null){
fr.close();
}
if(fw != null){
fw.close();
}
}catch (Exception e){
e.printStackTrace();
}
}
3、字符缓冲流
3.1、字符输入缓冲流
BufferedReader是针对字符输入流的缓冲流对象,提供按行读取的方法:String readLine () ,返回值为String类型
FileReader fr = null;
BufferedReader br = null;
try {
fr = new FileReader("d:/QQ/AAA/abc.txt");
br = new BufferedReader(fr);
String temp = null;
while((temp = br.readLine()) != null){
System.out.println(temp);
}
}catch(Exception e){
e.printStackTrace();
}finally {
try {
//关闭流对象
if(br != null){
br.close();
}
if(fr != null){
fr.close();
}
}catch (Exception e){
e.printStackTrace();
}
}
/*
运行结果:你好尚学堂
来到世界最高层理塘
呀,这不是丁真吗?
看看远处的雪山吧,家人们
*/
3.2、字符输出缓冲流
BufferedWriter针对字符输出流的缓冲流对象,提供换行处理的方法:void newLine()
FileWriter fw = null;
BufferedWriter bw = null;
try {
fw = new FileWriter("d:/QQ/AAA/sxt.txt");
bw = new BufferedWriter(fw);
bw.write("来到世界最高层理塘");
bw.write("呀,这不是丁真吗");
bw.newLine();
bw.write("嘭");
bw.newLine();
bw.write("看看远处的雪山吧家人们");
bw.flush();
}catch(Exception e){
e.printStackTrace();
}finally {
try {
//关闭流对象
if(bw != null){
bw.close();
}
if(fw != null){
fw.close();
}
}catch (Exception e){
e.printStackTrace();
}
}
/*
文件的内容为:来到世界最高层理塘呀,这不是丁真吗
嘭
看看远处的雪山吧家人们
*/
3.3、通过字符缓冲流实现文本文件的拷贝
由于readLine()方法是每行写入,所以需要在readLine()方法后调用newLine()方法换行,否则文件内容全在第一行
/**
* 基于字符缓冲流实现文件拷贝
* @param src 读取文件的路径
* @param des 写出文件的路径
*/
public static void copyFile(String src,String des){
BufferedReader br = null;
BufferedWriter bw = null;
try {
br = new BufferedReader(new FileReader(src));
bw = new BufferedWriter(new FileWriter(des));
String temp = "";
while ((temp = br.readLine()) != null){
bw.write(temp);
bw.newLine();
}
}catch(Exception e){
e.printStackTrace();
}finally {
try {
//关闭流对象
if(br != null){
br.close();
}
if(bw != null){
bw.close();
}
}catch (Exception e){
e.printStackTrace();
}
}
}
3.4、通过字符缓冲流为文件中的内容添加行号
BufferedReader br = null;
BufferedWriter bw = null;
try {
br = new BufferedReader(new FileReader("d:/QQ/AAA/abc123.txt"));
bw = new BufferedWriter(new FileWriter("d:/QQ/AAA/123abc.txt"));
String temp = "";
int i = 1;
while ((temp = br.readLine()) != null){
bw.write(i+"、"+temp);
bw.newLine();
i++;
}
}catch(Exception e){
e.printStackTrace();
}finally {
try {
//关闭流对象
if(br != null){
br.close();
}
if(bw != null){
bw.close();
}
}catch (Exception e){
e.printStackTrace();
}
}
/*
输出文件的内容为:1、你好尚学堂
2、来到世界最高层理塘
3、呀,这不是丁真吗?
4、看看远处的雪山吧,家人们
*/
4、转换流
InputStreamReader/OutputStreamWriter用来实现将字节流转换成字符流
4.1、通过转换流实现键盘输入屏幕输出
BufferedReader br = null;
BufferedWriter bw = null;
try {
br = new BufferedReader(new InputStreamReader(System.in));
bw = new BufferedWriter(new OutputStreamWriter(System.out));
bw.write("请输入:");
bw.flush();
String input = br.readLine();
bw.write(input);
bw.flush();
}catch (Exception e){
e.printStackTrace();
}finally{
try {
if(br!=null){
br.close();
}
if(bw!=null){
bw.close();
}
}catch (Exception e){
e.printStackTrace();
}
}
/*
运行结果:请输入:我是中国人
我是中国人
*/
4.2、通过字节流读取文本文件并添加行号
BufferedReader br = null;
BufferedWriter bw = null;
try {
br = new BufferedReader(new InputStreamReader(new FileInputStream("d:/QQ/AAA/abc.txt")));
bw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream("d:/QQ/AAA/123.txt")));
int i = 1;
String temp = "";
while((temp = br.readLine()) != null){
bw.write(i+"、"+temp);
bw.newLine();
i++;
}
bw.flush();
}catch (Exception e){
e.printStackTrace();
}finally{
try {
if(br!=null){
br.close();
}
if(bw!=null){
bw.close();
}
}catch (Exception e){
e.printStackTrace();
}
}
/*
输出文件的内容为:1、你好尚学堂
2、来到世界最高层理塘
3、呀,这不是丁真吗?
4、看看远处的雪山吧,家人们
*/
5、字符输出流
PrintWriter:用于字符输出的流对象。该对象有自动行刷新缓冲字符输出流,即不需要调用flush()方法。特点是可以按行写出字符串,并且可通过println()方法实现自动换行。
BufferedReader br = null;
PrintWriter pw = null;
try {
br = new BufferedReader(new FileReader("d:/QQ/AAA/abc.txt"));
pw = new PrintWriter("d:/QQ/AAA/td.txt");
int i = 1;
String temp = "";
while((temp = br.readLine()) !=null){
pw.println(i+"、"+temp);
i++;
}
}catch (Exception e){
e.printStackTrace();
}finally{
try {
if(br!=null){
br.close();
}
if(pw!=null){
pw.close();
}
}catch (Exception e){
e.printStackTrace();
}
}
6、字节数组流
ByteArrayInputStream和ByteArrayOutputStream用于流和数组之间转化
6.1、字节数组输入流
1.FileInputStream是把文件当作数据源,ByteArrayInputStream则是把内存中的“字节数组对象”当作数据源
2.该对象构造方法的参数是一个字节数组,这个字节数组就是数据源
bais = new ByteArrayInputStream(arr);
byte[] arr = "agacgg".getBytes();
ByteArrayInputStream bais = null;
StringBuffer buffer = new StringBuffer();
try {
//该构造方法的参数是一个字节数组,这个字节数组就是数据源
bais = new ByteArrayInputStream(arr);
int temp = 0;
while((temp = bais.read()) != -1){
buffer.append((char)temp);
}
System.out.println(buffer.toString());
}catch (Exception e){
e.printStackTrace();
}finally {
try {
if(bais!=null){
bais.close();
}
}catch (Exception e){
e.printStackTrace();
}
}
/*
运行结果:agacgg
*/
6.2、字节数组输出流
1.ByteArrayOutputStream流对象是将流中的数据写入到字节数组中
2.byte toByteArray( )[ ]:将流对象转换为字节数组,返回一个字节数组
ByteArrayOutputStream baos = null;
try {
baos = new ByteArrayOutputStream();
baos.write('a');
baos.write('b');
baos.write('c');
baos.write('d');
baos.write('e');
byte[] bytes = baos.toByteArray();
for (int i = 0; i < bytes.length; i++) {
System.out.println((char)bytes[i]);
}
}catch (Exception e){
e.printStackTrace();
}finally {
try {
if(baos!=null){
baos.close();
}
}catch (Exception e){
e.printStackTrace();
}
}
/*
运行结果:a
b
c
d
e
*/
7、数据流
数据流将“基本数据类型与字符串类型”作为数据源,从而让输入输出流操作Java基本数据类型与字符串类型
DataInputStream和DataOutputStream提供了所有基本类型数据(如int,doulbe,String等)方法
注意:数据流读取数据时,读取的顺序要与写入的顺序一致,否则不能正确读取。
DataOutputStream dos = null;
DataInputStream dis = null;
try {
dos = new DataOutputStream(new BufferedOutputStream(new FileOutputStream("D:/QQ/AAA/DataStream.txt")));
dos.writeBoolean(true);
dos.writeChar('g');
dos.writeDouble(10.12);
dos.writeInt(50);
dos.flush();
dis = new DataInputStream(new BufferedInputStream(new FileInputStream("D:/QQ/AAA/DataStream.txt")));
//直接读取数据,注意:读取的顺序要与写入的顺序一致,否则不能正确读取
System.out.println(dis.readBoolean());
System.out.println(dis.readChar());
System.out.println(dis.readDouble());
System.out.println(dis.readInt());
}catch (Exception e){
e.printStackTrace();
}finally {
try {
if(dos!=null){
dos.close();
}
if(dis!=null){
dis.close();
}
}catch (Exception e){
e.printStackTrace();
}
}
/*
运行结果:true
g
10.12
50
*/
8、对象流
8.1、Java对象的序列化和反序列化
8.1.1、序列化和反序列化是什么
1.对象的序列化:把Java对象转换为字节序列的过程
2.对象的反序列化:把字节序列恢复为Java对象的过程
3.对象序列化的作用:①持久化②网络通信
8.1.1、序列化涉及的类和接口
1.ObjectOutputStream代表对象输出流,它的writeObject(Object obj)方法可对参数指定的obj对象进行序列化,把得到的字节序列写到一个目标输出流中。
2.ObjectInputStream代表对象输入流,它的readObject()方法从一个源输入流中读取字节序列,再把他们反序列化为一个对象,并将其返回。
3.Serializable接口是一个空接口,只起标记作用。只有实现了Serializable接口的类的对象才能被序列化。
8.2、写出和读取操作基本数据类型
与数据流的代码类似,不多赘述,参考数据流代码。
8.3、将对象序列化到文件和反序列化到内存中
ObjectOutputStream可以将一个内存中的Java对象通过序列化的方式写入到磁盘的文件中。被序列化的对象必须要实现Serializable序列化接口,否则会抛出异常
ObjectOutputStream oos = null;
ObjectInputStream ois = null;
try {
oos = new ObjectOutputStream(new FileOutputStream("d:/QQ/AAA/ObjectStreamObject.txt"));
Users users1 = new Users(10, "张三", 23);
oos.writeObject(users1);
ois = new ObjectInputStream(new FileInputStream("d:/QQ/AAA/ObjectStreamObject.txt"));
Users users2 = (Users)ois.readObject();
System.out.println(users2.getId());
System.out.println(users2.getName());
System.out.println(users2.getAge());
}catch (Exception e){
e.printStackTrace();
}finally {
try {
if(oos!=null){
oos.close();
}
if(ois!=null){
ois.close();
}
}catch (Exception e){
e.printStackTrace();
}
}
/*
运行结果:10
张三
23
*/
9、随机访问流
1.RandomAccessFile可以实现两个作用:①实现对一个文件做读和写的操作。②可以访问文件的任意位置。
2.三个核心方法:
①构造方法RandomAccessFile(String name, String mode):name用来确定文件;mode取r(读)或者rw(读写),通过mode可以确定流对文件的访问权限
②seek(long a):用来定位流对象读写文件的位置,a确定读写位置距离文件开头的字节个数
③getFilePointer() :获取流的当前读写位置。
RandomAccessFile raf = null;
try {
raf = new RandomAccessFile("d:/QQ/AAA/RandomAccessFile.txt","rw");
//将数据写入文件中
int[] arr = new int[]{10,20,30,40,50,60,70,80,90,100};
for (int i = 0; i < arr.length; i++) {
raf.writeInt(arr[i]);
}
//将数据隔三个读出
for (int i = 0; i < arr.length; i+=3) {
raf.seek(i*4);
System.out.print(raf.readInt() + "\t");;
}
System.out.println();
//将第四个数据替换成110
raf.seek(4*3);
raf.writeInt(110);
//将数据隔三个读出
for (int i = 0; i < arr.length; i+=3) {
raf.seek(i*4);
System.out.print(raf.readInt() + "\t");;
}
}catch (Exception e){
e.printStackTrace();
}finally {
try {
if(raf!=null){
raf.close();
}
}catch (Exception e){
e.printStackTrace();
}
}
/*
运行结果:10 40 70 100
10 110 70 100
*/
10、File类在IO中的作用
当以文件作为数据源或自标时,除了可以使用字符串作为文件以及位置的指定以外,我们也可以使用File类指定。
BufferedReader br = null;
br = new BufferedReader(new FileReader(new File("路径")));
五、Apache IO包
1、FileUtils的使用
常用方法
①读入文件内容
readFileToString(文件需要写入的内容,字符集)
String content = FileUtils.readFileToString(new File("d:/QQ/AAA/abc/txt"),"UTF-8");
System.out.println(content);
②将已筛选的目录拷贝到新位置:
copyDirectory(File srcDir, File destDir, FileFilter filter)
String destFilePath = "E:\java\file04";
//将已筛选的目录复制,并保持原文件日期的新位置。
FileUtils.copyDirectory(file, new File(destFilePath), new FileFilter() {
@Override
public boolean accept(File pathname) {
if(pathname.isDirectory()) return true;
else {
boolean b1 = pathname.getName().endsWith(".txt");
boolean b2 = pathname.getName().endsWith(".jpg");
return b1 || b2;
}
}
});
2、IOUtils的使用
常用方法
①将输入流或数组中的内容转换为字符串
toString(InputStream input, String encoding)
String content = IOUtils.toString(new FileInputStream("d:/QQ/AAA/abc.txt"),"UTF-8");
System.out.println(content);