IO流
IO简介
对于任何程序设计语言而言,输入输出(Input/Output)系统都是非常核心的功能。程序运行需要数据,数据的获取往往需要跟外部系统进行通信,外部系统可能是文件、数据库、其他程序、网络、IO设备等。外部系统比较复杂多变,那么我们有必要通过某种手段进行抽象、屏蔽外部差异,从而实现更加便捷的编程。
1.输入(Input)指的是:可以让程序从外部系统获得数据(核心含义是“读”,读取外部数据)
- 读取硬盘上的文件内容到程序。例如:播放器打开一个视频文件、word打开一个doc文件。
- 读取网络上某个位置内容到程序。例如:浏览器中输入网址后,打开该网址对应的网页内容;下载网络上某个网址的文件。
- 读取数据库系统的数据到程序。
- 读取某些硬件系统数据到程序。例如:车载电脑读取雷达扫描信息到程序;温控系统等
2.输出(Output)指的是:程序输出数据给外部系统从而可以操作外部系统(核心含义是“写”,将数据写出到外部系统)- 将数据写到硬盘中
- 将数据写到数据库系统中
- 将数据写到某些硬件系统中
数据源
数据源 Data Source,提供数据的原始媒介。常见的数据源有:数据库、文件、其他程序、内存、网络连接、IO设备
数据源分为:源设备、目标设备
- 源设备:为程序提供数据,一般对应输入流
- 目标设备:程序数据的目的地,一般对应输出流
流的概念
1.流是一个抽象、动态的概念,是一连串连续动态的数据集合
2.对于输入流而言,数据源就像水箱,流(Stream)就像水管中流动着的水流,程序就是我们的最终用户。我们通过流(A Stream)将数据源中的数据输送到程序中
3.对于输出流而言,目标数据源就是目的地,我们通过流将程序中的数据输送到目的数据源中。
输入/输出流的划分是相对程序而言的,并不是相对数据源
IO流程序
public class PathDemo01 {
public static void main(String[] args) throws IOException {
try{
//创建输入流
FileInputStream fis = new FileInputStream("F:a.txt");//文件内容是:abc
//一个字节一个字节的读取数据
int s1 = fis.read();//打印输入字符a对应的ASCII码值97
int s2 = fis.read();//打印输入字符b对应的ASCII码值98
int s3 = fis.read();//打印输入字符c对应的ASCII码值99
int s4 = fis.read();//由于文件内容已经读取完毕,返回-1
System.out.println(s1);
System.out.println(s2);
System.out.println(s3);
System.out.println(s4);
//流对象使用完,必须关闭!不然,总占用系统资源,最终会造成系统崩溃
fis.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
}
1.我们读取的文件内容是已知的,因此可以使用固定次数的“int s= fis.read();”语句读取内容,但是在实际开发中通常我们根本不知道文件的内容,因此我们在读取的时候需要配合while循环使用。
2.为了保证出现异常后流的正常关闭,通常要将流的关闭语句要放到finally语句块中,并且要判断流是不是null
//经典代码
public class TestIO2 {
public static void main(String[] args) throws IOException {
FileInputStream fis = null;
try{
fis = new FileInputStream("F:/idea代码/IO流/a.txt");
StringBuilder sb = new StringBuilder();
int temp = 0;
//当temp等于-1时,表示已经到了文件结尾,停止读取
while((temp = fis.read()) != -1){
sb.append((char)temp);
}
System.out.println(sb);
} catch (FileNotFoundException e) {
e.printStackTrace();
} finally{
try{
//这种写法,保证了即使遇到异常情况,也会关闭流对象
if(fis != null){
fis.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
四大IO抽象类
InputStream
此抽象类是表示字节输入流的所有类的父类。InputStream是一个抽象类,不可实例化。数据的读取需要由它的子类来实现。根据节点的不同,他派生了不同的节点流子类。
继承自 InputStream 的流都是用于向程序中输入数据,且数据的单位为字节(8bit)
常用方法:
int read():读取一个字节的数据,并将字节的值作为int类型返回(0-255)
未读出返回-1
void close();关闭输入流对象,释放相关系统资源
OutputStream
此抽象类是表示字节输出流的所有类的父类。输出流接收输出字节并将这些字节发送到某个目的地
常用方法:
void write(int n):向目的地写入一个字节
void close();关闭输出流对象,释放相关系统资源
Reader
用于读取的字符流抽象类,数据单位为字符
int read():读取一个字符的数据,并将字节的值作为int类型返回(0-65535)
未读出返回-1
void close();关闭输入流对象,释放相关系统资源
Writer
用于输出的字符流抽象类,数据单位为字符
void write(int n):向输出流写入一个字符
void close();关闭输出流对象,释放相关系统资源
- 节点流:可以直接从数据源或目的地读写数据,如FileInputStream、FileReader、DataInputStream等。
- 处理流:不直接连接到数据源或目的地,是“处理流的流”。通过对其他流的处理提高程序性能,如:BufferedInputStream、BuffereReader等。处理流也叫包装流
File类
1.File类简介
1.1作用:
File类是Java提供的针对磁盘中的文件或目录转换对象的包装类。一个File对象可以代表一个文件或目录,File对象可以实现获取文件和目录属性等功能,可以实现对文件和目录的创建,删除等功能
1.2File类操作目录与文件的常用方法
1.2.1针对文件的操作方法
createNewFile()//创建新文件
delete()//直接从磁盘上删除
exists()//查询磁盘中的文件是否存在
getAbsolutePath()//获取绝对路径
getPath()//获取相对路径
getName()//获取文件名 相当于调用了一个to String 方法
isFile()//判断是否是文件
length()//查看文件中的字节数
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();
}
1.2.2针对目录的操作方法
exists()//查询目录是否存在
isDirectory()//判断当前路径是否为目录
mkdir()//创建目录
getParentFile()//获取当前目录的父级目录
list()//返回一个字符串数组,包含目录中的文件和目录的路径名
listFiles//返回一个File数组,表示用此抽象路径名表示的目录中的文件
//创建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());
常用类对象
1.文件字节流
1.1文件字节输入流
FileInputStream通过字节的方式读取文件,适合读取所有类型的文件。Java也提供了FileReader专门读取文本文件
FileOutputStream通过字节的方式写数据到文件,适合所有类型的文件。Java也提供了FileWriter专门读取文本文件
1.2文件字节输出流
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.3通过缓冲区提高读写效率
1.3.1方式一
通过创建一个指定长度的字节数组作为缓冲区,以此来提高IO流的读写效率。该方式用于读取较大图片时的缓冲区定义。
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.3.2方式二
通过创建一个字节数组作为缓冲区,数组长度是通过输入流对象的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.4通过字节缓冲流提高读写效率
java缓冲流本身并不具有IO流的读取与写入功能,只是在别的流(节点流或其他处理流)上加上缓冲功能提高效率,就像是把别的流包装起来一样,因此缓冲流是一种处理流(包装流)。
BufferedInputStream和BufferedOutputStream这两个流是缓冲字节流,通过内部缓存数组来提高操作流的效率。
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.5定义文件拷贝工具类
/**
*
* @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();
}
}
2.2文件字符输出流
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使用字符流实现文本文件的拷贝处理
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.字符缓冲流
BuffereReader/BuffereWriter增加了缓存机制,大大提高了读写文本文件的效率
3.1字符输入缓冲流
BuffereReader是针对字符输入流的缓冲流对象,提供了更方便的按行读取的方法:readLine();在使用字符流读取文本文件时,可以使用该方法以行为单位进行读取。
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字符输出缓冲流
BuffereWriter是针对字符输出流的缓冲流对象,在字符输出缓冲流中可以使用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通过字符缓冲流实现文本文件的拷贝
/**
* 基于字符缓冲流实现文件拷贝
* @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.1Java对象的序列化和反序列化
8.1.1序列化和反序列化
当两个进程远程通信时,彼此可以发送各种类型的数据。无论是何种类型的数据,都会以二进制序列的形式在网络上传送。
1.对象的序列化:把Java对象转换为字节序列的过程
2.对象的反序列化:把字节序列恢复为Java对象的过程
3.对象序列化的作用:a.持久化:把对象的字节序列永久地保存到硬盘上,通常存放在一个文件中
b.网络通信:在网络上传送对象的字节序列。
8.1.2序列化涉及的类和接口
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();
}
}
9.随机访问流
RandomAccessFile可以实现两个作用:①实现对一个文件做读和写的操作。②可以访问文件的任意位置。
三个核心方法:
1.构造方法RandomAccessFile(String name, String mode):name用来确定文件;mode取r(读)或者rw(读写),通过mode可以确定流对文件的访问权限
2.seek(long a):用来定位流对象读写文件的位置,a确定读写位置距离文件开头的字节个数
3.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. File类在IO流中的作用
当以文件作为数据源或自标时,除了可以使用字符串作为文件以及位置的指定以外,我们也可以使用File类指定
Apache IO包
1.FileUtils的使用
常用方法
1.读入文件内容
readFileToString(文件需要写入的内容,字符集)
String content = FileUtils.readFileToString(new File("d:/QQ/AAA/abc/txt"),"UTF-8");
System.out.println(content);
2.将已筛选的目录拷贝到新位置:
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);