@aarifkhamdi

Как правильно считать файл в кодировке UTF-8?

Есть большущий файл в кодировке UTF-8.

Хочу делать 2 вещи:
1) Читать до определённых символов (пусть, например, "а" и "б")
2) знать о какой символ я остановился ("а" или "б")

Пытаюсь ковыряться с BufferedReader, но ничего путного не выходит.
Суть того что я делаю: читаю в буфер, декодирую, потом хочу работать. Всё ломается на "декодирую", потому что UTF-8 может иметь символы разной длины. И я попадаю в ситуацию, когда считалась в буфер только часть символа (например, 1 байт из 3-х).

Как сделать? Мб подход неверный? Надеюсь на стандартное решение, которое я почему-то не вижу.
  • Вопрос задан
  • 755 просмотров
Решения вопроса 1
@aarifkhamdi Автор вопроса
В результате узнал про CodePoint и получилось вот что:
import java.io.BufferedReader;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;


public class Main {
    public static void main(String[] args) {
        Path path = Paths.get("src/test");
        assert Files.exists(path) : "Файл не найден";
        try (BufferedReader bufferedReader = Files.newBufferedReader(path)) {
            int ch;
            char surrogate = 0;
            while ((ch = bufferedReader.read()) != -1) {
                if (surrogate != 0) {
                    ch = Character.toCodePoint(surrogate, (char) ch);
                    surrogate = 0;
                } else if (Character.isHighSurrogate((char) ch)) {
                    surrogate = (char) ch;
                    continue;
                }
//                в результате в ch имеем CodePoint
//                можем работать как с обычным символом
                System.out.println(Character.toChars(ch));
            }
        } catch (IOException e) {
            e.printStackTrace();
            System.exit(-1);
        }
    }
}


Вдруг кому пригодится.

ps:
в src/test лежит
"幸福幸福幸福幸福一个梦想一个梦想Ðtestтест123456"
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 2
sergey-gornostaev
@sergey-gornostaev Куратор тега Java
Седой и строгий
Не надо ничего декодировать, просто укажите кодировку файла при открытии
try (BufferedReader in = new BufferedReader(
       new InputStreamReader(
         new FileInputStream(file), "UTF8"))) {
    // Делайте с входным потоком всё, что вам нужно
}
Ответ написан
Комментировать
SagePtr
@SagePtr
Еда - это святое
К примеру, воспринимать буфер как поток байт, как только чтение доходит до конца, то подгружать следующую порцию и сбрасывать указатель на начало. При декодировании не полагаться на жёстко закодированные смещения типа a[i+1], a[i+2], a[i+3] и т.п., а получать следующий байт как-нибудь типа того: mybuffer.getNextByte() (в свою очередь, метод getNextByte должен обрабатывать ситуацию, когда буфер исчерпан, и в таком случае подгружать следующую порцию байт)
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы