2014-02-24 55 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