Прочитать строку с RandomAccessFile из файла с другой кодировкой

У меня есть большой файл с кодировкой 1250. Строки — это просто отдельные полированные слова друг за другом:

zając
dzieło
kiepsko
etc

Мне нужно довольно быстро выбрать случайные 10 уникальных строк из этого файла. Я сделал это, но когда я печатаю эти слова, они имеют неправильную кодировку [zaj?c, dzie?o, kiepsko...], мне нужна UTF8. Поэтому я изменил свой код, чтобы читать байты из файла, а не просто читать строки, поэтому мои усилия закончились этим кодом:

public List<String> getRandomWordsFromDictionary(int number) {
    List<String> randomWords = new ArrayList<String>();
    File file = new File("file.txt");
    try {
        RandomAccessFile raf = new RandomAccessFile(file, "r");

        for(int i = 0; i < number; i++) {
            Random random = new Random();
            int startPosition;
            String word;
            do {
                startPosition = random.nextInt((int)raf.length());
                raf.seek(startPosition);
                raf.readLine();
                word = grabWordFromDictionary(raf);
            } while(checkProbability(word));
            System.out.println("Word: " + word);
            randomWords.add(word);
        }
    } catch (IOException ioe) {
        logger.error(ioe.getMessage(), ioe);
    }
    return randomWords;
}

private String grabWordFromDictionary(RandomAccessFile raf) throws IOException {
    byte[] wordInBytes = new byte[15];
    int counter = 0;
    byte wordByte;
    char wordChar;
    String convertedWord;
    boolean stop = true;
    do {
        wordByte = raf.readByte();
        wordChar = (char)wordByte;
        if(wordChar == '\n' || wordChar == '\r' || wordChar == -1) {
            stop = false;
        } else {
            wordInBytes[counter] = wordByte;
            counter++;
        }           
    } while(stop);
    if(wordInBytes.length > 0) {
        convertedWord = new String(wordInBytes, "UTF8");
        return convertedWord;
    } else {
        return null;
    }
}

private boolean checkProbability(String word) {
    if(word.length() > MAX_LENGTH_LINE) {
        return true;
    } else {
        double randomDouble = new Random().nextDouble();
        double probability = (double) MIN_LENGTH_LINE / word.length();
        return probability <= randomDouble;         
    }
}

Но что-то не так. Не могли бы вы посмотреть на этот код и помочь мне? Может быть, вы видите какие-то очевидные ошибки, но не очевидные для меня? Я буду признателен за любую помощь.


person Mariusz Grodek    schedule 13.12.2012    source источник


Ответы (1)


Ваш файл в формате 1250, поэтому вам нужно декодировать его в формате 1250, а не UTF-8. Однако вы можете сохранить его как UTF-8 после процесса декодирования.

Charset w1250 = Charset.forName("Windows-1250");
convertedWord = new String(wordInBytes, w1250);
person Esailija    schedule 13.12.2012
comment
Но мне нужны эти слова в UTF8. Есть ли способ преобразовать их в UTF8? Или я вас неправильно понял? - person Mariusz Grodek; 14.12.2012
comment
@MariuszGrodek, что заставляет тебя так думать? Да, вам нужно раскодировать его как 1250, потому что он был закодирован в 1250. После этого вы можете закодировать его в UTF-8. Используйте исходный код для нормального чтения файла, но на этот раз используйте кодек w1250 вместо UTF-8. - person Esailija; 14.12.2012
comment
Извините, я проверил ваш код, и вы абсолютно правы! Я просто неправильно понял этот вопрос. Большое спасибо, что разъяснили мне это. - person Mariusz Grodek; 14.12.2012
comment
@MariuszGrodek после кодирования файла в UTF-8 вы можете прочитать новый файл в UTF-8, потому что теперь он закодирован в UTF-8 :) - person Esailija; 14.12.2012
comment
Я думал, что мне нужно кодировать эти слова прямо в UTF8. Мой плохой :) Спасибо - person Mariusz Grodek; 14.12.2012
comment
Через некоторое время есть другая мысль. Ваше решение работает в Windows, но когда я захотел сделать это в Linux, у меня возникла проблема. Буквы не были закодированы должным образом. - person Mariusz Grodek; 11.02.2013
comment
@MariuszGrodek вам нужно использовать ту же кодировку, что и файл, это не имеет ничего общего с операционной системой Windows. - person Esailija; 11.02.2013