很久没弄文件随机读取了,这回遇到需求,好了 不啰嗦 直接上代码: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

解决方案 »

  1.   

    在while之前增加一句试试:
    randomAccessFile.seek(0);
      

  2.   


    在while之前
    再加randomAccessFile.seek(0); 
    这个用了不就没有skipBytes(7)的效果了么!!
    何况上面的代码就是:
    randomAccessFile.seek(0);
    skipBytes(7);

    需要的是跳过N个字节后开始读取。
      

  3.   

    现在需要的是跳过N个字节后开始读取,
    上面代码中使用的是
    randomAccessFile.skipBytes(7);
    但是却没有效果,反而啥都不输出了!
      

  4.   

    你没报错?我这显示的报错,你外层套了try catch 吧。你为什么要写skipBytes(7)?
    writeUTF方法每次写入都会先占用2个字节,用来写入后续UTF-8字符的二进制字节长度,readUTF读取时也会先找这2个特殊字节。
    你划过7个字节,readUTF从读取了错误的特殊字节,当然会报错。
      

  5.   

    另外readUTF读到末尾后,再次尝试读取并不会返回null,而是抛出EOF异常,你最好写几次就读几次。
      

  6.   

    或者比较FilePointer和length。 RandomAccessFile randomAccessFile = new RandomAccessFile("d:/345.txt","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;
    while (randomAccessFile.getFilePointer() < randomAccessFile.length()) {
    data = randomAccessFile.readUTF();
    System.out.println(data);
    }
      

  7.   


    是的 、这个会抛出异常,用try处理了,当时没有发出来,
    可是我试了下用
    randomAccessFile.skipBytes(X);划过字节;
    X除了0之外任何数都会报错;
    那如果想跳过几个字节再读取,该怎么写才好呢?
    还能用skipBytes来做么?
      

  8.   


    不行哦、除了
    randomAccessFile.skipBytes(0);之外其它的都会报错:
    java.io.EOFException
      

  9.   


    是的 、这个会抛出异常,用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 开始。
      

  10.   

    跳过中文是把?        RandomAccessFile randomAccessFile;
            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();
            }
      

  11.   

    楼上的方法可行,如果你要想划过中文,只能放弃使用writeUTF和readUTF。
      

  12.   


    是的 、这个会抛出异常,用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的读取机制与分析的有点区别的原因!
      

  13.   


    对了,这个方法是可行的;
    后面我又换了方式用这个代码测试了下;
    就是把写入的部分注释掉,
    即:
    // randomAccessFile.write(bArr);
    意思就是不在程序中写入,而是直接到txt记事本中去手动写进去,如图:然后再把读取模式由rw 改为只读取 r ;
    这个时候运行会出现个错误:
    java.io.IOException: 拒绝访问。
    当再把模式改为rw才可以操作,
    只是改为rw,运行一次后控制台没有输出跳过汉字后剩下的数据,当然也没有报错,而且还会把txt里面的数据都删掉,变成空白了!
    这个是什么原因呢?
      

  14.   


    是的 、这个会抛出异常,用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个字节。
      

  15.   

    writeUTF写入的东西是不能划过的,如果要划过只能划过整体,比如你writeUTF执行了2次,可以划过第一次执行的写入总长度,这样readUTF就会直接读取你第二次写入的内容。但是不能只划过第一次写入中的中文部分,我说的是这个意思,因为readUTF就找不到定位字节了。如果你要划过一部分写入内容,就应该采用12楼的方法。
      

  16.   


    对了,这个方法是可行的;
    后面我又换了方式用这个代码测试了下;
    就是把写入的部分注释掉,
    即:
    // randomAccessFile.write(bArr);
    意思就是不在程序中写入,而是直接到txt记事本中去手动写进去,如图:然后再把读取模式由rw 改为只读取 r ;
    这个时候运行会出现个错误:
    java.io.IOException: 拒绝访问。
    当再把模式改为rw才可以操作,
    只是改为rw,运行一次后控制台没有输出跳过汉字后剩下的数据,当然也没有报错,而且还会把txt里面的数据都删掉,变成空白了!
    这个是什么原因呢?
    你改为只读模式了,就不能再使用setLength方法了,你把setLength(0)执行,就等于把内容都请空了。