none
[C#]如何知道自定义结构、类型、对象的实际占用字节长度,包括在内存中占用的长度和磁盘上的占用长度? RRS feed

  • 问题

  • [C#]如何知道自定义结构(Struct)、类型、对象(Class)的实际占用字节长度,包括在内存中占用的长度和磁盘上的占用长度?我想规划和更高效构建内存的占用和磁盘的占用,谢谢。

     

    2010年8月3日 7:31

答案

  • 如果您直接使用的是binary formatter序列化  由于需要保存type类型数据  文件存取的结果会比csv大很多的

    如果您使用 json formatter  就会减少很多

    System.Runtime.Serialization.Json


    成为 Microsoft V Dash了。。。 欢迎各位前辈同事在OCS加我
    • 已标记为答案 OpenNovo 2010年8月5日 5:03
    2010年8月3日 10:07
    版主
  • 首先说明,不要提Sizeof,貌似对我的问题没什么帮助。

    我现在主要是应用序列化后,发现文件存取的结果,反而比我原来的csv还要大。

    我总共使用了两种序列化来存取,一种是每一行都是一个struct A,这样我存出来的目标文件最大是原来1csv的10被大。于是我改进,我把这些struct A全部加进一个Array,这时存出来的文件大小是原来csv的2倍大。

    我想这样做的目的是因为,csv中有大量的数字,如果表达一个100,那么int32用的字节数应该比string少,int16肯定更少。如果我要存一个大于int32的数字,我可以使用decimal,而这可能没有string大。而且直接使用二进制,也减少了convert的消耗。但我发现序列化会加入许多额外的标记字符,比如标记这个二进制文件中的类型等,这是我不想去付出的代价,最好有一种方式像csv一样,以逗号或其它特定字符分割,此外没有别的标记,只要我知道、程序知道如何读取存取就行了。


    如果你的Class有方法之类的,内存中占用的大小并不是那么简单的几个属性的大小而已.根据你后面提到的东西,我觉得你需要的是Marshal.

    通过SturctLayerout,你可以将类或sturct封送到一个字节数组,该字节数组只有值,没有数据类型和其它标识.当然,也不会有你想要的逗号,不过没关系,我们有办法分割开,如下定义你的class,只是一个示例,具体的参数,请参看Mrashal的使用

    [StructLayerout()]

    public class FirstMarshalObject

    {

     public int IntValue{get;set;}

    public char Separator1 = ','; // 指定一个分割符号,把它放在两个需要分割开的字段之间.

    public double DValue{get;set;}

    public char Separator2 = ','; // 指定一个分割符号,把它放在两个需要分割开的字段之间.

    public string StringValue{get;set;}
    }

    然后使用Marshal.StructToPtr方法,就可以把上面的对象实例写入一个byte[],这里面只有值,没有仍和标记字符.

    • 已标记为答案 OpenNovo 2010年8月5日 5:03
    2010年8月4日 5:22

全部回复

  • 首先说明,不要提Sizeof,貌似对我的问题没什么帮助。

    我现在主要是应用序列化后,发现文件存取的结果,反而比我原来的csv还要大。

    我总共使用了两种序列化来存取,一种是每一行都是一个struct A,这样我存出来的目标文件最大是原来1csv的10被大。于是我改进,我把这些struct A全部加进一个Array,这时存出来的文件大小是原来csv的2倍大。

    我想这样做的目的是因为,csv中有大量的数字,如果表达一个100,那么int32用的字节数应该比string少,int16肯定更少。如果我要存一个大于int32的数字,我可以使用decimal,而这可能没有string大。而且直接使用二进制,也减少了convert的消耗。但我发现序列化会加入许多额外的标记字符,比如标记这个二进制文件中的类型等,这是我不想去付出的代价,最好有一种方式像csv一样,以逗号或其它特定字符分割,此外没有别的标记,只要我知道、程序知道如何读取存取就行了。

    2010年8月3日 7:43
  • 如果您直接使用的是binary formatter序列化  由于需要保存type类型数据  文件存取的结果会比csv大很多的

    如果您使用 json formatter  就会减少很多

    System.Runtime.Serialization.Json


    成为 Microsoft V Dash了。。。 欢迎各位前辈同事在OCS加我
    • 已标记为答案 OpenNovo 2010年8月5日 5:03
    2010年8月3日 10:07
    版主
  • 首先说明,不要提Sizeof,貌似对我的问题没什么帮助。

    我现在主要是应用序列化后,发现文件存取的结果,反而比我原来的csv还要大。

    我总共使用了两种序列化来存取,一种是每一行都是一个struct A,这样我存出来的目标文件最大是原来1csv的10被大。于是我改进,我把这些struct A全部加进一个Array,这时存出来的文件大小是原来csv的2倍大。

    我想这样做的目的是因为,csv中有大量的数字,如果表达一个100,那么int32用的字节数应该比string少,int16肯定更少。如果我要存一个大于int32的数字,我可以使用decimal,而这可能没有string大。而且直接使用二进制,也减少了convert的消耗。但我发现序列化会加入许多额外的标记字符,比如标记这个二进制文件中的类型等,这是我不想去付出的代价,最好有一种方式像csv一样,以逗号或其它特定字符分割,此外没有别的标记,只要我知道、程序知道如何读取存取就行了。


    如果你的Class有方法之类的,内存中占用的大小并不是那么简单的几个属性的大小而已.根据你后面提到的东西,我觉得你需要的是Marshal.

    通过SturctLayerout,你可以将类或sturct封送到一个字节数组,该字节数组只有值,没有数据类型和其它标识.当然,也不会有你想要的逗号,不过没关系,我们有办法分割开,如下定义你的class,只是一个示例,具体的参数,请参看Mrashal的使用

    [StructLayerout()]

    public class FirstMarshalObject

    {

     public int IntValue{get;set;}

    public char Separator1 = ','; // 指定一个分割符号,把它放在两个需要分割开的字段之间.

    public double DValue{get;set;}

    public char Separator2 = ','; // 指定一个分割符号,把它放在两个需要分割开的字段之间.

    public string StringValue{get;set;}
    }

    然后使用Marshal.StructToPtr方法,就可以把上面的对象实例写入一个byte[],这里面只有值,没有仍和标记字符.

    • 已标记为答案 OpenNovo 2010年8月5日 5:03
    2010年8月4日 5:22