как декодировать ubyte [] в указанную кодировку? - PullRequest
3 голосов
/ 11 марта 2012

Проблема в : как анализировать файл, если кодировка установлена ​​во время выполнения?

кодировка может быть: utf-8 , utf-16 , latin1 или other

Цель - преобразовать ubyte [] в строку из выбранной кодировки.Потому что, когда вы используете std.stdio.File.byChunk или std.mmFile.MmFile, у вас есть ubyte [] в качестве данных.

Ответы [ 4 ]

1 голос
/ 11 марта 2012

Вы пытаетесь конвертировать текстовый файл в UTF-8? Если ответ «да», у Фобоса есть специальная функция для этого: @trusted string toUTF8(in char[] s). Подробнее см. http://dlang.org/phobos/std_utf.html.

Извините, если это не то, что вам нужно.

0 голосов
/ 25 сентября 2012

File.byChunk возвращает диапазон, который возвращает ubyte [] через front.

Быстрый поиск в Google показал, что UTF-8 использует от 1 до 6 байтов для кодирования данных, поэтому просто убедитесь, что у вас всегда есть 6 байтов данных, и вы можете использовать декодирование std.encoding для преобразования его в символ dchar,Затем вы можете использовать toUFT8 из std.utf для преобразования в обычную строку вместо dstring.

Функция преобразования ниже преобразует любой массив без знака в строку.

import std.encoding, std.stdio, std.traits, std.utf;

void main()
{
    File input = File("test.txt");

    string data = convert(input.byChunk(512));

    writeln("Data: ", data);
}

string convert(R)(R chunkRange) 
in
{
    assert(isArray!(typeof(chunkRange.front)) && isUnsigned!(typeof(chunkRange.front[0])));
} 
body
{
    ubyte[] inbuffer;
    dchar[] outbuffer;

    while(inbuffer.length > 0 || !chunkRange.empty)
    {
        while((inbuffer.length < 6) && !chunkRange.empty)// Max UTF-8 byte length is 6
        {
            inbuffer ~= chunkRange.front;
            chunkRange.popFront();
        }

        outbuffer ~= decode(inbuffer);
    }

    return toUTF8(outbuffer); // Convert to string instead of dstring
}
0 голосов
/ 11 марта 2012

D строк уже UTF-8. Транскодирование не требуется. Вы можете использовать validate из std.utf, чтобы проверить, содержит ли файл действительный UTF-8. Если вы используете readText из std.file, это сделает проверку за вас.

0 голосов
/ 11 марта 2012

Я нашел способ, может быть, лучше использовать std.algorithm.reduce

import std.string;
import std.stdio;
import std.encoding;
import std.algorithm;

void main( string[] args ){
    File f = File( "pathToAfFile.txt", "r" );
    size_t i;
    auto e = EncodingScheme.create("utf-8");
    foreach( const(ubyte)[] buffer; f.byChunk( 4096 ) ){
        size_t step = 0;
        if( step == 0 ) step = e.firstSequence( buffer );
        for( size_t start; start + step < buffer.length; start = start + step )
            write( e.decode( buffer[start..start + step] ) );
    }
}
...