【问题标题】:Buffer.BlockCopy - Object must be an array of primitivesBuffer.BlockCopy - 对象必须是基元数组
【发布时间】:2020-11-14 05:55:01
【问题描述】:

我正在尝试从二进制文件中读取数据,我可以读取所有数据类型,但当它是字符串数组时,我收到错误“对象必须是原语数组”

这是我的代码中出现错误的地方

        binReader.BaseStream.Seek(position, SeekOrigin.Begin);
        buff = binReader.ReadBytes(369);
        string[,,] MyArray = new string[1000, 4, 4];
        Buffer.BlockCopy(buff, 0, MyArray , 0, buff.Length);

知道如何解决这个问题吗?

【问题讨论】:

  • 对于原始(“blittable”)类型,字节缓冲区中有自然表示,而对于字符串则没有。所以问题是:你的字符串是如何在缓冲区中布置的?以前面的计数还是以 0 结尾?哪种编码(ASCII、UTF8、...)?
  • 这就是问题所在,我怀疑这是我没有使用任何编码的原因,但是当我从二进制文件中读取时我无法克服它,任何机会如何在我进行编码时正在读取数据? @KlausGütter
  • 您必须知道字符串是如何存储在文件中的。您是如何创建文件的?
  • @KlausGütter 不知道说实话

标签: c# arrays string byte


【解决方案1】:

我们可以在buffer.blockCopy 的文档中看到它只适用于原始类型:

参数异常

src 或 dst 不是基元数组。

Type.IsPrimitive我们可以看出原始类型有:

基本类型为 Boolean、Byte、SByte、Int16、UInt16、Int32、UInt32、Int64、UInt64、IntPtr、UIntPtr、Char、Double 和 Single。

值得注意的是,string 不是原始类型,因此不能与 blockCopy 一起使用。

由于问题没有描述字符串是如何存储的,因此很难知道如何读取数据。我建议在数据前面加上数组大小。这样阅读会是这样的:

    public static string[,,] Read3DArray( BinaryReader binReader)
    {
        var xSize = binReader.ReadInt32();
        var ySize = binReader.ReadInt32();
        var zSize= binReader.ReadInt32();

        var result = new string[xSize, ySize, zSize];
        for (int x = 0; x < xSize; x++)
        {
            for (int y = 0; y < ySize; y++)
            {
                for (int z = 0; z < zSize; z++)
                {
                    result[x, y, z] = binReader.ReadString();
                }
            }
        }

        return result;
    }

如果您知道字符串数组的大小,则可以跳过读取 x/y/z 最大值。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-02-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-09-21
    相关资源
    最近更新 更多