1. RandomAccessFile    

  Java提供了一个可以对文件随机访问的操作,访问包括读和写操作。该类名为RandomAccessFile。该类的读写是基于指针的操作。

 

1)文件访问模式

  RandomAccessFile在堆文件进行随机访问操作时有两个模式,分为只读模式(只读取文件数据),和读写模式(对文件数据进行读写)。

  在创建RandomAccessFile时,其提供的构造方法要求我们传入访问模式:

  • RandomAccessFile(File file,String mode)
  • RandomAccessFile(String filename,String mode)

  其中构造方法的第一个参数是需要访问的文件,而第二个参数则是访问模式:“r”字符串表示对该文件的访问是只读的;”rw“字符串表示对该文件的访问是读写模式。

2)字节数据读写操作

2.1)write(int d)方法

  • 该方法可以向文件中写出字节:void write(int d);
  • 该方法会根据当前指针所在位置初写入一个字节,是将参数int的”低8位“写出

2.2)read()方法

  • 该方法可以从文件中读取字节:int read();
  • 该方法会从文件中读取一个byte(8位)填充到int的低8位,高24位为0,返回值范围整数:0~255,如果返回-1表示读取到了文件末尾。每次读取后自动移动文件指针,准备下次读取。

案例1:write和read演示

import java.io.IOException;
import java.io.RandomAccessFile; public class RandomAccessFile_writeAndread {
public static void main(String[] args) throws IOException {
RandomAccessFile raf = new RandomAccessFile("raf.txt","rw");
raf.write(24);
int x = raf.read();
System.out.println(x); //写完之后指针会停留在文件的最后一个字节位置,即文件末尾,所以读取的时候是-1
raf.seek(0); //将指针移动到开始位置
x = raf.read();
System.out.println(x);
raf.close();
}
} /*
运行结果:
-1
24
*/

  

  

案例2:read超范围演示

import java.io.IOException;
import java.io.RandomAccessFile; public class RandomAccessFile_writeAndread {
public static void main(String[] args) throws IOException {
RandomAccessFile raf = new RandomAccessFile("raf.txt","rw");
raf.write(264); //范围是0~255,超范围
raf.seek(0); //将指针移动到开始位置
int x = raf.read();
System.out.println(x);
raf.close();
}
} /*
运行结果:
8 分析:因为read()方法会读取当前指针所在位置的一个字节(8位),264二进制的低8位是:00001000,所以指针从0开始读取到的是8
*/

  

  

2.3)write(byte[] d)方法

  • 该方法可以向文件中写出一组字节:void write(byte[] d)
  • 该方法会根据当前指针所在的位置处连续写出给定数组中的所有字节

  与该方法相似的还有一个常用方法:

  • void write(byte[] d,int offset,int len)
  • 该方法会根据当前指针所在位置处连续写出给定数组中的部分字节,这个部分是从数组的offset处开始,连续len个字节

2.4)read(byte[] b)方法

  • 该方法可以从文件中批量读取字节:int read(byte[] b)
  • 该方法会从指针位置处尝试最多读取给定数组的总长度的字节量,并从给定的字节数组第一个位置开始,将读取到的字节顺序存放至数组中,返回值为实际读取到的字节量。

案例3:批量写入和读取演示

import java.io.IOException;
import java.io.RandomAccessFile; public class RandomAccessFile_writeAndread {
public static void main(String[] args) throws IOException {
RandomAccessFile raf = new RandomAccessFile("raf.txt","rw");
String str = "你好,Java!";
byte[] date = str.getBytes(); //将字符串转换为字节
raf.write(date); //将字节写入文件
raf.seek(0); //将指针移动到初始位置
byte[] dateRead = new byte[100]; //创建字符串数组用于批量读取文件字节
int re = raf.read(dateRead);
System.out.println(re);
raf.close();
}
} //运行结果:10

  

案例4:批量写入和读取演示2

import java.io.IOException;
import java.io.RandomAccessFile; public class RandomAccessFile_write {
public static void main(String[] args) throws IOException {
RandomAccessFile raf = new RandomAccessFile("raf.txt","rw");
String str = "你好,Java!";
byte[] date = str.getBytes();
raf.write(date,0,4); //写入”你好“即4个字节
raf.seek(0);
byte[] dateRead = new byte[100];
int re = raf.read(dateRead);
System.out.println(re);
raf.close();
}
} //运行结果:4

  

  

2.5)close()方法

  • RandomAccessFile在对文件访问操作全部结束后,要调用close()方法来释放与其关联的所有系统资源:void close()

2.6)getFilePointer方法

  • RandomAccessFile的读写操作都是基于指针的,也就是说在指针当前所指向的位置进行读写操作
  • 方法:long getFilePointer(),该方法用于获取当前RandomAccessFile的指针位置

案例5:指针演示

import java.io.IOException;
import java.io.RandomAccessFile; public class RandomAccessFile_writeAndread {
public static void main(String[] args) throws IOException {
RandomAccessFile raf = new RandomAccessFile("raf.txt","rw");
System.out.println(raf.getFilePointer()); //开始指针位置0
raf.write('A');
System.out.println(raf.getFilePointer()); //指针位置1
raf.writeInt(15); //与write()方法区别
System.out.println(raf.getFilePointer()); //指针位置5
raf.close();
}
} /*
运行结果:
0
1
5
*/

  

  

