【发布时间】:2012-03-10 20:01:57
【问题描述】:
问题是:在运行时设置编码时如何解析文件?
编码可以是:utf-8、utf-16、latin1或other
它的目标是将 ubyte[] 从所选编码转换为字符串。因为当您使用 std.stdio.File.byChunk 或 std.mmFile.MmFile 时,您有 ubyte[] 作为数据。
【问题讨论】:
-
与其发布代码,不如描述您要解决的问题。
问题是:在运行时设置编码时如何解析文件?
编码可以是:utf-8、utf-16、latin1或other
它的目标是将 ubyte[] 从所选编码转换为字符串。因为当您使用 std.stdio.File.byChunk 或 std.mmFile.MmFile 时,您有 ubyte[] 作为数据。
【问题讨论】:
您是否正在尝试将文本文件转换为 utf-8?
如果答案是“是”,Phobos 有专门的功能:@trusted string toUTF8(in char[] s)。
详情请见http://dlang.org/phobos/std_utf.html。
抱歉,如果不是您需要的。
【讨论】:
toUTF8 唯一要做的就是验证输入字符串并返回它的副本。 D 的 string 类型已经使用 UTF-8。 Source
void transcode(Src, Dst)(immutable(Src)[] s, out immutable(Dst)[] r)
transcode 一起使用的新编码?比如Windows-1251(西里尔文),因为它在Windows下被广泛使用。
transcode 不是您的问题解决方案。
我已经找到了一种方法,也许使用 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] ) );
}
}
【讨论】:
D 字符串已经是 UTF-8。无需转码。您可以使用std.utf 中的validate 来检查文件是否包含有效的UTF-8。如果您使用来自std.file 的readText,它将为您进行验证。
【讨论】:
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
}
【讨论】: