RandomAccessFile

转载自  RandomAccessFile

 

RandomAccessFile是用来访问那些保存数据记录的文件的,你就可以用seek( )方法来访问记录,并进行读写了。这些记录的大小不必相同;但是其大小和位置必须是可知的。但是该类仅限于操作文件。

RandomAccessFile不属于InputStream和OutputStream类系的。实际上,除了实现DataInput和DataOutput接口之外(DataInputStream和DataOutputStream也实现了这两个接口),它和这两个类系毫不相干,甚至不使用InputStream和OutputStream类中已经存在的任何功能;它是一个完全独立的类,所有方法(绝大多数都只属于它自己)都是从零开始写的。这可能是因为RandomAccessFile能在文件里面前后移动,所以它的行为与其它的I/O类有些根本性的不同。总而言之,它是一个直接继承Object的,独立的类。

基本上,RandomAccessFile的工作方式是,把DataInputStream和DataOutputStream结合起来,再加上它自己的一些方法,比如定位用的getFilePointer( ),在文件里移动用的seek( ),以及判断文件大小的length( )、skipBytes()跳过多少字节数。此外,它的构造函数还要一个表示以只读方式("r"),还是以读写方式("rw")打开文件的参数 (和C的fopen( )一模一样)。它不支持只写文件。

只有RandomAccessFile才有seek搜寻方法,而这个方法也只适用于文件。BufferedInputStream有一个mark( )方法,你可以用它来设定标记(把结果保存在一个内部变量里),然后再调用reset( )返回这个位置,但是它的功能太弱了,而且也不怎么实用。

RandomAccessFile的绝大多数功能,但不是全部,已经被JDK 1.4的nio的"内存映射文件(memory-mapped files)"给取代了,你该考虑一下是不是用"内存映射文件"来代替RandomAccessFile了。

Java代码 

  1. import java.io.IOException;  
  2. import java.io.RandomAccessFile;  
  3.   
  4. public class TestRandomAccessFile {  
  5.     public static void main(String[] args) throws IOException {  
  6.         RandomAccessFile rf = new RandomAccessFile("rtest.dat", "rw");  
  7.         for (int i = 0; i < 10; i++) {  
  8.             //写入基本类型double数据  
  9.             rf.writeDouble(i * 1.414);  
  10.         }  
  11.         rf.close();  
  12.         rf = new RandomAccessFile("rtest.dat", "rw");  
  13.         //直接将文件指针移到第5个double数据后面  
  14.         rf.seek(5 * 8);  
  15.         //覆盖第6个double数据  
  16.         rf.writeDouble(47.0001);  
  17.         rf.close();  
  18.         rf = new RandomAccessFile("rtest.dat", "r");  
  19.         for (int i = 0; i < 10; i++) {  
  20.             System.out.println("Value " + i + ": " + rf.readDouble());  
  21.         }  
  22.         rf.close();  
  23.     }  
  24. }   

内存映射文件

内存映射文件能让你创建和修改那些因为太大而无法放入内存的文件。有了内存映射文件,你就可以认为文件已经全部读进了内存,然后把它当成一个非常大的数组来访问。这种解决办法能大大简化修改文件的代码。
fileChannel.map(FileChannel.MapMode mode, long position, long size)将此通道的文件区域直接映射到内存中。注意,你必须指明,它是从文件的哪个位置开始映射的,映射的范围又有多大;也就是说,它还可以映射一个大文件的某个小片断。


MappedByteBuffer是ByteBuffer的子类,因此它具备了ByteBuffer的所有方法,但新添了force()将缓冲区的内容强制刷新到存储设备中去、load()将存储设备中的数据加载到内存中、isLoaded()位置内存中的数据是否与存储设置上同步。这里只简单地演示了一下put()和get()方法,除此之外,你还可以使用asCharBuffer( )之类的方法得到相应基本类型数据的缓冲视图后,可以方便的读写基本类型数据。

Java代码 

  1. import java.io.RandomAccessFile;  
  2. import java.nio.MappedByteBuffer;  
  3. import java.nio.channels.FileChannel;  
  4.   
  5. public class LargeMappedFiles {  
  6.     static int length = 0x8000000; // 128 Mb  
  7.   
  8.     public static void main(String[] args) throws Exception {  
  9.         // 为了以可读可写的方式打开文件,这里使用RandomAccessFile来创建文件。  
  10.         FileChannel fc = new RandomAccessFile("test.dat", "rw").getChannel();  
  11.         //注意,文件通道的可读可写要建立在文件流本身可读写的基础之上  
  12.         MappedByteBuffer out = fc.map(FileChannel.MapMode.READ_WRITE, 0, length);  
  13.         //写128M的内容  
  14.         for (int i = 0; i < length; i++) {  
  15.             out.put((byte) 'x');  
  16.         }  
  17.         System.out.println("Finished writing");  
  18.         //读取文件中间6个字节内容  
  19.         for (int i = length / 2; i < length / 2 + 6; i++) {  
  20.             System.out.print((char) out.get(i));  
  21.         }  
  22.         fc.close();  
  23.     }  
  24. }  

 

