很久没弄文件随机读取了,这回遇到需求,好了 不啰嗦 直接上代码:RandomAccessFile randomAccessFile = new RandomAccessFile(fileName,"rw");
// 设置文件的内容为0字节
randomAccessFile.setLength(0);
//循环写入
for (int i = 0; i < 5; i++) {
randomAccessFile.writeUTF("我爱你!i love you!");
}
// 重新把文件指针定位到开始处
randomAccessFile.seek(0);
System.out.println("=>"+randomAccessFile.getFilePointer());
randomAccessFile.skipBytes(7);
System.out.println("=>"+randomAccessFile.getFilePointer());
String data = randomAccessFile.readUTF();
while (data!=null) {
System.out.println(data);
data = randomAccessFile.readUTF();
}
以上代码使用RandomAccessFile 来做随机读取,
希望在skipBytes(7)后开始循环遍历出来;
无奈控制台只是输出了:没有输出任何东西,如果设置skipBytes(0);就能输出了,
不知道这是什么问题?该如何解决才好呢?Java文件随机读取RandomAccessFileskipBytes
// 设置文件的内容为0字节
randomAccessFile.setLength(0);
//循环写入
for (int i = 0; i < 5; i++) {
randomAccessFile.writeUTF("我爱你!i love you!");
}
// 重新把文件指针定位到开始处
randomAccessFile.seek(0);
System.out.println("=>"+randomAccessFile.getFilePointer());
randomAccessFile.skipBytes(7);
System.out.println("=>"+randomAccessFile.getFilePointer());
String data = randomAccessFile.readUTF();
while (data!=null) {
System.out.println(data);
data = randomAccessFile.readUTF();
}
以上代码使用RandomAccessFile 来做随机读取,
希望在skipBytes(7)后开始循环遍历出来;
无奈控制台只是输出了:没有输出任何东西,如果设置skipBytes(0);就能输出了,
不知道这是什么问题?该如何解决才好呢?Java文件随机读取RandomAccessFileskipBytes
randomAccessFile.seek(0);
在while之前
再加randomAccessFile.seek(0);
这个用了不就没有skipBytes(7)的效果了么!!
何况上面的代码就是:
randomAccessFile.seek(0);
skipBytes(7);
的
需要的是跳过N个字节后开始读取。
上面代码中使用的是
randomAccessFile.skipBytes(7);
但是却没有效果,反而啥都不输出了!
writeUTF方法每次写入都会先占用2个字节,用来写入后续UTF-8字符的二进制字节长度,readUTF读取时也会先找这2个特殊字节。
你划过7个字节,readUTF从读取了错误的特殊字节,当然会报错。
// 设置文件的内容为0字节
randomAccessFile.setLength(0);
//循环写入
for (int i = 0; i < 5; i++) {
randomAccessFile.writeUTF("我爱你!i love you");
}
// 重新把文件指针定位到开始处
randomAccessFile.seek(0);
System.out.println("=>"+randomAccessFile.getFilePointer());
// randomAccessFile.skipBytes(7);
System.out.println("=>"+randomAccessFile.getFilePointer());
String data;
while (randomAccessFile.getFilePointer() < randomAccessFile.length()) {
data = randomAccessFile.readUTF();
System.out.println(data);
}
是的 、这个会抛出异常,用try处理了,当时没有发出来,
可是我试了下用
randomAccessFile.skipBytes(X);划过字节;
X除了0之外任何数都会报错;
那如果想跳过几个字节再读取,该怎么写才好呢?
还能用skipBytes来做么?
不行哦、除了
randomAccessFile.skipBytes(0);之外其它的都会报错:
java.io.EOFException
是的 、这个会抛出异常,用try处理了,当时没有发出来,
可是我试了下用
randomAccessFile.skipBytes(X);划过字节;
X除了0之外任何数都会报错;
那如果想跳过几个字节再读取,该怎么写才好呢?
还能用skipBytes来做么?因为你是使用writeUTF写入的,这个方法不仅仅是写入你要求写入的字符串,而且会在写入字符串之前先用2个字节来写入字符串的字节长度信息,就好像定位信息一样。你使用skipBytes只要大于0,他就会从错误的地方开始读取2个字节,当作定位信息,所以肯定会出错。
举个例子,如果把 我爱你 三个字使用writeUTF方法写入,文件的十六进制内容是:
00 09 E6 88 91 E7 88 B1 E4 BD A0
头2个字节00 09说明你写入的字符串数据占位9个字节,也就是后面的9个,每3个代表一个汉字。如果你划过2个字节,从E6 88读起,readUTF就会把E6 88当作你写入的字符串长度,很明显是错误的。
按道理writeUTF写入的数据是不应该使用skipBytes的,不清楚你为什么这么做,要划过的话,只能刚好划过你一次写入字节总长度,比如上面的那个例子,你写入2次 我爱你,读取的时候先划过 11个字节,这样就会刚好从第二次写入的内容开始,也就是第二个 00 09 开始。
try
{
randomAccessFile = new RandomAccessFile("RandomAccess.txt", "rw");
//设置文件的内容为0字节
randomAccessFile.setLength(0);
//循环写入
String loveStr = "我爱你!i love you!";
byte[] bArr = loveStr.getBytes();
for (int i = 0; i < 5; i++)
{
randomAccessFile.write(bArr);
}
System.out.println("=>" + randomAccessFile.getFilePointer());
// 重新把文件指针定位到开始处
randomAccessFile.seek(0);
System.out.println("=>" + randomAccessFile.getFilePointer());
//跳过中文?
byte[] zhByte = "我爱你!".getBytes();
randomAccessFile.skipBytes(zhByte.length);
System.out.println("=>" + randomAccessFile.getFilePointer());
byte[] data = new byte[bArr.length - zhByte.length];
while ((randomAccessFile.read(data)) != -1)
{
String str = new String(data,"GBK");
System.out.println(str);
randomAccessFile.skipBytes(zhByte.length);
}
}
catch (FileNotFoundException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
catch (IOException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
是的 、这个会抛出异常,用try处理了,当时没有发出来,
可是我试了下用
randomAccessFile.skipBytes(X);划过字节;
X除了0之外任何数都会报错;
那如果想跳过几个字节再读取,该怎么写才好呢?
还能用skipBytes来做么?因为你是使用writeUTF写入的,这个方法不仅仅是写入你要求写入的字符串,而且会在写入字符串之前先用2个字节来写入字符串的字节长度信息,就好像定位信息一样。你使用skipBytes只要大于0,他就会从错误的地方开始读取2个字节,当作定位信息,所以肯定会出错。
举个例子,如果把 我爱你 三个字使用writeUTF方法写入,文件的十六进制内容是:
00 09 E6 88 91 E7 88 B1 E4 BD A0
头2个字节00 09说明你写入的字符串数据占位9个字节,也就是后面的9个,每3个代表一个汉字。如果你划过2个字节,从E6 88读起,readUTF就会把E6 88当作你写入的字符串长度,很明显是错误的。
按道理writeUTF写入的数据是不应该使用skipBytes的,不清楚你为什么这么做,要划过的话,只能刚好划过你一次写入字节总长度,比如上面的那个例子,你写入2次 我爱你,读取的时候先划过 11个字节,这样就会刚好从第二次写入的内容开始,也就是第二个 00 09 开始。分析的合理,我原先也是这样想的,按道理说
写入:“ 我爱你i love you” 这三个汉字以及后面的英文
加上计数的两个字节以后
一共是大于11个字节的,
也就是说skipByte 11个字节后 就刚好把汉字部分给划掉了,
可是实际上还是报错了,还是EOFException异常,
也许这个是readUTF的读取机制与分析的有点区别的原因!
对了,这个方法是可行的;
后面我又换了方式用这个代码测试了下;
就是把写入的部分注释掉,
即:
// randomAccessFile.write(bArr);
意思就是不在程序中写入,而是直接到txt记事本中去手动写进去,如图:然后再把读取模式由rw 改为只读取 r ;
这个时候运行会出现个错误:
java.io.IOException: 拒绝访问。
当再把模式改为rw才可以操作,
只是改为rw,运行一次后控制台没有输出跳过汉字后剩下的数据,当然也没有报错,而且还会把txt里面的数据都删掉,变成空白了!
这个是什么原因呢?
是的 、这个会抛出异常,用try处理了,当时没有发出来,
可是我试了下用
randomAccessFile.skipBytes(X);划过字节;
X除了0之外任何数都会报错;
那如果想跳过几个字节再读取,该怎么写才好呢?
还能用skipBytes来做么?因为你是使用writeUTF写入的,这个方法不仅仅是写入你要求写入的字符串,而且会在写入字符串之前先用2个字节来写入字符串的字节长度信息,就好像定位信息一样。你使用skipBytes只要大于0,他就会从错误的地方开始读取2个字节,当作定位信息,所以肯定会出错。
举个例子,如果把 我爱你 三个字使用writeUTF方法写入,文件的十六进制内容是:
00 09 E6 88 91 E7 88 B1 E4 BD A0
头2个字节00 09说明你写入的字符串数据占位9个字节,也就是后面的9个,每3个代表一个汉字。如果你划过2个字节,从E6 88读起,readUTF就会把E6 88当作你写入的字符串长度,很明显是错误的。
按道理writeUTF写入的数据是不应该使用skipBytes的,不清楚你为什么这么做,要划过的话,只能刚好划过你一次写入字节总长度,比如上面的那个例子,你写入2次 我爱你,读取的时候先划过 11个字节,这样就会刚好从第二次写入的内容开始,也就是第二个 00 09 开始。分析的合理,我原先也是这样想的,按道理说
写入:“ 我爱你i love you” 这三个汉字以及后面的英文
加上计数的两个字节以后
一共是大于11个字节的,
也就是说skipByte 11个字节后 就刚好把汉字部分给划掉了,
可是实际上还是报错了,还是EOFException异常,
也许这个是readUTF的读取机制与分析的有点区别的原因!我举例的是写入我爱你 3个字,需要划过11个字节;针对你说的那个 “我爱你!i love you”,感叹号是英文的则需要划过22个字节,如果感叹号是中文需要划过24个字节。
对了,这个方法是可行的;
后面我又换了方式用这个代码测试了下;
就是把写入的部分注释掉,
即:
// randomAccessFile.write(bArr);
意思就是不在程序中写入,而是直接到txt记事本中去手动写进去,如图:然后再把读取模式由rw 改为只读取 r ;
这个时候运行会出现个错误:
java.io.IOException: 拒绝访问。
当再把模式改为rw才可以操作,
只是改为rw,运行一次后控制台没有输出跳过汉字后剩下的数据,当然也没有报错,而且还会把txt里面的数据都删掉,变成空白了!
这个是什么原因呢?
你改为只读模式了,就不能再使用setLength方法了,你把setLength(0)执行,就等于把内容都请空了。