Laden...

Sequenzielles Deserialisieren

Erstellt von gelöschtem Konto vor 14 Jahren Letzter Beitrag vor 14 Jahren 1.103 Views
Gelöschter Account
vor 14 Jahren
Sequenzielles Deserialisieren

Hallo Freunde der Programmierung,

ich habe mal ein Frage. Ich habe export Dateien die ich brauche um bestimmt Inhalte zu sichern. Dabei werden sehr umfangreiche Datenmengen exportiert. Die Daten befinden sich in Komprimierten Dateien und sind so auf der Platte ungefäht 6MB groß. Wenn ich diese nun deserialisieren entsteht dabei 1,2GB!!! an RAM. Da er ja das gesammte Object im Speicher wieder zusammen setzt. Meine Frage lautet nun also: Gibt es ein möglichkeite sequenzie. zu serialiesieren? Das heißt ich möchte nach und nach die Daten haben und verarbeiten. Oder ist das mit serialisier schlicht nicht möglich und ich muss das ganz mit hilfe von Xml z.b. machen. Oder habt ihr gar noch bessere Anregungen? 😃

Vielen Dank im Vorraus

Steffen

4.506 Beiträge seit 2004
vor 14 Jahren

Hallo gordon2001,

der herkömmliche (De)Serialisierungsprozess für Objekte ist bestimmt nicht 100%ig optimal (nicht falsch verstehen, er ist sehr zu empfehlen, ich vermute aber, dass man hier bei 98% Performanceoptimal liegt und dass nur minimal Verbesserungen möglich sind), aber dass eine 6 MB Datei zum Deserialisieren plötzlich 1,2 GB Speicher benötigt, da muss definitiv etwas ganz schräg laufen.

Ich vermute aber auch sehr stark, dass das nicht am Deserialisierungsprozess aus dem Framework heraus passiert, sondern, dass eventuell die Deserialisierung falsch verwendet bzw. etwas anderes dafür verantwortlich sein muss.

Kannst Du genauer Beschreiben wie Du (De)Serialisierst?

Grüße
Norman-Timo

A: “Wie ist denn das Wetter bei euch?”
B: “Caps Lock.”
A: “Hä?”
B: “Na ja, Shift ohne Ende!”

Gelöschter Account
vor 14 Jahren

Nene das serialiesieren kalppt wunderbar...
aber hier gerne nochmal der code:



FileInfo file = new FileInfo(path);
                FileStream stream = file.Open(FileMode.Open);

                MemoryStream mStream = new MemoryStream();

                

                using (var gzip = new GZipStream(stream, CompressionMode.Decompress))
                {
                    const int bufferSize = 4096;
                    byte[] buffer = new byte[bufferSize];
                    while (true)
                    {
                        int read = gzip.Read(buffer, 0, buffer.Length);
                        if (read == 0)
                            break;
                        mStream.Write(buffer, 0, read);
                    }
                    mStream.Flush();
                }

                mStream.Seek(0, SeekOrigin.Begin);

                BinaryFormatter formatter = new BinaryFormatter();
                ProjectFile project = (ProjectFile)formatter.Deserialize(mStream);

das Problem ist das die Klasse die deseriealisiert wird undgefähr 200.000 Datenobjekte enthält. Die sind Komprimiert auf der Platte relative klein aber im Speicehr echt riesig. Habe auch schon tests mit structs und klasse im vergleich gemacht. Wobei structs zunehmen hier nur minimale Vorteile bringt...

Gelöschter Account
vor 14 Jahren

Ich kann die Datei auch gerne mal hier anhängen und du probierst es selber auch mit meinem code snipsel ^^

T
433 Beiträge seit 2006
vor 14 Jahren

Hallo,

Versteh ich das richtig das das ProjectFile am Ende 1.2 GB gross ist?
Wieso verwendest du keine DB für deine '200.00 Datenobjekte'?

Gruß,
Tom

Gelöschter Account
vor 14 Jahren

hallo, mach ich auch in der business Logik. Aber ich muss die Projekte irgendwie als export Dateien haben damit ich sie z.b auf anderen Rechnern wieder importieren kann. Ich brauche also ein ganzes Projekt als herumreichbare export Datei. Und das ganze aus der Anwender GUI herraus, ich aknn den Kunden nicht sagt "ja dann müsst ihr SQL management tool öffnen -> rechts klick -> export.. usw." Auserdem hängt noch mehr an einem Projekt als nur die 200.000 Datenobjekte, z.b. bestimmte Einstellungen usw. die nicht in einer DB gehalten werden.

