二进制格式化程序,设置位置以反序列化特定对象 [英] Binary Formatter, Set Position to Deserialize Particular Object

查看:107
本文介绍了二进制格式化程序,设置位置以反序列化特定对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想问一下用二进制格式化程序对对象进行序列化/反序列化。好吧,我正在尝试反序列化FileStream中的对象,该对象包含许多已经一个一序列化的对象。对象的大小太大,无法保存在进程内存中,这就是为什么我不将所有对象打包在一个对象中的原因,例如: List ,因为它们在进程内存中太大,所以我需要序列化根据需要多次。通过这种方式,不需要很多处理内存,因为我只是交替处理一个对象,而不是所有对象。看一下我的意思

 < FileStream> 
----对象1 -----大小= 100 Mb ------索引= 0
----对象2 -----大小= 100 Mb-- --- index = 1
----对象3 -----大小= 100 Mb ------ index = 2
----对象4 -----大小= 100 Mb ------索引= 3
----对象5 -----大小= 100 Mb ------ index = 4
----对象6 -----大小= 100 Mb ------索引= 5
< / FileStream>

序列化对象也成功了,现在我遇到了反序列化对象的问题。这是
的问题:列表中的
我们可以带索引的物品。因此,如果我们想获取第五个索引,可以这样称呼它:

  List< object> list = new List< object>(); 
list(0)= object1;
list(1)= object2;
list(2)= object3;
list(3)= object4;
list(4)= object5;
list(5)= object6;
object thirdIndex = list [5]; //在这里我们可以获取基于项目的索引

现在问题是如何获取第五个对象就像 List方法 一样,使用Binary Formatter对文件流中的六个反序列化对象进行索引。我知道FileStream中有一个名为 FileStream.Position的属性,但它不喜欢Index,当我对对象进行反序列化/序列化时,它看起来像一个随机数。也许它会增加随机数。



实际上我已经成功了,但是我敢打赌这不是看我尝试过的代码的最佳方式: p>

  object GetObjectStream(FileStream fs,int index)
{
if(fs!= null)
{
BinaryFormatter binaryformatter = new BinaryFormatter();
bool isFinished = false; int count = 0;
while(isFinished == false)
{
try
{
object objectdeserialized = binaryformatter.Deserialize(fs);
if(count == index)返回反序列化的对象;
count ++;
}
catch
{
isFinished = true;
返回null;
}
}
}
返回null;
}

这些代码将 foreach 已序列化的每个对象,然后反序列化每个对象。我敢打赌我的代码不是最好的方法,因为要对包含100 MB的对象进行反序列化可能会花费很长时间,我什至不知道除已反序列化的索引之外的对象是否会被处理?我想要的方法就像序列化跨越。



如果我们能解决这个问题,您的答案对我非常有用和有用。 / p>

谢谢。.

解决方案

每个对象最有可能需要一个序列化的空间量不同-数据包的存储方式不同,尤其是对于字符串和数组之类的数据。基本上,要高效地执行此操作(即不每次都完整读取每个对象),您可能需要:




    通过将对象序列化为 MemoryStream 并存储 .Length 为每个对象添加所需的数据量前缀>(任何方便的方式;一个4字节的little-endian块就足够了),然后将您写入 MemoryStream 的数据复制到输出中;那么您可以按n倍的次数跳到第n个项((将4字节作为一个整数读取,跳过那么多字节)
  • 在单独的索引中,存储<$ c $序列化每个对象之前的基本流的c> .Position ;然后要读取第n个对象,可以使用索引找到所需的位置,然后滚动到该位置。



实际上,幸运的是: BinaryFormatter 实际上没有被记录为可以安全附加,但是碰巧它确实可以,您可以这样做-



不过,就我个人而言,我想问是否这里可以简单地使用其他设计。

>

I want to ask about serialize/deserialize object with binary formatter. well i'm trying to deserialize object in FileStream that contain many objects that has been serialized one by one. The size of an object is too big to be saved in process memmory that's why i don't pack all of objects in one such as: List because they are too big in process memory So i serialize as much as needed in many times. with this way it won't take many process memmory because i just process one object alternately not all of objects. take a look at sketch that i mean

<FileStream>
----Object 1-----Size = 100 Mb------index = 0
----Object 2-----Size = 100 Mb------index = 1
----Object 3-----Size = 100 Mb------index = 2
----Object 4-----Size = 100 Mb------index = 3
----Object 5-----Size = 100 Mb------index = 4
----Object 6-----Size = 100 Mb------index = 5
</FileStream>

Serialization object is also successfully now i got a problem to deserialized an object. here is the problem: in List we can take an item with index. so if we like to take fifth index we can call it such as:

    List<object> list = new List<object>();
    list(0) = "object1";
    list(1) = "object2";
    list(2) = "object3";
    list(3) = "object4";
    list(4) = "object5";
    list(5) = "object6";
    object fifthIndex = list[5]; // here we can get item based index

Well now the problem is how can i get objects with fifth index just like List Method on six Deserialization object in a filestream with Binary Formatter. i know in FileStream there is a property that named "FileStream.Position" but it does not like Index, it looks like a random number when i have deserialize/serialize an object. maybe it will increase random number.

actually i have succeeded with this but i bet this is not best way take a look at my code that i have ever tried:

object GetObjectStream(FileStream fs, int index)
{
    if (fs != null)
    {
        BinaryFormatter binaryformatter = new BinaryFormatter();
        bool isFinished = false; int count = 0;
        while (isFinished == false)
        {
            try
            {
                object objectdeserialized = binaryformatter.Deserialize(fs);
                if (count == index) return objectdeserialized;
                count++;
            }
            catch
            {
                isFinished = true;
                return null;
            }
        }
    }
    return null;
}

these codes will "foreach" every object that has been serialized and then deserialize every objects. i bet my codes are not the best way because to Deserialize object that contain 100 MB maybe it will take long time, I don't even know the object except index that ever be deserialized will be disposed or not? i want method just like a "Serialization Leap."

your answer is very helpfull and usefull for me if we can solve this problem.

Thanks before..

解决方案

Each object will most likely take a different amount of space to serialize - data packs differently, especially for things like strings and arrays. Basically, to do this efficiently (i.e. without reading every object in full each time), you would want to either:

  • prefix each object with the amount of data it takes, by serializing it to a MemoryStream, storing the .Length (any way that is convenient to you; a 4 byte little-endian chunk would suffice), and then copy the data you wrote to MemoryStream to the output; then you can skip to the n'th item by n-times-(read 4 bytes as an int, skipping that many bytes)
  • in a separate index, store the .Position of the base stream just before you serialize each object; then to read the nth object, you use the index to find the position you need, and scroll to there

Actually, you were quite lucky here: BinaryFormatter isn't actually documented as being safe to append, but as it happens it does kinda work out ok it you do that - but this isn't true for all serialization formats.

Personally, though, I'd question whether there is simply a different design that could be used here.

这篇关于二进制格式化程序,设置位置以反序列化特定对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