尽管映射写似乎要用到FileOutputStream,但是映射文件中的所有输出 必须使用RandomAccessFile,但如果只需要读时可以使用FileInputStream,写映射文件时一定要使用随机访问文件,可能写时要读的原因吧。

 

该程序创建了一个128Mb的文件,如果一次性读到内存可能导致内存溢出,但这里访问好像只是一瞬间的事,这是因为,真正调入内存的只是其中的一小部分,其余部分则被放在交换文件上。这样你就可以很方便地修改超大型的文件了(最大可以到2 GB)。注意,Java是调用操作系统的"文件映射机制"来提升性能的。

 

 

原创  RandomAccessFile类的应用 收藏

/*
 * 程序功能:演示了RandomAccessFile类的操作,同时实现了一个文件复制操作。
 */
package com.lwj.demo;

import java.io.*;

public class RandomAccessFileDemo {
 public static void main(String[] args) throws Exception {
  RandomAccessFile file = new RandomAccessFile("file", "rw");
  // 以下向file文件中写数据
  file.writeInt(20);// 占4个字节
  file.writeDouble(8.236598);// 占8个字节
  file.writeUTF("这是一个UTF字符串");// 这个长度写在当前文件指针的前两个字节处,可用readShort()读取
  file.writeBoolean(true);// 占1个字节
  file.writeShort(395);// 占2个字节
  file.writeLong(2325451l);// 占8个字节
  file.writeUTF("又是一个UTF字符串");
  file.writeFloat(35.5f);// 占4个字节
  file.writeChar('a');// 占2个字节

  file.seek(0);// 把文件指针位置设置到文件起始处

  // 以下从file文件中读数据,要注意文件指针的位置
  System.out.println("——————从file文件指定位置读数据——————");
  System.out.println(file.readInt());
  System.out.println(file.readDouble());
  System.out.println(file.readUTF());

  file.skipBytes(3);// 将文件指针跳过3个字节,本例中即跳过了一个boolean值和short值。
  System.out.println(file.readLong());

  file.skipBytes(file.readShort()); // 跳过文件中“又是一个UTF字符串”所占字节,注意readShort()方法会移动文件指针,所以不用加2。
  System.out.println(file.readFloat());
  
  //以下演示文件复制操作
  System.out.println("——————文件复制(从file到fileCopy)——————");
  file.seek(0);
  RandomAccessFile fileCopy=new RandomAccessFile("fileCopy","rw");
  int len=(int)file.length();//取得文件长度(字节数)
  byte[] b=new byte[len];
  file.readFully(b);
  fileCopy.write(b);
  System.out.println("复制完成!");
 }
}

运行结果(同时生成相应的文件):

——————从file文件指定位置读数据——————
20
8.236598
这是一个UTF字符串
2325451
35.5

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/327644.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

JSR303常见参数

常见参数 NotNull(message "名字不能为空")private String userName;Max(value 120, message "年龄最大不能查过120")private int age;Email(message "邮箱格式错误")private String email;空检查Null 验证对象是否为nullNotNull 验证对象是…

解决:Could not find metadata org.apache.maven.plugins:maven-archetype-plugin/maven-metadata.xml in loc

我的方法 1.电脑可以Google 你要开启那个小飞机 2.笔记本连接手机热点 3.重新操作秒下下来 总结&#xff1a; 公司的网太差 &#xff0c; 也有可能做了外网访问的限制 下面是一个大神的方法 https://blog.csdn.net/Ajax_mt/article/details/81870086 解决:Could n…

Linux 临时表空间满了,Temporary表空间100%解决方案

说明&#xff1a;temp表空间的TS# 为 3*, So TS# 1 4一下是摘自Metalink的说明The DROP_SEGMENTS event~~~~~~~~~~~~~~~~~~~~~~~Available from 8.0 onwards.DESCRIPTIONFinds all the temporary segments in a tablespace which are notcurrently locked and drops them.For t…

Ajax传递json数据

Ajax的传递json数据的实现&#xff1a; 看这篇之前建议大家去看看前面两篇文章&#xff1a; 1.Ajax基本案例详解之$.ajax的实现 2.Ajax基本案例详解之$.get的实现 现在来看一下具体的内容&#xff0c;在index.jsp的<script>里面写&#xff1a; $.ajax({url:"…

ASP.NET Core服务器综述

ASP.NET Core应用通过一个进程内的HTTP服务器实例实现运行&#xff0c;这个服务器实例侦听HTTP请求并将请求作为组成HttpContext的一组请求功能集暴露给我们的应用程序。 ASP.NET Core搭载两个服务器实现&#xff1a; Kestrel是一个基于libuv的跨平台HTTP服务器&#xff0c;lib…

多环境切换---SpringBoot

多环境切换 优先级由高到底&#xff0c;高优先级的配置会覆盖低优先级的配置&#xff1b; profile是Spring对不同环境提供不同配置功能的支持&#xff0c;可以通过激活不同的环境版本&#xff0c;实现快速切换环境&#xff1b; [外链图片转存失败,源站可能有防盗链机制,建议…

Java.io.File.getPath()方法实例