T
433 Beiträge seit 2006
vor 14 Jahren

Du solltest aber schon Daten und Anwendung trennen.
Ich würde nur Settings in eine Xml Datei schreiben ((de)serialisieren) und deine Daten in einer dateibasierten DB speichern, oder du erstellst z.B. ein DB Export in deiner Anwendung.

Die ganzen Dateien kannst du dann auch komprimiert als eine Datei rausgeben.

Gelöschter Account
vor 14 Jahren

Jaja Daten und Anwedung sind strinkt getrennt.

DB <- PowerShell Commandlets <- Business Logik (Objects) <- GUI

also das ist sehr strinkt. Es geht hier um Projekt bezogene Eingenschaften (settings war das falsche Wort). Hm naja ich hab gehofft das ohne DB-Datei hinzubekommen in den ich die Business Logik exportiere.

T
433 Beiträge seit 2006
vor 14 Jahren

Das mit der Trennung meinte ich auf Datenebene.
Ich würde halt nicht versuchen alles in einem 'grossen Super Duper Objekt' zu erschlagen.
Dann wirst du auch nicht auf solche Probleme stossen und bist für die Zukunft flexibler.

Gruß,
Tom

4.506 Beiträge seit 2004
vor 14 Jahren

Hallo gordon2001,

hatte Dir ne PM geschickt und Dir Hilfe angeboten !?

Aber unabhängig davon lässt sich Dein Code stark optimieren. Das Arbeiten mit Streams bedeutet eben nicht, dass man bei jedem Verarbeitungsschritt den Stream komplett verarbeiten muss. Im Gegenteil, man übergibt einfach jeder Verarbeitungskette den Stream, und sobald einer daran zieht durchläuft dieser alle Kettenglieder.

Ein Besipiel hierfür (Dateistream <-> GZipStream <-> (De)Serialisierungsstream):


using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.Serialization.Formatters.Binary;
using System.IO;
using System.IO.Compression;

namespace StreamTest
{
    public class Program
    {
        #region main entry point

        static void Main(string[] args)
        {
            TestDataClass deserializedObject = null;
            Program myApp = new Program();
            
            myApp.CreateZipFileFromObject(new TestDataClass(), "TestData.zip");
            deserializedObject = (TestDataClass)myApp.GetObjectFromZipFile("TestData.zip");
            
            Console.WriteLine(String.Format("Testwerte: {0} | {1}", deserializedObject.IntVal, deserializedObject.StrVal));
            Console.WriteLine("Tastendruck beendet das Programm!");
            Console.ReadKey();
        }

        #endregion

        #region Public methods

        /// <summary>
        /// Method which takes an object to serialize it. Than the method will generate
        /// and zip file from the serialization stream.
        /// </summary>
        /// <param name="p_Data">Object to serialize and zip.</param>
        /// <param name="p_zipName">Filename for the zip file.</param>
        public void CreateZipFileFromObject(object p_Data, string p_zipName)
        {
            using (FileStream fs = new FileStream(p_zipName, FileMode.Create))
            {
                using (GZipStream zipStream = new GZipStream(fs, CompressionMode.Compress))
                {
                    BinaryFormatter binFormatter = new BinaryFormatter();
                    binFormatter.Serialize(zipStream, p_Data);
                }
            }
        }

        /// <summary>
        /// Method which takes the zip filename which is used to decompress and deserialize.
        /// </summary>
        /// <param name="p_zipName">Filename for the zip file.</param>
        /// <returns>Deserialized object.</returns>
        public object GetObjectFromZipFile(string p_zipName)
        {
            object retValue = null;

            using (FileStream fs = new FileStream(p_zipName, FileMode.Open))
            {
                using (GZipStream zipStream = new GZipStream(fs, CompressionMode.Decompress))
                {
                    BinaryFormatter binFormatter = new BinaryFormatter();
                    retValue = binFormatter.Deserialize(zipStream);
                }
            }

            return retValue;
        }

        #endregion

    }
}


Das optimiert in Deinem Falle schon einiges. Verhält sich danach der Speicher besser?

Grüße
Norman-Timo

A: “Wie ist denn das Wetter bei euch?”
B: “Caps Lock.”
A: “Hä?”
B: “Na ja, Shift ohne Ende!”

Gelöschter Account
vor 14 Jahren

oh sorry war ne weile nicht online dadurch hab ich deine PM nicht gesehen.

ja das halbiert das speicheraufkommen schon einmal da ich den stream nicht doppelt halte. sehr guter tip 😃