2014-02-24 34 views
1

主营:Java的RandomAccessFile的EOFException类

package main; 

import racreader.RAFReader; 

public class RandomAccessFile { 

    public static void main(String[] args) { 
     if (args.length != 2) { 
      System.err.println("Wrong arguments length"); 
      System.exit(1); 
     } 
     try { 
      RAFReader reader = new RAFReader (args[0]); 
      try { 

       String output = reader.readUTF(Integer.parseInt(args[1])); 
       System.out.print(output); 
      } catch (Exception e) { 
       System.err.println(e.toString()); 
      } finally { 
       reader.close(); 
      } 
     } catch (Exception e) { 
      System.err.println(e.toString()); 
     } 
    } 
} 

RAFReader:

package racreader; 

import java.io.FileNotFoundException; 
import java.io.IOException; 
import java.io.RandomAccessFile; 

public class RAFReader { 

    private final String fileName; 
    private final RandomAccessFile reader; 

    public RAFReader(String fileName) throws FileNotFoundException { 
     this.fileName = fileName; 
     this.reader = openFile(); 

    } 

    private RandomAccessFile openFile() throws FileNotFoundException { 
     RandomAccessFile reader = new RandomAccessFile(fileName, "r"); 
     return reader; 
    } 

    public String readUTF(int offset) throws IOException { 
     reader.seek(offset); 
     String output = reader.readUTF(); 
     return output; 
    } 

    public void close() throws IOException { 
     reader.close(); 
    } 
} 

的问题是在EOFException类中的每个文件(即使是在UTF8编码),每所抵消。为什么?

UPD:我试图让我的程序与文件正在与此内容:

Это тест UTF-8 чтения 

它只有offset = 0工作正常。任何其他的偏移量都会引发EOFException。

回答

2

readUTF()/writeUTF()方法从RandomAccesFile使用约定编写Java对象,这些对象不一定被UTF编码的文本文件所支持。 readUTF()不是用来读取任何文本文件,它最初不是用RandomAccesFile.writeUTF()写的。

由于方法Javadocs指定,readUTF()假定它读取的前两个字节包含以下字符串中的字节数。如果通过配对writeUTF()方法将该字符串写入文件,则会出现这种情况,但在文本文件的情况下,由于前两个字节将包含字符串中的实际字符,因此会导致间歇发生EOFException

就你而言,一组不同的类可以解决这个问题。考虑重写使用InputStreamReaderRAFReader类:

public String readUTF(int offset) throws IOException { 
    FileInputStream is = new FileInputStream(fileName); 

    Reader fileReader = new InputStreamReader(is, "UTF-8"); 
    StringBuilder stringBuilder = new StringBuilder(); 

    fileReader.skip(offset); 

    int charsRead; 
    char buf[] = new char[256]; 

    //Read until there is no more characters to read. 
    while ((charsRead = fileReader.read(buf)) > 0) { 
     stringBuilder.append(buf, 0, charsRead); 
    } 

    fileReader.close(); 

    return stringBuilder.toString(); 
} 

如果使用RandomAccesFile是必须的,你可以用它包装了RandomAccesFile输入流。要做到这一点,最简单的方法是通过FileChannel,通过RandomAccesFile封装:

InputStream is = Channels.newInputStream(reader.getChannel()); 
+0

但是有时我在阅读开始时会用一些'RandomAccessFile'偏移量来获得一些特殊的符号。如何自动同步UTF'InputStream'? – michaeluskov

+0

如果偏移量是要跳过的字符数,请确保您正在使用'Reader#skip()',而不是'RandomAccessFile#seek()'。后者将以字节为单位,因此它可以将流指向由几个字节编码的字符的中间,因此是特殊符号。 –

0

EOFException - 如果在读取所有 字节之前该文件到达结尾。在你有EOFException类

一种可能的方式是线

reader.seek(offset); 
String output = reader.readUTF(); 

也许offset值高的文件长度。试用offset = 0并检查是否得到EOF或不。

+0

我不明白EOF只有'偏移== 0' – michaeluskov

+0

@ user23791那是你的解决方案。不要使用大于文件长度的“seek”功能来设置文件指针。 –

+0

但是为什么'offset = 1'会抛出EOFException?我的文件包含多个字节 – michaeluskov