如何原始写入数组!ubyte?

How to rawWrite an Array!ubyte?

几天前,我在为 ZX Spectrum 编写一个 TAP 文件生成器。要将字节增量写入输出,我会在 Delphi 或 C++ 上使用流,但 D 已弃用流。

所以我选择了rawWrite。至于字节存储,它是 Array!uint (更正:它是 Array!ubyte) 来自 std.containers。但是 rawWrite 只能写传统的数组,不能写容器。似乎没有简单的方法可以将数组转换为数组。 (使用 .array 适用于 Array!uint,但不适用于 Array!ubyte)

最后我用了一个简单的动态数组,但是给人一种不友好的感觉。

您始终可以使用 std.array.array 函数从 Array 数据中获取数组,如下面的 D 代码所示:

import std.algorithm;
import std.stdio;
import std.range;
import std.container.array;

void main() {
  auto fn = "test.dat";
  // scope(exit) std.file.remove(fn);

  auto f = File(fn,"wb");
  Array!ubyte myarr = [ubyte(5), ubyte(4), ubyte(3), ubyte(2), ubyte(1)];
  f.rawWrite(myarr.array);
}

将其保存到 arr2.d,编译并 运行:

dmd arr2.d && ./arr2 

让我们验证它是否写出了我们期望的内容:

hexdump -C test.dat
00000000  05 04 03 02 01                                    |.....|
00000005

std.containers.array.Array 拥有并完全封装其数据,不提供对其的直接访问。这是因为它管理数据的生命周期,所以对 Array 的任何操作都会使指向其内部数据的任何指针无效。因此,获取 Array 的元素作为连续向量的唯一方法是将它们一个一个地复制到例如一个标准的 D 数组。 std.array.array 函数将任意范围复制到 D 数组,有助于完成此任务:

import std.array;
import std.container.array;


Array!uint ci = [1, 2, 3];
uint[] ai = ci.array;
assert(ai == [1, 2, 3]);

Array!ubyte cb = [ubyte(1), ubyte(2), ubyte(3)];
ubyte[] ab = cb.array;
assert(ab == [ubyte(1), ubyte(2), ubyte(3)]);

在这一点上,这对于将 Array 元素直接写入文件或完全避免使用 Array 似乎没有多大优势。