转自:http://www.cnblogs.com/xudong-bupt/archive/2013/04/20/3028980.html     Thanks

Java对文件的读、写随机访问,RandomAccessFile类的使用分析

  在网上看了一些关于java中的RandomAccessFile类的介绍,又经过查看Java API和自己编的测试程序,总算是对RandomAccessFile的使用有了一定的了解。自己做了以下比较详细的总结吧。

  1.RandomAccessFile类的简单介绍

  该类的实例支持对文件的随机读取和写入。随机存取文件的行为类似存储在文件系统中的一个大型字节数组。存在指向该隐含数组的光标或索引,称为文件指针。读取操作从文件指针开始读取字节,并随着对字节的读取而前移此文件指针。如果随机存取文件以读取/写入模式创建,则写入操作也可用;写入操作从文件指针开始写入字节,并随着对字节的写入而前移此文件指针。该文件指针可以通过 getFilePointer 方法读取,并通过 seek 方法设置。

  通常,如果此类中的所有读取例程在读取所需数量的字节之前已到达文件末尾,则抛出 EOFException。如果由于某些原因无法读取任何字节,而不是在读取所需数量的字节之前已到达文件末尾,则抛出 IOException。需要特别指出的是,如果流已被关闭,则可能抛出 IOException

  2.一个文件读取错误例子引出的思考

import java.io.RandomAccessFile;
public class RandomAccessFile_test {
public static void main(String args[]) throws Exception{
RandomAccessFile access=new RandomAccessFile("c:\\a.txt","rw"); //文件a.txt中只有一个整数1234
System.out.println("文件长度为:"+access.length());
System.out.println("读出的数据位:"+access.readInt());
access.close();
}
}

  执行输出: 文件长度为:4         读出的数据位:825373492

  分析:这是因为RandomAccessFile类的实例都是根据要读取的数据类型来读取指定大小的数据块到变量。int类型占4个字节,因此readInt()函数会从文件开头读取四个字节,每个字节都当做ASCII码。读到的四个ASCII码字节是‘1’,‘2’,‘3’,‘4’,对应十六进制为31H,32H,33H,34H,即31323334H=825373492D。

  3.随机读写文件的存储图示

    3.1数据存放

    (1)用RandomAccessFile类写入的数据一般都是按照ASCII字符的形式保存在文件中的,即以字节的形式,字节是计算机存储设备编址的最小单元。

     (2)Java中各数据类型所占的字节数,如图表所示:

     (3)如下图就是依次写入int,byte,double,int,byte,short,short数据时,在文件中的存放。文件指针会随着数据的写入按照写入后移。

    3.2数据读取

    (1)如用readInt()方法读取一个int数据。文件指针会从当前位置向后读取去四个字节的数据,将取到的数据在强制转换为int类型返回即可,同时文件指针也自动的向后移动了相应的四个位置。

     (2)如果先用readByte()方法读取一个byte数据,读取后文件指针移动了一个位置(还在int原本的四个字节中),这样再用readInt()方法读取一个int数据就会出现乱码。

    (3)也就是说用RandomAccessFile类来操作文件,应该知道数据事先是如何存放的,之后用相应的读取就能顺序的读出,而不会出现乱码。

  4.特殊的数据读取

    4.1字符串读readUTF()和字符串写writeUTF(String str)

    这2个方法都带有“UTF”,是因为写入数据时按照utf-8编码写入,读取时也是utf-8。

    每次写入的字符串的长度是不一定的。因为Java API给出了读取与写入字符串是成对的,因此需要标记每次写入的字符串的长度。每次写入字符串时,会分配2个字节来保存,要写入的字符串的大小,也就是一次写入字符串的大小应该不能大于65536个字节。每次读取的字符串时,先从文件指针的位置开始读取2个字节,分析得到要读取字符串的长度,之后在进行读取。如下图所示:

      

    程序举例:写入2次字符串。

import java.io.RandomAccessFile;
public class Char_Byte{
public static void main(String args[]) throws Exception{
RandomAccessFile access=new RandomAccessFile("C:\\a.txt","rw"); //“读写”方式建立类的实例
access.writeUTF("你好"); //以utf-8格式写入数据
access.writeUTF("朋友"); //以utf-8格式写入数据
access.close();
}
}

    查看生成文件,可以看到在汉字的前面有一些字符,其实就是2个字节的标记字符串长度的ASCII编码。

    4.2读取一行readLine()

     (1)Java API中只有读取一行readLine()方法,然而没有写入一行writeLine()的方法。      (2)在Windows下的行结束符号是“\r\n”。执行readLine()方法,从当前的文件指针开始读取,直到遇到“\r\n”或者文件结束为止。      (3)此方法不支持完整的 Unicode 字符集。所以用writeUTF(String str)写入的中文需要相应的readUTF()读取,以免出现乱码。汉字的UTF-8编码占3个字节,而GBK占用2个字节,汉字的Unicode编码占2字节。      (4)在写文件时,为了可以更换使用readLine(),需要自己写入行结束符号是“\r\n”。     程序举例:写入2次字符串,以行结束符号隔开。

import java.io.RandomAccessFile;
public class Char_Byte{
public static void main(String args[]) throws Exception{
RandomAccessFile access=new RandomAccessFile("C:\\a.txt","rw"); //“读写”方式建立类的实例
access.writeBytes("Hello world!!!"); //写入数据
access.writeBytes("\r\n");//写入行结束符号
access.writeUTF("he he"); //以utf-8格式写入数据
access.close(); access=new RandomAccessFile("C:\\a.txt","rw");
String context=access.readLine(); //读取数据
access.close();
System.out.println(context);
}
}

    程序输出:Hello world!!!

  5.总结

  (1)RandomAccessFile类可以进行文件的随机读写,就好比对一个大型的数组的操作,对于大文件来说速度是比较慢的。

  (2)RandomAccessFile类的实例是根据给定的数据类型大小写入和读取数据,因此用writeXXX()写入的数据,最好用相应的readXXX()来读取。

  (3)RandomAccessFile类的实例写入也是按照字节顺序的写入,生成文件的。要读取这样的文件就必须知道是如何生成的,否则很可能出现读取出乱码。

