目录
1.RandomAccessFile类
1.相关介绍
1. RandomAccessFile声明在java.io包下,但直接继承于java.lang.Object类。并且它实现了Datalnput、DataOutput这两个接口,也就意味着这个类既可以读也可以写。
2. RandomAccessFile类支持“随机访问”的方式,程序可以直接跳到文件的任意地方来读、写文件:
>支持只访问文件的部分内容
>可以向已存在的文件后追加内容
3. RandomAccessFile对象包含一个记录指针,用以标示当前读写处的位置。RandomAccessFile类对象可以自由移动记录指针:
>long getFilePointer():获取文件记录指针的当前位置
>void seek(long pos):将文件记录指针定位到pos位置
4. 我们可以用RandomAccessFile这个类,来实现一个多线程断点下载的功能,用过下载工具的朋友们都知道,下载前都会建立两个临时文件,一个是与被下载文件大小相同的空文件,另一个是记录文件指针的位置文件,每次暂停的时候,都会保存上一次的指针,然后断点下载的时候,会继续从上一次的地方下载,从而实现断点下载或上传的功能,有兴趣的朋友们可以自己实现下。
2.使用介绍
1. RandomAccessFile 直接继承于java.Lang.object类,实现了DataInput和DataOutput接口
2. RandomAccessFile 既可以作为输入流,也可以作为输出流
3. 构造方法:
RandomAccessFile (String name, String mode)
RandomAccessFile (File file, String mode)
参数:
name :文件名,创建的流的源,也是流的目的地
file :File对象,创建的流的源,也是流的目的地
mode :取 r(只读)、 rw(可读可写)、rwd(打开以便读取和写入;同步文件内容 的更新)、rws(打开以便读取和写入;同步文件内容和元数据的更新),决定 访问模式
4. 如果RandomAccessFile作为输出流时,写出到的文件如果不存在,则在执行过程中自动创建。如果写出到的文件存在,则会对原有文件内容进行覆盖。(默认情况下,从头开始覆盖)
2.使用
1.文件的读和写操作
@Test
public void TestRandomAccessFile() {
RandomAccessFile raf1 = null;
RandomAccessFile raf2 = null;
try {
//创建对象
raf1 = new RandomAccessFile(new File("C:\\Users\\zhang\\Desktop\\1.jpg"),"r");
raf2 = new RandomAccessFile(new File("C:\\Users\\zhang\\Desktop\\2.jpg"),"rw");
//读出并写入
byte[] buffer = new byte[1024];
int len;
while((len = raf1.read(buffer))!=-1){
raf2.write(buffer,0,len);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if(raf1!=null){
try {
raf1.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(raf2!=null){
try {
raf2.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
2.文件的覆盖
如果RandomAccessFile作为输出流时,写出到的文件如果不存在,则在执行过程中自动创建。如果写出到的文件存在,则会对原有文件内容进行覆盖。(默认情况下,从头开始覆盖)
@Test
public void Test01() throws IOException {
RandomAccessFile raf1 = null;
raf1 = new RandomAccessFile(new File("C:\\Users\\zhang\\Desktop\\1.txt"),"rw");
raf1.write("xyz".getBytes());
raf1.close();
}
若1.txt中的内容为abcdefg,则执行完后变为xyzdefg。
3.文件的插入和覆盖
1.覆盖
@Test
public void Test01() throws IOException {
RandomAccessFile raf1 = null;
raf1 = new RandomAccessFile(new File("C:\\Users\\zhang\\Desktop\\1.txt"), "rw");
raf1.seek(3);//将指针跳到角标为3的位置
raf1.write("xyz".getBytes());//覆盖后,abcdefg变为abcxyzg
raf1.close();
}
2.插入
@Test
public void Test01(){
RandomAccessFile raf1 = null;
try {
raf1 = new RandomAccessFile(new File("C:\\Users\\zhang\\Desktop\\1.txt"), "rw");
raf1.seek(3);//将指针跳到角标为3的位置
//保存位置3之后的所有数据
//创建一个长度为指定文件长度的StringBuilder
StringBuilder sb = new StringBuilder((int) new File("C:\\Users\\zhang\\Desktop\\1.txt").length());
byte[] buffer = new byte[1024];
int len = 0;
while ((len = raf1.read(buffer)) != -1) {
sb.append(new String(buffer, 0, len));
}
//调回指针,写入
raf1.seek(3);
raf1.write("xyz".getBytes());
//将StringBuilder中的内容写入文件
raf1.write(sb.toString().getBytes());
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
raf1.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
执行后,1.txt的内容改变如下
------>
4.从InputStream获得String的三种方法
public String readStringFromInputStream(FileInputStream fis) throws IOException {
//方式一,可能会出现乱码
// String content = "";
// byte[] buffer = new byte[1024];
// int len;
// while((len = fis.read(buffer))!=-1){
// content += new String(buffer);
// }
// return content;
//方式二
BufferedReader br = new BufferedReader(new InputStreamReader(fis));
char[] buf = new char[10];
int len;
String str = "";
while((len = br.read(buf))!=-1){
str += new String(buf,0,len);
}
return str;
//方式三,可避免出现乱码
// ByteArrayOutputStream baos = new ByteArrayOutputStream();
// byte[] buffer = new byte[10];
// int len;
// while((len = fis.read())!=-1){
// baos.write(buffer,0,len);
// }
// return baos.toString();
}