RandomAccessFile类
RandomAccessFile类
RandomAccessFile类
1 什么是RandomAccessFile类
java.io.RandomAccessFile类能对文件的内容进行读写操作
2 为什么需要RandomAccessFile类
File类智能创建,删除文件或获得文件信息,但是不能操作文件的内容
RandomAccessFile类可以对文件的内容进行任意的读写
3 向文件中写入内容
RandomAccessFile raf=new RandomAccessFile(<指定文件路径>,<读写模式>);
实例化对象在构造方法中:
- 指定一个文件路径
- 指定读写模式
- r:只读模式
- rw:读写模式
write() 能够对指定文件进行内容的写入
package cn.tedu.vip.raf;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;
/**
* java.io.RandomAccessFile
* 专门用来读写文件数据的API,基于指针对文件进行随机读写操作
* 读写文件非常灵活
* @author Tedu
*
*/
public class RAFDemo01 {
public static void main(String[] args) throws IOException {
/*
* RandomAccessFile对象的创建
*/
//File f=new File("./raf.dat");//dat为后缀名
//RandomAccessFile raf=new RandomAccessFile(f,"rw");
/*
* RsndomAccessFile对象的权限
* r:只读模式
* rw:读写模式
* 如果创建文件时使用的是读写模式
* 那么这个文件会被创建
* 如果是只读模式会发生异常
*/
RandomAccessFile raf=new RandomAccessFile("./raf.det","rw");
/*
* 下面代码写入的内容是
* 00000001
* raf.write(int d)
* 功能是向指定文件中写入给定int值的
* 2进制的低八位数据
*/
raf.write(97);
System.out.println("over");
//一定要运行关闭操作
raf.close();
}
}
4 从文件中读取内容
read() 能够从指定文件中读取一个字节
package cn.tedu.vip.raf;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;
/**
* 使用RAF读取一个字节的内容
* @author Tedu
*
*/
public class RAFDemo02 {
public static void main(String[] args) throws IOException {
RandomAccessFile raf=new RandomAccessFile("./raf.det","r");
/*
* int read();
* 从文件中读取一个字节的数据
* 装载到int值的低八位数据上,并返回这个int值
* 如果没有任何内容的位置时,那么返回-1,表示文件读完了
* 00000000 00000000 00000000 00000001
*/
int d=raf.read();
System.out.println(d);//97
d=raf.read();
System.out.println(d);//-1
raf.close();
}
}
5 复制文件
配合write()和read() 能够复制指定文件到新的位置
package cn.tedu.vip.raf;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;
/**
* 使用RandomAccessFile实现文件的复制
* @author Tedu
*
*/
public class CopyDemo {
public static void main(String[] args) throws IOException {
//负责读取数据的raf
RandomAccessFile rafRead=new RandomAccessFile("./齐晨 - 咱们结婚吧.m4a","r");
//负责写入的raf
RandomAccessFile rafWrite=new RandomAccessFile("./齐晨 - 咱们结婚吧_cp.m4a","rw");
//声明一个字节(只使用低八位)
long start=System.currentTimeMillis();//检验时间
int d;
while((d=rafRead.read())!=-1) {
rafWrite.write(d);
}
long end=System.currentTimeMillis();//检验时间
System.out.println("用时:"+(end-start)+"ms");
rafRead.close();
rafWrite.close();
}
}
6 复制文件优化
void write(byte[] data)
定义一个数组,将给定的字节数组中的所有字节一次性写出提高运行效率
package cn.tedu.vip.raf;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;
/**
* 优化文件复制
* 创建缓存,减少读写数据的次数
* 单字节读写是一种随机读写形式(效率低)
* 一组字节读写是块读写形式
* @author Tedu
*
*/
public class CopyDemo2 {
public static void main(String[] args) throws IOException {
RandomAccessFile rafRead=new RandomAccessFile("./齐晨 - 咱们结婚吧.m4a","r");
RandomAccessFile rafWrite=new RandomAccessFile("./齐晨 - 咱们结婚吧_cp.m4a","rw");
/*
* int read(byte[] date)
* 一次性读取给定字节数组长度的字节量,并存到该数组中
* 返回实际读取到的字节量
* 如果返回-1表示本次读取已经到末尾(没有读取到数据)
*
* void write(byte[]data)
* 将给定的字节数组中的数据写入文件中
*
* void write(byte[] data,int offset,int len)
* 将给定的字节数组中的数据,从下标为offset的位置开始
* 一次性写入len个长度
*/
//定义缓存
byte[] data=new byte[1024*10];//10k的缓存
int len;//每次读取到的字节数
long start=System.currentTimeMillis();
while((len=rafRead.read(data))!=-1) {
//将读取到的信息写入
rafWrite.write(data,0,len);
}
long end=System.currentTimeMillis();
System.out.println("用时:"+(end-start)+"ms");
//别忘了关闭读写
rafRead.close();
rafWrite.close();
}
}
7 写入文件
byte[]data=str.getBytes("utf-8");
raf.write(data)
使用byte类型数组
package cn.tedu.vip.raf;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;
/**
* 向文件中写入文本(中文)
* @author Tedu
*
*/
public class WriteStringDemo {
public static void main(String[] args) throws IOException {
RandomAccessFile raf=new RandomAccessFile("raf.txt", "rw");
String str="左边~跟我一起画条龙";
/*
* String对象的方法
* byte[]getBytes();
* 功能是将字符串中的字符转换为字节
* 按照系统默认的字符集
*
* byte[]getBytes(String csn)
* 功能是将字符串中的字符转换为字节
* 按照指定的字符集
*/
byte[] data=str.getBytes("utf-8");
raf.write(data);
System.out.println("over");
raf.close();//一定要记得关闭,重点
}
}
8 读取文本
byte[] data=new byte[(int)raf.length()];
raf.read(data);
提高读取效率
package cn.tedu.vip.raf;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;
/**
* 读取文本数据
* @author hp
*
*/
public class ReadStringDemo {
public static void main(String[] args) throws IOException {
RandomAccessFile raf=new RandomAccessFile("raf.txt","r");
//System.out.println(raf.length());
byte[] data=new byte[(int)raf.length()];
//读取文件中的所有数据到data数值
raf.read(data);
/*
* String类中有一个构造方法
* String(byte[] data,String scn)
* data是字节数值,会按照scn指定的字符集解析字符,并创建对象
*/
String str=new String(data,"utf-8");
System.out.println(str);
raf.close();
}
}
9 编写简易记事本
程序启动后要求用户输入一个文件名,然后对该文件进行读写操作,
之后用户在控制台输入的每行字符串都写入到该文件中(统一用UTF-8编码)写入文件的字符
package cn.tedu.vip.raf;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.util.Scanner;
/**
* 简易记事本
* 程序启动后用户输入一个文件名
* 针对这个文件进行读写操作
* 使用循环让用户向记事本写入字符串
* 统一编码utf-8,不用考虑换行问题
* 输入exit结束循环
* @author Tedu
*
*/
public class Note {
public static void main(String[] args) throws IOException {
Scanner scan=new Scanner(System.in);
System.out.println("请输入要创建的文件名");
String fileName=scan.nextLine();//输入一行全部读取
RandomAccessFile raf=new RandomAccessFile(fileName, "rw");
//循环开始记事
while(true) {
System.out.println("请输入记事");
String msg=scan.nextLine();
if(msg.equals("exit")){//如果信息退出
//输入exit循环退出
break;
}
byte[] data=msg.getBytes("utf-8");
raf.write(data);
}
System.out.println("谢谢使用");
raf.close();
}
}
10 RAF中的指针及使用
seek(int pos)
定位指针的位置
package cn.tedu.vip.raf;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;
/**
* 读写数据以及Raf指针的操作
* @author Tedu
*
*/
public class RafAeekDemo {
public static void main(String[] args) throws IOException {
RandomAccessFile raf=new RandomAccessFile("data.dat", "rw");
//获取指针当前的位置
long pos=raf.getFilePointer();
System.out.println(pos);
int max=Integer.MAX_VALUE;//21亿多
/* vvvvvvvv
* 01111111 11111111 11111111 11111111
*/
raf.write(max>>>24);
System.out.println("pos:"+raf.getFilePointer());//1
raf.write(max>>>16);
raf.write(max>>>8);
raf.write(max);
System.out.println("pos:"+raf.getFilePointer());//4
//直接写一个int数据
raf.writeInt(max);
System.out.println("pos:"+raf.getFilePointer());//8
raf.writeLong(123);
System.out.println("pos:"+raf.getFilePointer());//16
raf.writeDouble(123.123);
System.out.println("pos:"+raf.getFilePointer());//24
//读取文件数据
/*
* 指针移动到指定位置
* void seek(long pos)
*/
System.out.println("---------------");
raf.seek(0);
int data=raf.read();
System.out.println("pos:"+raf.getFilePointer());
System.out.println(data);
raf.seek(4);
int i=raf.readInt();
System.out.println("pos:"+raf.getFilePointer());//8
long I=raf.readLong();
System.out.println("pos:"+raf.getFilePointer());//16
double d=raf.readDouble();
System.out.println("pos:"+raf.getFilePointer());//24
System.out.println(i);
System.out.println(I);
System.out.println(d);
System.out.println("over");
raf.close();//切记关闭
}
}
11 用户注册练习
程序启动后顺序输入:用户名,密码,昵称,年龄
然后将其写入文件user.dat中保存
package cn.tedu.vip.raf;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.util.Arrays;
import java.util.Scanner;
/**
* 完成用户注册功能
* 将一个用户信息保存到一个文件中
* 这个文件可以保存多个用户信息
* 程序运行一次保存一个用户
* 用户名(String) 密码(String)昵称(String) 年龄(int)
* 每个用户信息占用一百字节
* 其中每个字符串信息占32字节年龄占4字节
* @author Tedu
*
*/
public class RegDemo {
public static void main(String[] args) throws IOException {
Scanner scan=new Scanner(System.in);
System.out.println("开始注册,请输入您的信息");
System.out.println("请输入用户名");
String name=scan.nextLine();
System.out.println("请输入密码");
String pwd=scan.nextLine();
System.out.println("请输入昵称");
String nick=scan.nextLine();
System.out.println("请输入年龄");
int age=scan.nextInt();
System.out.println(name+","+pwd+","+nick+","+age);
RandomAccessFile raf=new RandomAccessFile("user.dat", "rw");
//将指针移动到最后
raf.seek(raf.length());
//将用户名转换为字节数组
//写用户名
byte[] arrName=name.getBytes("utf-8");
arrName=Arrays.copyOf(arrName, 32);//扩容让系统书写32字节
raf.write(arrName);
System.out.println(raf.getFilePointer());//获取指针位置
//写密码
byte[] arrPwd=pwd.getBytes("utf-8");
arrPwd=Arrays.copyOf(arrPwd, 32);
raf.write(arrPwd);
System.out.println(raf.getFilePointer());
//写昵称
byte[] arrNick=nick.getBytes("utf-8");
arrNick=Arrays.copyOf(arrNick, 32);
raf.write(arrNick);
System.out.println(raf.getFilePointer());
//写年龄
raf.writeInt(age);
System.out.println(raf.getFilePointer());
System.out.println("注册成功");
raf.close();
}
}
12 读取用户练习
显示user.dat文件中所有的用户信息
package cn.tedu.vip.raf;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;
/**
* 显示user.dat中所有用户信息
* @author Tedu
*
*/
public class ShowAllUserDemo {
public static void main(String[] args) throws IOException {
RandomAccessFile raf=new RandomAccessFile("user.dat", "r");
for(int i=0; i<raf.length()/100; i++) {
byte[]data=new byte[32];
//读取第一个32字节
raf.read(data);
String name=new String(data,"utf-8");
System.out.println(raf.getFilePointer());//32
//读取下一个32字节
raf.read(data);
String pwd=new String(data,"utf-8");
System.out.println(raf.getFilePointer());//64
//读取下一个32字节
raf.read(data);
String nick=new String(data,"utf-8");
System.out.println(raf.getFilePointer());//96
//读取最后4字节
int age=raf.readInt();
System.out.println(raf.getFilePointer());//100
//raf.read(data);
//String age=new String(data,"uft-8");
//System.out.println(raf.getFilePointer());
System.out.println(name.trim()+","+pwd.trim()+","+nick.trim()+","+age);
}
System.out.println("over");
raf.close();
}
}
13 修改用户练习
程序启动后要求用户输入用户名和新昵称,然后将user.dat文件中对应的记录进行修改,如果输入的用户名在user.dat文件中不存在,则输出:查无此人
package cn.tedu.vip.raf;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.util.Arrays;
import java.util.Scanner;
/**
* 修改昵称
* 程序运行后输入用户名和新昵称
* 在user.dat中查找对应用户
* 如果存在修改昵称为新昵称
* 如果不存在输出查无此人
* @author Tedu
*
*/
public class UpdateDemo {
public static void main(String[] args) throws IOException {
Scanner scan=new Scanner(System.in);
System.out.println("请输入用户名");
String name=scan.nextLine();
System.out.println("请输入新昵称");
String nick=scan.nextLine();
RandomAccessFile raf=new RandomAccessFile("user.dat", "rw");
boolean isUpdated=false;//表示是否修改的变量,默认没修改
for(int i=0; i<raf.length()/100; i++) {
//移动指针至本次循环对应用户的起始位置
raf.seek(i*100);
//读取用户名
byte[]data=new byte[32];
raf.read(data);
String n=new String(data,"utf-8").trim();
//对比当前取出的用户名和用户要修改的用户名是否相同
if(n.equals(name)) {
//移动到昵称位置
raf.seek(i*100+64);
data=nick.getBytes("utf-8");
data=Arrays.copyOf(data, 32);
raf.write(data);
isUpdated=true;
System.out.println("修改成功");
break;
}
}//for循环结束
//判断是否修改过
if(!isUpdated) {
System.out.println("查无此人");
}
raf.close();
}
}
I(Input)\O(Output)
1 什么是IO
IO:Input,Output java标准的输入与输出
javaIO是以标准的操作对外界设备进行数据交换并将读写分为输入与输出
IO是顺序读写方式,只能顺序向后进行读或读写操作,并且不能同时进行读和写操作
2 为什么需要IO
功能上与RandomAccessFile一样,但是RAF是随机读写形式,而文件流是顺序读写形式,对于读写的灵活而言不如RAF,但是基于流连接可以完成复杂数据的读写
3 IO的分类
按方向分:输入流和输出流
java.io.InputStream:所有字节输入流的超类
规定了读取字节的相关方法
java.io.OututStream: 所有字节输出流的超类
规定了写出字节的相关方法
按使用方式:节点流与处理流,也称为低级流和高级流
节点流:真实连接数据源与程序之间的“管道”,负责实际搬运数据的流,流读写一定是建立在节点流的基础上进行的
处理流:不能独立存在,必须连接在其他流上,使得在读写数据的过程中,当数据流经当前处理流时,对其做某些加工处理,简化对数据的相关操作
4 文件流的使用
write(byte[] data)
向文件中写入信息、读取信息
package cn.tedu.vip.io;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
/**
* 文件流写操作
* @author Tedu
*
*/
public class FosDemo {
public static void main(String[] args) throws IOException {
/*
* 创建文件流的方法
* FileOutputStream(File file)
* FileOutputStream(String path)
* 上面两种创建形式都是覆盖输出模式
* 如果当前文件中有内容会全部清除重新写
*
* FileOutputStream(File file,true)
* FileOutputStream(String path,true)
* 追加模式
* 在源文件所有内容最后在追加输出的内容
* 不会清除源文件的内容
*/
FileOutputStream fos=new FileOutputStream("fos.txt",true);//加true追加
String str="流太厉害了~奥利给!";
//String str="文件输出流~奥利给!";
byte[] data=str.getBytes("gbk");
fos.write(data);
System.out.println("over");
fos.close();
}
}
package cn.tedu.vip.io;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
/**
* 使用文件输入流读取文件中的内容
* @author Tedu
*
*/
public class FisDemo {
public static void main(String[] args) throws IOException {
FileInputStream fis=new FileInputStream("fos.txt");
/*
* fis对象是按顺序读取文件中的内容
* int read();
* 从头读取文件中的内容,再次调用获得下一个字节的内容
* 如果读取到末尾返回-1
*
* int read(byte[] data)
* 从头读取数据,将读取到的内容存放到data中
* 如果读取到数据,返回读取到数据的字节数
* 如果没读取到数据,返回-1
* 再次调用从最后读取到的数据后面继续读取
*/
//int data;
//while((data=fis.read())!=-1) {
//System.out.println(data);
//}
byte[] data=new byte[1024];
int len=fis.read(data);
System.out.println("读取到了:"+len+"字节的内容");
String str=new String(data,0,len,"GBK");
System.out.println(str);
/*int n=fis.read();
System.out.println(n);
n=fis.read();
System.out.println(n);*/
fis.close();
}
}

浙公网安备 33010602011771号