参考:

1.Java API文档

2.http://blog.csdn.net/akon_vm/article/details/7429245

3.http://zhidao.baidu.com/question/139267246.html

RandomAccessFile乱码问题的更多相关文章

  1. java web 学习十(HttpServletRequest对象1)

    一.HttpServletRequest介绍 HttpServletRequest对象代表客户端的请求,当客户端通过HTTP协议访问服务器时,HTTP请求头中的所有信息都封装在这个对象中,通过这个对象 ...

  2. RandomAccessFile出现中文乱码问题

    之前程序里调用了RandomAccessFile的writeByte(String str)方法,报文里存在中文的时候出现了乱码 后面换成了 write(byte b[])或writeBytes(by ...

  3. RandomAccessFile 文件读写中文乱码解决方案!

    RandomAccessFile 读写文件时,不管文件中保存的数据编码格式是什么   使用 RandomAccessFile对象方法的 readLine() 都会将编码格式转换成 ISO-8859-1 ...

  4. Java IO读写中文各种乱码问题 【转】

    Java IO读写中文各种乱码问题 转自:http://blog.sina.com.cn/s/blog_484ab56f0101muzh.html java.io.*读写中文各种乱码,很费劲.不完全解 ...

  5. 【Java IO流】RandomAccessFile类的使用

    RandomAccessFile类的使用 RandomAccessFile类是java提供的对文件内容的访问,既可以读文件,也可以写文件. 支持随机访问文件,可以访问文件的任意位置. RandomAc ...

  6. Java 输入/输出——处理流(RandomAccessFile)

    RandomAccessFile是Java输入/输出流体系中功能最丰富的文件内容访问类,它提供了众多的方法来访问文件内容,它既可以读取文件内容,也可以向文件输出数据.与普通的输入/输出流不同的是,Ra ...

  7. 读取文件任意位置的内容——RandomAccessFile

    http://www.cnblogs.com/Sunw/p/3801145.html http://www.cnblogs.com/dukc/p/4776868.html http://www.cnb ...

  8. 深入理解JAVA I/O系列四:RandomAccessFile

    一.简述 这个是JDK上的截图,我们可以看到它的父类是Object,没有继承字节流.字符流家族中任何一个类.并且它实现了DataInput.DataOutput这两个接口,也就意味着这个类既可以读也可 ...

  9. Java之RandomAccessFile小结

    今天跟大家分享一下javase中的关于I/O的操作: 有时我们需要在文件的末尾追加一些内容,在这时用RandomAccessFile就很好. 这个类有两个构造方法: RandomAccessFile( ...

随机推荐

  1. 栅栏——CyclicBarrier

    栅栏CyclicBarrier和闭锁CountDownLatch类似,可以说它们都是用来计数,都能阻塞一组线程知道某个事件发生.不同的是闭锁用于等待事件,而栅栏用于等待其他线程. 在前一篇<Co ...

  2. 远程登录Linux服务器修改ssh端口

    公司有部分服务器root密码被禁用,有部分没有禁用,禁用root的服务器需要通过tomcat用户登陆系统,切换至root修改端口,没有禁用的直接修改root密码: #-*- coding:utf-8 ...

  3. Appium 1.6.4 环境搭建流程(Java, Android+IOS, Windows+Mac)

    Appium1.6.4已经出来一段时间了,快速给大家串一下怎么搭建,贴了下载链接 1 基础环境: Windows + Mac: Java JDK 1.8+ (需配置环境变量),Appium1.6.4的 ...

  4. 关于EF中直接执行sql语句的参数化问题

    某天 , 在review项目中代码的时候, 发现有哥们直接通过 Database.ExecuteSqlCommand("select * from order_info where  com ...

  5. STM32伺服编码器接口

    在STM32的高级定时器和一般定时器中有Encoder interface mode(编码器接口),TI1和TI2分别对应TIM_CH1 和TIM_CH2 通道. 一.计数规则如下: 表55的是编码器 ...

  6. 30多个Android 开发者工具 带你开发带你飞

    文中部分工具是收费的,但是绝大多数都是免费的. FlowUp 这是一个帮助你跟踪app整体性能的工具,深入分析关键的性能数据如FPS, 内存, CPU, 磁盘, 等等.FlowUp根据用户数量收费. ...

  7. Java文件流之练习

    1 )将"今年是反法西斯胜利70周年,举国欢庆,所以要放假啦" 字符串 使用文件字符输出流 写入到oldhappy.txt文件中,复写10000行, 要求换行 在文件的开头写入当前 ...

  8. .net—— webservice的新建、发布、使用(最全、最简单)【原创】

    网上有很多关于webservice资料,但大部分都不完整,其中还要很大部分是转载的--.这个悲剧了,自己都没试过能不能用就不负责任的转载. 所以今天对webservice的新建.发布.使用最一个全面. ...

  9. 如何用python绘制各种图形

    1.环境 系统:windows10 python版本:python3.6.1 使用的库:matplotlib,numpy 2.numpy库产生随机数几种方法 import numpy as np nu ...

  10. Web前端的路该怎么走?很迷茫

    “路漫漫其修远兮,吾将上下而求索”,这句出自<离骚>. 虽然端午已过,但是还是不影响一个程序员想表(zhuang)达(boy)自己此刻心情的冲动. 偶然路过同事旁边,不(tou)小(kan ...