【问题标题】:how to decode ubyte[] to a specified encoding?如何将 ubyte[] 解码为指定的编码?
【发布时间】:2012-03-10 20:01:57
【问题描述】:

问题是:在运行时设置编码时如何解析文件?

编码可以是:utf-8utf-16latin1other

它的目标是将 ubyte[] 从所选编码转换为字符串。因为当您使用 std.stdio.File.byChunk 或 std.mmFile.MmFile 时,您有 ubyte[] 作为数据。

【问题讨论】:

  • 与其发布代码,不如描述您要解决的问题。

标签: d phobos


【解决方案1】:

您是否正在尝试将文本文件转换为 utf-8? 如果答案是“是”,Phobos 有专门的功能:@trusted string toUTF8(in char[] s)。 详情请见http://dlang.org/phobos/std_utf.html

抱歉,如果不是您需要的。

【讨论】:

  • toUTF8 唯一要做的就是验证输入字符串并返回它的副本。 D 的 string 类型已经使用 UTF-8。 Source
  • @Cyber​​Shadow 好的,但是如何将此“标准”UTF-8 转换为另一种编码?我在 std.encoding 中只找到这个:void transcode(Src, Dst)(immutable(Src)[] s, out immutable(Dst)[] r)
  • 看起来像 OP 的问题解决方案。但是:如何正确添加与transcode 一起使用的新编码?比如Windows-1251(西里尔文),因为它在Windows下被广泛使用。
  • toUTF8 将 char[] 转换为字符串。在这里我想将 ubyte[] 转换为编码
  • 嗯,char 和 ubyte 类型的长度相同(8 位,无符号)。所以我不明白,为什么transcode 不是您的问题解决方案。
【解决方案2】:

我已经找到了一种方法,也许使用 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] ) );
    }
}

【讨论】:

  • 这是一个糟糕的解决方案。块大小可能会在 UTF-8 序列的中间剪切文件。看起来您的代码不会导致任何异常,但它会跳过字符。
  • 直到块是 utf-8(或其他)长度的倍数是安全的。 e.firstSequence 授予此权限。如果 e.firstSequence 的值是块值的倍数,则可以。
  • UTF-8 是一种可变长度编码。
【解决方案3】:

D 字符串已经是 UTF-8。无需转码。您可以使用std.utf 中的validate 来检查文件是否包含有效的UTF-8。如果您使用来自std.filereadText,它将为您进行验证。

【讨论】:

  • 我知道这是一个例子。我想阅读各种编码的文本。它可以是 latin1 或其他。
  • 这就是为什么说出您要解决的实际问题很重要的原因! :) 使用您发布的代码,我只能猜测您真正想要做什么。
  • 我已经编辑了问题。事实上,我想使用 1) MmFile 2) 在运行时将 ubyte[] 转换为编码。首先它很好。
【解决方案4】:

File.byChunk 返回一个范围,该范围通过前面返回一个 ubyte[]。

快速的 Google 搜索似乎表明 UTF-8 使用 1 到 6 个字节对数据进行编码,因此只需确保您始终拥有 6 个字节的数据,并且可以使用 std.encoding 的解码将其转换为 dchar 字符。然后,您可以使用 std.utf 的 toUFT8 转换为常规字符串而不是 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
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-10-07
    • 1970-01-01
    • 2020-08-14
    • 1970-01-01
    • 2017-07-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多