转载自 Java.io.File.getPath()方法实例 java.io.File.getPath() 方法将抽象路径名到路径名字符串。为了分离名称的序列所产生的字符串使用默认名称分隔符。 声明 以下是java.io.File.getPath()方法的声明&#xff1a; public String getPath() String getPath() 参数 NA …

linux中usb设备名,Linux 中识别 USB 设备名字的 4 种方法

摘要&#xff1a; 对于初学者来说&#xff0c;在 Linux 系统里你必须掌握的技术之一就是识别出插入系统里的各种设备。这也许是你的系统硬盘、外部的存储设备或者是可移动设备&#xff0c;比如 USB 设备或 SD 闪存卡等。 现如今&#xff0c;使用 USB 设备来传输文件是十分常见的…

作为 IT 行业的过来人,你有什么话想对后辈说的?

程序员转型 作为 IT 行业的过来人&#xff0c;你有什么话想对后辈说的&#xff1f; - 圆胖肿的回答 - 知乎 https://www.zhihu.com/question/312019918/answer/1246349365 圆胖肿 程序猿 1,644 人赞同了该回答 给资本家做工具人不靠谱&#xff0c;迟早被卷 如果你是男…

探究Java File类中list()、listFiles()的使用及区别,认识和使用匿名内部类

转载自 探究Java File类中list()、listFiles()的使用及区别&#xff0c;认识和使用匿名内部类 内容概要&#xff1a; 1、认识File类&#xff1b; 2、File的构造函数&#xff1b; 3、list()及其重载方法的使用&#xff0c;匿名内部类的两种使用方式&#xff1b; 4、list…

自动配置原理---SpringBoot

自动配置原理 配置文件到底能写什么&#xff1f;怎么写&#xff1f; SpringBoot官方文档中有大量的配置&#xff0c;我们无法全部记住 分析自动配置原理 我们以**HttpEncodingAutoConfiguration&#xff08;Http编码自动配置&#xff09;**为例解释自动配置原理&#xff1b;…

Docker 部署dotnetcore

安装docker 系统还是之前centos 7.1 https://www.docker.com/products/docker#/linux yum update 创建源: /etc/yum.repos.d/docker.repo tee /etc/yum.repos.d/docker.repo <<-EOF [dockerrepo] nameDocker Repository baseurlhttps://yum.dockerproject.org/repo/main/…

Ajax基本案例详解之$.getjson的实现

Ajax的$.gethson实现&#xff1a; 看这篇之前建议大家去看看前面两篇文章&#xff1a; 1.Ajax基本案例详解之$.ajax的实现 2.Ajax基本案例详解之$.get的实现 现在写一下$.getjson里面的主要内容&#xff1a; $.getJSON("doindex.jsp",{email:$("#email&q…

Python基础案例(一)

早就有耳闻Python是多么多么的强大了&#xff0c;满怀一颗好奇心去研究研究&#xff0c;初学几天&#xff0c;果然不出所料&#xff0c;Python很强大&#xff0c;相对java,C# 等来说也比较简单&#xff0c;于是在学习中做了点总结&#xff0c;欢迎评论区留言&#xff0c;互相交…

虚拟机安装windows ghost版本系统记录完整过程

重点 1.磁盘一定要分成2个 2.直接安装第一个盘 就是进入CD后选1 自动安装 https://blog.csdn.net/hanzl1/article/details/79298787 虚拟机安装windows ghost版本系统记录完整过程 NO如果 2018-02-09 15:26:08 15193 收藏 5 分类专栏&#xff1a; windows 虚拟机 版权 …

linux下kill指令默认信号,Linux基础命令之kill命令

相信大家在使用Linux的过程中都会遇到过某个程序出错导致系统锁死的情况&#xff0c;按照常规的思维我们会通过重启来重新启动系统。然而事实上在Linux中并不需要进行重启就能够完成出错程序的关闭操作。在Linux中我们可以通过使用"kill"命令来强制终结它。那么到底它…

java中File类的getPath(),getAbsolutePath(),getCanonicalPath()区别

转载自 java中File类的getPath(),getAbsolutePath(),getCanonicalPath()区别 今天看一个例子&#xff0c;里面用到File类的getCanonicalPath()方法&#xff0c;忽然忘记这个方法返回的是什么样的路径了&#xff0c;跟getPath()和getAbsolutePath()有什么区别&#xff1f;带着这…

Supervisor 守护 dotnetcore 程序

环境准备 1.设置nginx 服务开机启动 systemctl enable nginx.servic 2.安装Supervisor yum install python-setuptools easy_install supervisor 3.配置Supervisor mkdir /etc/supervisorecho_supervisord_conf > /etc/supervisor/supervisord.conf#指定配置文件supervisord…

Python解决中文乱码问题

在学Python的过程中&#xff0c;一直困扰我的就是中文乱码&#xff0c;输上英文之后看上去不得劲&#xff0c;所以只能解决这个乱码问题&#xff0c;为了这个问题&#xff0c;百度查了谷歌查&#xff0c;还有包括自己总结的&#xff0c;终于解决了&#xff0c;下面看个案例吧&a…