Чтение символов Юникода из большого текстового файла - PullRequest
3 голосов
/ 18 марта 2019

Как читать символы Юникода? как "ä"

public static string Read(int length, string absolutePath)
{
    StringBuilder resultAsString = new StringBuilder();

    using (MemoryMappedFile memoryMappedFile = MemoryMappedFile.CreateFromFile(absolutePath))
    using (MemoryMappedViewStream memoryMappedViewStream = memoryMappedFile.CreateViewStream(0, length))
    {
        for (int i = 0; i < length; i++)
        {                  
            int result = memoryMappedViewStream.ReadByte();

            if (result == -1)
            {
                break;
            }
            char letter = (char)result;

            resultAsString.Append(letter);
        }
    }

    return resultAsString.ToString();
}

чтение int (результат) - 195, а приведение char дает мне не ожидаемый результат.

Ответы [ 2 ]

2 голосов
/ 18 марта 2019

Не уверен, если это то, что вы просите, но вы можете использовать StreamReader

StreamReader sr = new StreamReader(stream, Encoding.Unicode);
0 голосов
/ 19 марта 2019

Если вы просто хотите загрузить и прочитать файл UTF-8 в строковую переменную, код может быть простым:

var text = File.ReadAllText(filePath, Encoding.UTF8);

Если вы настаиваете на обработке UTF-8 побайтовые данные, хотя есть немного более сложный синтаксический анализ.
Вот грубый (но работающий) набросок, чтобы пойти с вашим исходным кодом:

StringBuilder resultAsString = new StringBuilder();

using (MemoryMappedFile memoryMappedFile = MemoryMappedFile.CreateFromFile(filePath))
using (MemoryMappedViewStream viewStream = memoryMappedFile.CreateViewStream(0, new FileInfo(filePath).Length))
{
    int b;
    while((b = viewStream.ReadByte()) != -1)
    {
        int acc = b;

        bool readUtfDataBytes(int bytesToRead)
        {
            while (bytesToRead-- > 0)
            {
                var nextB = viewStream.ReadByte();
                if (nextB == -1) return false; // EOS reached
                if ((nextB & 0xC0) != 0x80) return false; // invalid UTF-8 data byte
                acc <<= 6;
                acc |= nextB & 0x3F;
            }
            return true;
        }

        if (b >= 0xF0) // 1111 0000
        {
            acc &= 0x07;
            if (!readUtfDataBytes(3)) break; // break on malformed UTF-8
        }
        else if (b >= 0xE0) // 1110 0000
        {
            acc &= 0x0F;
            if (!readUtfDataBytes(2)) break; // break on malformed UTF-8
        }
        else if (b >= 0xC0) // 1100 0000
        {
            acc &= 0x1F;
            if (!readUtfDataBytes(1)) break; // break on malformed UTF-8
        }
        else if (b >= 0x80)
        {
            break; // break on malformed UTF-8
        }

        if (acc == 0xFEFF)
        {
            // ignore UTF-8 BOM
        }
        else
        {
            resultAsString.Append(Char.ConvertFromUtf32(acc));
        }
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...