RandomAccessFile java IO
Posted hello4world
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了RandomAccessFile java IO相关的知识,希望对你有一定的参考价值。
1.写入字节
/** * java.io.RandomAccessFile * RAF是专门用来读写文件数据的API,其基于指针对文件任意位置进行读写. */ public class RafDemo1 { public static void main(String[] args) throws IOException { /* * 对当前目录下的raf.dat文件读写数据 */ RandomAccessFile raf = new RandomAccessFile("./raf.dat","rw"); /* * void write(int d) * 向文件中写入1个字节,写入的是给定的int值 * 所对应2进制的"低八位" * vvvvvvvv * 00000000 00000000 00000000 00000001 */ raf.write(1); System.out.println("写出完毕!"); raf.close(); } }
2.读取字节
/** * 从文件中读取字节 */ public class RafDemo2 { public static void main(String[] args) throws IOException { RandomAccessFile raf = new RandomAccessFile("raf.dat","r"); /* * int read() * 从文件中读取1个字节,并以int形式 * 返回.若返回值为-1则表示文件末尾 * 00000000 00000000 00000000 11111111 */ int d = raf.read(); System.out.println(d); d = raf.read(); System.out.println(d); System.out.println("读取完毕!"); raf.close(); } }
3.读写基本类型数据以及RAF基于指针的操作
/** * 读写基本类型数据以及RAF基于指针的操作 */ public class RafDemo3 { public static void main(String[] args) throws IOException { RandomAccessFile raf = new RandomAccessFile("raf.dat","rw"); /* * 获取RAF指针位置,创建后从0开始(文件第 * 一个字节位置) */ long pos = raf.getFilePointer(); System.out.println("pos:"+pos); /* * 向文件中写入一个int最大值 * vvvvvvvv * 01111111 11111111 11111111 11111111 * imax>>>24 * 00000000 00000000 00000000 01111111 */ int imax = Integer.MAX_VALUE; System.out.println(imax); raf.write(imax>>>24); System.out.println("pos:"+raf.getFilePointer()); raf.write(imax>>>16); raf.write(imax>>>8); raf.write(imax); System.out.println("pos:"+raf.getFilePointer()); /* * void writeInt(int d) * 将给定的int值对应的4字节一次性写出 * 等同上面四句操作 */ raf.writeInt(imax); System.out.println("pos:"+raf.getFilePointer()); raf.writeLong(123L); System.out.println("pos:"+raf.getFilePointer()); raf.writeDouble(123.123); System.out.println("pos:"+raf.getFilePointer()); System.out.println("写出完毕!"); /* * void seek(long pos) * 移动指针到指定位置 */ raf.seek(0); System.out.println("pos:"+raf.getFilePointer()); /* * int readInt() * 连续读取4个字节并返回该int值,若连续读取 * 4个字节的过程中发现读取到了文件末尾,此时 * 会直接抛出异常EOFException * EOF(end of file)文件末尾 */ int d = raf.readInt(); System.out.println(d); System.out.println("pos:"+raf.getFilePointer()); //读取long值 //1移动指针到long的所在位置 raf.seek(8); //2读取long的8字节还原long值 long lon = raf.readLong(); System.out.println(lon); System.out.println("pos:"+raf.getFilePointer()); double dou = raf.readDouble(); System.out.println(dou); System.out.println("pos:"+raf.getFilePointer()); /* * 将第二个int值内容改为int最小值 */ //1移动指针到第二个int值的开始位置 raf.seek(4); //2重写写入新的int值来覆盖原内容 raf.writeInt(Integer.MIN_VALUE); System.out.println("pos:"+raf.getFilePointer()); raf.seek(4); d = raf.readInt(); System.out.println(d); raf.close(); } }
4.用RAF复制文件(单字节,很慢)
/** * 复制文件 */ public class CopyDemo { public static void main(String[] args) throws IOException { RandomAccessFile src = new RandomAccessFile("./movie.mp4","r"); RandomAccessFile desc = new RandomAccessFile("./movie_cp.mp4","rw"); int d = -1;//用于保存每次读取到的字节 long start = System.currentTimeMillis(); while((d = src.read())!=-1) { desc.write(d); }; long end = System.currentTimeMillis(); System.out.println("复制完毕!耗时:"+(end-start)+"ms"); src.close(); desc.close(); } }
5.用RAF复制文件(块读,速度快)
/** * 通过提高每次读写的数据量,减少实际读写的次数可以提高读写效率. * 单字节读写是随机读写,效率差 * 块读写是一组一组字节的读写,效率高 */ public class CopyDemo2 { public static void main(String[] args) throws IOException { RandomAccessFile src = new RandomAccessFile("movie.mp4","r"); RandomAccessFile desc = new RandomAccessFile("movie_cp.mp4","rw"); /* * int read(byte[] data) * 一次性从文件中读取给定数组总长度的字节量,并将读取到的数据存入到该数组 * 中,返回值为实际读取到的字节量.若返回值为-1,则表示文件末尾(本次没有 * 读取到任何数据) * void write(byte[] data) * 一次性将给定字节数组中所有字节写入文件 * * void write(byte[] data,int s,int len) * 将给定字节数组从下标s处开始的连续len个字节一次性写入文件 */ //10K byte[] data = new byte[1024*10]; int len = -1;//每次实际读取到的字节数 long start = System.currentTimeMillis(); while((len = src.read(data))!=-1) { desc.write(data,0,len); } long end = System.currentTimeMillis(); System.out.println("复制完毕!耗时"+(end-start)+"ms"); src.close(); desc.close(); } }
6.读取文本数据
/** * 读取文本数据 */ public class ReadStringDemo { public static void main(String[] args) throws IOException { RandomAccessFile raf = new RandomAccessFile("raf.txt","r"); byte[] data = new byte[(int)raf.length()]; raf.read(data); String str = new String(data,"UTF-8"); System.out.println(str); raf.close(); } }
7.写入字符串
/** * 使用RAF向文件中写入字符串 */ public class WriteStringDemo { public static void main(String[] args) throws IOException { RandomAccessFile raf = new RandomAccessFile("raf.txt","rw"); String line = "夜空中最亮的星"; /* * String提供了转换为字节的方法: * byte[] getBytes() * 将当前字符串按照系统默认字符集转换为一组字节 * * byte[] getBytes(String csn) * 重载的getBytes方法要求我们传入一个 * 字符串参数表示字符集的名称,该名称 * 不区分大小写,作用是将当前字符串按照 * 给定的字符集转换为一组字节,推荐用 * 这种方式,不要按照系统默认字符集操作. */ byte[] data = line.getBytes("UTF-8"); raf.write(data); raf.write(",能否听清,".getBytes("UTF-8")); System.out.println("写出完毕!"); raf.close(); } }
8.RAF简单应用
/** * 用户注册 * 程序启动后,要求用户输入注册信息: * 用户名,密码,昵称,年龄 * 其中除了年龄是int值外,其余三个是String. * 然后将该信息写入user.dat文件中保存. * * 每条记录固定占用100字节. * 其中用户名,密码,昵称为字符串,各占用32字节. * 年龄为int值固定的4字节. */ public class RegDemo { public static void main(String[] args) throws IOException { Scanner scanner = new Scanner(System.in); System.out.println("欢迎注册"); System.out.println("请输入用户名:"); String username = scanner.nextLine(); System.out.println("请输入密码:"); String password = scanner.nextLine(); System.out.println("请输入昵称:"); String nickname = scanner.nextLine(); System.out.println("请输入年龄:"); int age = Integer.parseInt(scanner.nextLine()); System.out.println(username+","+password+","+nickname+","+age); RandomAccessFile raf = new RandomAccessFile("user.dat","rw"); //首先将指针移动到文件末尾,以便追加新记录 raf.seek(raf.length()); //写入用户名 byte[] data = username.getBytes("UTF-8"); //扩容数组到32字节 data = Arrays.copyOf(data, 32); raf.write(data); //写密码 data = password.getBytes("UTF-8"); data = Arrays.copyOf(data, 32); raf.write(data); //写昵称 data = nickname.getBytes("UTF-8"); data = Arrays.copyOf(data, 32); raf.write(data); //写年龄 raf.writeInt(age); System.out.println("pos:"+raf.getFilePointer()); System.out.println("注册完毕!"); raf.close(); } }
/** * 将user.dat文件中的用户信息显示到控制台 */ 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]; raf.read(data); String username = new String(data,"UTF-8").trim(); raf.read(data); String password = new String(data,"UTF-8").trim(); raf.read(data); String nickname = new String(data,"UTF-8").trim(); int age = raf.readInt(); System.out.println(username+","+password+","+nickname+","+age); System.out.println("pos:"+raf.getFilePointer()); } raf.close(); } }
/** * 完成修改昵称操作 * * 程序启动后要求输入用户名和新的昵称.然后 * 修改user.dat文件中该用户的昵称. * 若输入的用户名在user.dat文件中不存在则输出 * 提示信息:该用户不存在! */ public class UpdateDemo { public static void main(String[] args) throws IOException { Scanner scanner = new Scanner(System.in); System.out.println("请输入用户名:"); String username = scanner.nextLine(); System.out.println("请输入新的昵称:"); String nickname = scanner.nextLine(); RandomAccessFile raf = new RandomAccessFile("user.dat","rw"); boolean updated = false;//是否修改过信息 for(int i=0;i<raf.length()/100;i++) { //移动到每条记录的开始位置 raf.seek(i*100); //读取用户名 byte[] data = new byte[32]; raf.read(data); String name = new String(data,"UTF-8").trim(); if(name.equals(username)) { //移动指针到昵称位置 raf.seek(i*100+64); data = nickname.getBytes("UTF-8"); data = Arrays.copyOf(data, 32); raf.write(data); System.out.println("修改完毕!"); updated = true; break; } } if(!updated) { System.out.println("该用户不存在!"); } raf.close(); } }
以上是关于RandomAccessFile java IO的主要内容,如果未能解决你的问题,请参考以下文章
Java IO流 之 RandomAccessFile 多线程下载