2.7)seek方法

  • 该方法用于移动指针的位置:void seek(long pos)

2.8)skipBytes方法

  • 该方法用于尝试跳过输入的n个字节以丢弃跳过的字节(跳过的字节不读取):int skipBytes(int n)
  • 该方法可能跳过一些较少数量的字节(可能包括0),这可能由任意数量的条件引起,在跳过n个字节之前已经到大文件的末尾只是其中的一种可能
  • 该方法不抛出EOFException,返回跳过的实际字节数,如果n为负数,则不跳过任何字节

案例6:seek和skipBytes演示

import java.io.IOException;
import java.io.RandomAccessFile; public class RandomAccessFile_writeAndread {
public static void main(String[] args) throws IOException{
RandomAccessFile raf = new RandomAccessFile("raf.txt","rw");
String str = "你好,Java!";
byte[] date = str.getBytes();
raf.write(date);
System.out.println(raf.getFilePointer());
raf.seek(0);
System.out.println(raf.getFilePointer());
raf.skipBytes(5);
System.out.println(raf.getFilePointer());
raf.close();
}
} /*
运行结果:
10
0
5
*/

2.9)案例演示

案例1:批量写文件

import java.io.IOException;
import java.io.RandomAccessFile; public class RandomAccessFile_write {
public static void main(String[] args) throws IOException {
RandomAccessFile raf = new RandomAccessFile("raf.txt","rw");
String str = "好好学习,天天向上";
byte[] date = str.getBytes("GBK"); //将字符串转换为字节数组,这里可以设置字符集,如果不写则为系统默认的字符集
raf.write(date);
System.out.println("写出完毕");
raf.close();
}
}

案例2:批量读文件

*
* 字符串提供了构造方法可以将给定的字节数组
* 转换为字符串.
* String(byte[] d,int offset,int len,String csn)
* 将给定字节数组从下标offset处开始连续len个
* 字节按照csn指定的字符集转换为字符串
*
*/
import java.io.IOException;
import java.io.RandomAccessFile; public class RandomAccessFile_read {
public static void main(String[] args) throws IOException {
RandomAccessFile raf = new RandomAccessFile("raf.txt","r");
byte[] date = new byte[100];
int len = date.length;
String str = new String(date,0,len,"GBK");
System.out.println(str);
raf.close();
}
}

  

案例3:按字节复制文件(速度慢)

import java.io.IOException;
import java.io.RandomAccessFile; public class RandomAccessFile_copyFileDemo {
public static void main(String[] args) throws IOException {
RandomAccessFile src = new RandomAccessFile("raf.txt","r");
RandomAccessFile desc = new RandomAccessFile("rafcopy.txt","rw");
int d = -1;
while((d=src.read())!=-1){ //每次让d按字符读取源文件,当读到文件末尾的时候(也就是d=-1)的时候停止循环
desc.write(d); //每次读取到源文件写入到目标文件
}
System.out.println("复制完毕");
src.close();
desc.close();
}
}

 

案例4:按字节数组批量复制文件(速度快)

import java.io.IOException;
import java.io.RandomAccessFile; public class RandomAccessFile_copyFileDemo02 {
public static void main(String[] args) throws IOException {
RandomAccessFile src = new RandomAccessFile("demo.jpg","r");
RandomAccessFile desc = new RandomAccessFile("democopy.jpg","rw");
byte[] date = new byte[1024*10];
int len = -1;
while((len=src.read(date))!=-1){
//将给定字节数组中从offset处开始连续的len个字节一次性写出
desc.write(date,0,len);
}
System.out.println("复制完毕");
src.close();
desc.close();
}
}

  

 

最新文章

  1. jQuery美女幻灯相册轮播源代码
  2. [nodejs] Error: unable to verify the first certificate
  3. 简单的redis 性能测试
  4. [转载] 理解 epoll 的事件触发机制
  5. xcode6默认不支持armv7s
  6. https://github.com/mlzboy/spider-impl.git
  7. 【无聊放个模板系列】POJ 1274 (匈牙利)
  8. ASP.NET MVC之PagedList使用
  9. 记微信开发(自定义回复&关注回复)
  10. 与众不同 windows phone (27) - Feature(特性)之搜索的可扩展性, 程序的生命周期和页面的生命周期, 页面导航, 系统状态栏
  11. More DETAILS! PBR的下一个发展在哪里?
  12. Gym101473A Gym101473E Gym101473F-前缀和
  13. POJ 3581 Sequence [后缀数组]
  14. ARKit1.5 采坑
  15. 记一个在移动端调试 web 页面的方法
  16. Linux运维40道精华题
  17. 在阿里云服务器上搭建xampp遇到的问题
  18. 使用pickle进行存储变量
  19. Windows Server 2003出现Directory Listing Denied This Virtual Directory does not allow contents to be listed.的解决方案
  20. Oracle使用startup与startup force启动的区别

热门文章

  1. 学习总结:斯特林数( Stirling number )
  2. linux c实现的提取文件名的小程序
  3. windows和Dos常见命令总结
  4. Spark HA 配置中spark.deploy.zookeeper.url 的意思
  5. FISCO BCOS WorkShop | 区块链开发特训营,开课啦!
  6. 今天是 Java 诞生日,Java 24 岁了!
  7. gitlab之source tree使用方法
  8. FileUtils简化你的文件操作
  9. UML类图学习总结
  10. 健康检查NET Core之跨平台的实时性能监控