1

我想使用WriteFile将大(〜500mb)多维数组写入文件(因为BinaryFormatter在写入大东西时非常慢,并且.Net框架中没有其他方法可以编写多维字节数组,只有单字节或一维数组, 并且进行 for 循环和逐字节写入速度很慢)。

然而,事实证明,这是被禁止的:

IOException
The OS handle's position is not what FileStream expected. Do not use a handle simultaneously in one FileStream and in Win32 code or another FileStream. This may cause data loss.

除了在使用 WriteFile 编写后每次想使用 BinaryFormatter 编写时重新打开文件流之外,还有什么办法吗?

4

1 回答 1

0

(我知道这个问题已被放弃,很快就会被删除。)

首先,WriteFile不要BinaryFormatter混合。WriteFile假设您知道文件格式,即写入文件的字节的解释。BinaryFormatter是一个序列化程序,基于 Microsoft .NET 实现内部的文件格式(有些人会说是专有的,即使信息可以在线找到)。因此,您甚至无法BinaryFormatter在 Microsoft .NET 和 Mono C# 之间传递由序列化的文件。

根据 OP 的描述,很明显 OP 一开始就不应该使用BinaryFormatter。否则 OP 将全权负责此类数据的丢失(不可恢复性)。

正如 Hans Passant 评论的那样,渐近地说, 的性能FileStream.Write应该能够与 Win32 调用相匹配。WriteFile这意味着每次调用的时间开销可以建模为alpha * numberOfBytesWritten + beta,其中beta是每次调用的纯常数开销。通过增加每次调用写入的字节数,可以使这种开销相对可以忽略不计。

鉴于我们不能直接将多维 C# 数组传递给WriteFile,这里是建议。根据 OP 的评论,假设多维数组将具有 size byte[1024, 1024, 1024]

  • 首先,分配一个足够大的临时一维数组。典型的建议范围从 4KB 到几 MB,但这只是一个优化细节。对于这个例子,我们使用 1MB =byte[1048576]因为它很好地划分了总数组大小。

  • 然后,我们在最外层的维度上编写一个顶层 for 循环。

  • 在下一步中,我们使用System.Array.Copy实用函数将字节从最里面的两个维度复制1024 x 1024到临时一维数组中。这依赖于多维数组的 C# 规范,如System.Array.Copy函数中所述:

在多维数组之间复制时,数组的行为类似于一个长的一维数组,其中行(或列)在概念上是首尾相连的。

  • 一旦复制到临时 1D 数组中,就可以将其写入FileStream.Write.
于 2015-05-26T17:02:42.350 回答