将原始二进制结构写入 D 中的文件?

Writing a raw binary structure to file in D?

我正在尝试创建一个二进制文件,其中包含一些 struct 中定义的多个二进制记录。但是,我似乎无法找到如何去做。查看其他示例,我成功地编写了 strings,但没有问题 struct。我只想像在 Cfwrite(3) 中那样写它,但是在 D 版本 2.

这是我到目前为止尝试过的方法:

Error: template std.stdio.File.rawWrite cannot deduce function from argument types !()(TitleRecord), candidates are:

/usr/lib/ldc/x86_64-linux-gnu/include/d/std/stdio.d(1132): std.stdio.File.rawWrite(T)(in T[] buffer)

阅读the docs has not been very helpful (writing strings works for me too, but not writing struct). I'm sure there must be simple way to do it, but I'm not able to find it.... Other SO questions did not help me。我 D 1.0,它可能已经用 stream.writeExact(&tr, tr.sizeof) 完成了,但这不再是一个选项。

import std.stdio;

struct TitleRecord {
        short id;
        char[49] text;
};

TitleRecord tr;

void main()
{
 auto stream = File("filename.dat","wb+");
 tr.id = 1234;
 tr.text = "hello world";
 writeln(tr);
 //stream.write(tr);
 //stream.rawWrite(tr);
 //stream.rawWrite(cast(ubyte[52]) tr);
 //stream.rawWrite(cast(ubyte[]) tr);
 //fwrite(&tr, 4, 1, stream);
}

为此,错误是说它需要一个数组而不是一个结构。因此,一种简单的方法是简单地将指针切片并将其提供给 rawWrite:

stream.rawWrite((&tr)[0 .. 1]);

(&tr) 获取地址,从而将您的结构转换为指针。然后 [0 .. 1] 表示从头开始获取一部分,只抓取一个元素。

因此你现在有一个 T[] rawWrite 可以处理包含你的一个元素。

请注意,如果您使用 @safe 注释,这将不会通过,您必须将其标记为 @trusted。当然,你的结构中的任何引用(包括 string)都将被写为二进制指针而不是数据,正如你从 C 经验中肯定知道的那样。但是如果你在那里展示了你就没事了。

编辑:顺便说一句,如果你愿意,你也可以只使用 fwrite,copy/pasting 来自 C 的相同代码(除了它是 foo.sizeof 而不是 sizeof foo) . D File 只是 C 的 FILE* 的一个小包装,您可以使用 stream.getFP() http://dpldocs.info/experimental-docs/std.stdio.File.getFP.html )

rawWrite 需要一个数组,但有很多解决方法。

一种是创建单元素数组。

file.rawWrite([myStruct]);

另一个正在将结构转换为数组。我的名为 bitleveld 的库有一个名为 reinterpretAsArray 的函数。这也使得创建所述结构的校验和变得容易。

我偶尔会遇到使用这种方法对齐的问题,所以要小心。可以通过更改结构的 align 属性 来修复。