如果您愿意承认 C++ fread() 本质上是脆弱且不可移植的,那么最好编写一个抽象层来读取(和写入)代码数据类型,例如这样的格式很有用:
// returns true on success, false on EOF
public static bool Read(Stream stm, out int val)
{ /* ... */ }
public static bool Read(Stream stm, out short val)
{ /* ... */ }
然后你可以写你的代码是这样的:
if (!Read(stm, out _someMember))
throw SomeException(); // or return a fail code
if (!Read(stm, out _someOtherMember))
throw SomeException();
或者在我的一些代码的情况下,我编写了一个方法,它给出了一个对象、一个流和一个字段或一个属性的名称,读取适当大小的值并设置成员(或者如果它可以抛出异常'找不到它),然后是一个类似的方法,它适用于一个对象和一组名称(或者实际上是可变数量的字符串参数,所以初始化看起来像这样:
public static TTHorizontalHeader FromStream(Stream stm)
{
TTHorizontalHeader header = new TTHorizontalHeader();
if (!Reader.ReadType(stm, header,
"TableVersion", "Ascender", "Descender", "LineGap", "AdvanceWidthMax", "MinLeftSideBearing",
"MinRightSideBearing", "XMaxExtent", "CaretSlopeRise", "CaretSlopeRun", "CaretOffset", "Reserved0",
"Reserved1", "Reserved2", "Reserved3", "MetricDataFormat", "NumberOfHMetrics"))
return null;
return header;
}
但你说,“C++ 不会运行得更快,因为它只执行一个 fread() 吗?” 我回答说,“字节序、数据类型大小、结构填充和对象布局的变化足以让我们不要以性能为幌子继续传播相同的脆弱代码。任何体面的缓冲流无论如何都只会进行一次实际读取,并且读取工作由公正的机器人完成,除了 I/O 的成本,无论是否缓冲,都会使反射和字符串迭代的成本相形见绌。