C# - RAM-Speicher als String wiedergeben

Palladin007

assimiliert
Moin


Ich hatte vorhin den Gedanken, dass jeder PC Speicherdaten in einem bestimmten Zeichencode abspeichern muss.
Logischerweise muss das dann auch im Arbeitsspeicher so laifen, nur dass die Daten dort nicht dauerhaft gespeichert sind.
(Korrektur wenn ich falsch liege)

Gibt es dann eine Möglichkeit, etwas in den Arbeitsspeicher zu laden und die Daten von dort, so wie sie sind, abzurufen und als string in eine Datei zu schreiben?

Ich finde die Vorstellung praktisch, da man auf diese Weise ein ganzes Feld, das ja auch mehrere Ebenen und auch sehr viele Elemente enthalten kann, auf diese Weise viel einfacher speichern lassen kann.

Wenn der Nutzer von einem Programm dann also z.B. Personen-Daten einträgt, dann werden die in einem Feld gespeichert und müssten eigentlich irgendwo im Arbeitsspeicher hinterlegt sein, oder?
Um das zu speichern müsste man dann nur noch diesen Code als string abrufen und in eine Datei schreiben, zum laden wird dieser Code aus der Datei gelesen und in den Arbeitsspeicher geladen.
Das würde umständliche Speicher-Methoden unnötig machen.


Geht das, oder gibt es andere Methoden, die ein Feld (oder ähnliches) als ein String-Code ausgibt und ebenso aus dem Code wieder ein Feld machen kann?
 
AW: C# - RAM-Speicher als string wiedergeben

Basic: peek und poke. :ROFLMAO: (Nur ein Spaß)

Hast du dich denn inzwischen schon mal mit Pointern (Zeigervariablen) beschäftigt?
Mit deren Hilfe kannst du Speicherbereiche auch absolut adressieren, soweit es die Speicherverwaltung des Betriebssystems auch zulässt und die Adressen nicht umbiegt. So könntest du Bereiche ohne Rücksicht auf Datentypen auslesen und mittels Typecasting in eine Stringvariable schreiben.
Umgekehrt geht das aber nicht und ein absolutes Schreiben von Speicherbereichen lässt der Protected-Mode nicht zu. Das läuft immer über die Speicherverwaltung.
 
AW: C# - RAM-Speicher als string wiedergeben

Ich finde es einfach nur umständlich, wenn man große Felder mit jedem Element einzeln in eine Datei schreiben muss.

Kennst du nicht eine schnellere Methode?

Deswegen hatte ich die Idee mit dem Arbeitsspeicher, aber ein anderer Weg geht auch.


Ich will nur ein Feld, möglichst einfach, in eine Datei schreiben können und dafür nicht jedes Element einzeln aufrufen und von den anderen trennen müssen.
Das Speichern ist da an sich nicht weiter schwer, aber das richtig auslesen ist dann wieder nervig.
 
AW: C# - RAM-Speicher als string wiedergeben

Mit der Hochsprache C und ihren Ablegern kenne ich mich ja nun leider nur sehr wenig aus.

In Pascal/Delphi dagegen sind mir für solche Operationen schon lange die beiden Kommandos BlockRead und BlockWrite bekannt, welche ich auch immer häufig und gern genutzt habe, da sie die Sache nicht nur vereinfachen, sondern auch sehr schnell sind. Ein weiterer Vorteil dieser Befehle ist, dass der Typ der zu lesenden und schreibenden Daten vollkommen egal ist.

Allerdings sind diese beiden Befehle für Dateien gedacht, was somit ein kleiner Umweg über temporäre Dateien wäre. Ein anderer Weg kann in Delphi unter Verwendung der Funktionen New oder GetMem und ihren artverwandten Funktionen beschritten werden. Daher auch meine Frage eingangs, ob du dich mit Pointern schon auskennst. Diese Materie ist recht umfangreich und greift tief ins System ein. Beherrscht man aber erstmal den Umgang mit Zeigervariablen, werden solche Sachen wie du sie vorhast ungeheuer einfach.

Diese Möglichkeiten sind in so einer umfangreichen Sprache wie C mit 100%iger Sicherheit ebenfalls vorhanden, da musst du mal schauen, wie dort die Befehle dafür lauten.
 
Zuletzt bearbeitet:
AW: C# - RAM-Speicher als string wiedergeben

Hallo,

das Stichwort das Du suchst, lautet Serialization. Damit kannst du in .NET komplette Instanzen von Klassen z.B. als Datei. Datensatz, etc. speichern.

Weiterhin, wenn es nur um einfache Felder geht, kannst du über einen memory/file-Stream gehen und damit komplette Arrays (Felder) auf einmal speichern.

Bsp:
byte []aByte = new byte[1024];
I=0;
FileStream FileStream = System.IO.File.OpenRead(CKAMS.HttpPath + p.http_url);
while(FileStream.Read(aByte,0,1024)>0)
{
p.OutputStream.BaseStream.Write(aByte,0,1024);
I+=1024;
}
FileStream.Close();
 
AW: C# - RAM-Speicher als string wiedergeben

@ElSer:


Viielen Danke^^
as klingt exakt so, wie ich es mir vorgestellt habe^^
Jetzt muss ich es nur noch ausprobieren und verstehen, dann bin ich glücklich^^
 
AW: C# - RAM-Speicher als string wiedergeben

Das, was ich suche und was du wahrscheinlich auch meinst, verstehe ich irgendwie nicht^^
Aber das hätte ich auch nur benutzt, um Daten zu verschlüsseln, bevor ich sie speichere.
Mit einer XML-Datei kann ich Daten ja viel einfacher Speichern, aber dann werden sie nicht verschlüsselt.
Aber das ist erst m

Diese Methode habe ich auf der Microsoft-Website gefunden:

Code:
        public void ReadXML()
        {
            System.Xml.Serialization.XmlSerializer reader =
                new System.Xml.Serialization.XmlSerializer(typeof(Book));
            System.IO.StreamReader file = new System.IO.StreamReader(
                @"c:\temp\SerializationOverview.xml");
            Book overview = new Book();
            overview = (Book)reader.Deserialize(file);

            Console.WriteLine(overview.title);

        }

Ich wollte mir das nun als eine generische Methode umschreiben, aber das funktioniert nicht, weil von einem generischen Typ keine Instanz erstellt werden kann. Hast du, oder jemand anderes eine Idee, wie ich das trotzdem machen kann, dass egal ist, welche Klasse ich übergebe?

Edit:
Bei der Methode, die die Datei schreibt, funktioniert das Problemlos.




Edit²:

Ich habe jetzt doch eine Lösung gefunden. Die war einfach zu einfach, dass sie mir nicht gleich auf gefallen ist^^

Code:
        public static void WriteXML<T>(T overview, string Pfad)
        {
            XmlSerializer writer = new XmlSerializer(typeof(T));
            StreamWriter file = new StreamWriter(Pfad);
            writer.Serialize(file, overview);
            file.Close();
        }

        public static T ReadXML<T>(string Pfad)
        {
            XmlSerializer reader = new XmlSerializer(typeof(T));
            StreamReader file = new StreamReader(Pfad);
            object result = reader.Deserialize(file);
            file.Close();
            return (T)result;
        }

Schreibt und Liest XML-Dateien, unabhängig vom der Klasse^^
 
Zuletzt bearbeitet:
AW: C# - RAM-Speicher als string wiedergeben

Um das Thema mal abzuschließen:


Ich habe jetzt in einem anderen Forum mal nach gefragt und dort hab ich den Tipp erhalten, das ganze doch mit Hilfe einer XML-Datei zu machen, nur wird die nicht geschrieben, sondern als MemoryStream gespeichert.
Mit diesem Lösungsweg kann man jeden Datentyp verwenden und eben auch Arrays, da das ganze über einen XML-Stream arbeitet. Mit Listen habe ich es aber nicht getestet, da ich keine Listen benutze.
Das ganze habe ich dann weiter verfolgt und nun habe ich zwei funktionierende Methoden:


PHP:
        public static string ArrayInStringCode<Type>(Type Array)
        {
            System.IO.MemoryStream newMemoryStream = new System.IO.MemoryStream();
            System.Xml.Serialization.XmlSerializer xmlWriter = new System.Xml.Serialization.XmlSerializer(typeof(Type));

            xmlWriter.Serialize(newMemoryStream, Array);

            System.IO.StreamReader newStreamReader = new System.IO.StreamReader(newMemoryStream);
            newStreamReader.BaseStream.Position = 0;
            string result = newStreamReader.ReadToEnd();

            newMemoryStream.Close();
            newStreamReader.Close();

            return result;
        }

        public static Type ArrayCodeInArray<Type>(string Code)
        {
            System.IO.MemoryStream newMemoryStream = new System.IO.MemoryStream(System.Text.ASCIIEncoding.Default.GetBytes(Code));

            System.IO.StreamReader newStreamReader = new System.IO.StreamReader(newMemoryStream);

            System.Xml.Serialization.XmlSerializer xmlReader = new System.Xml.Serialization.XmlSerializer(typeof(Type));
            object result = xmlReader.Deserialize(newMemoryStream);

            newMemoryStream.Close();
            newStreamReader.Close();

            return (Type)result;
        }


Weitere using-Direktiven sind nicht nötig, da ich alle nötigen Direktiven schon in den Methoden eingefügt habe.



Hier mal ein Beispiel:

PHP:
namespace ArrayAlsString
{
    class Program
    {
        static void Main(string[] args)
        {
                // Das Feld wird erstellt
            Person[] PersonenListe = 
            {
                new Person("Hans", 13),
                new Person("Peter", 15)
                                     
            };

                // Die Methode wird aufgerufen, um das Feld in einen Byte-Code zu schreiben
                // In den spitzen Klammern muss der Typ übergeben werden. (Bei einem Feld muss auch das als Typ angegeben werden)
            string ArrayCode = ArrayInStringCode<Person[]>(PersonenListe);

            /*
             * Nun kann der Byte-Code z.B. versendet werden
             */

                // Die Methode wird aufgerufen, um aus dem Byte-Code wieder ein Feld zu erstellen
                // In den spitzen Klammern muss der Rückgabetyp übergeben werden. (Bei einem Feld muss auch das als Typ angegeben
                // werden)
            Person[] PersonenListe2 = ArrayCodeInArray<Person[]>(ArrayCode);

                // Die folgenden Zeilen sind zum testen gedacht
            foreach (var item in PersonenListe2)
            {
                System.Console.Write("Name: " + item.Name + ", Alter: " + item.Alter);
                System.Console.WriteLine();
            }
                // Pausiert das Program, damit das Ergebnis nicht sofort wieder ausgeblendet wird
            System.Console.Read();
        }

        public static string ArrayInStringCode<Type>(Type Array)
        {
                // Eine neue Instanz der Klasse MemoryStream wird erstellt
            System.IO.MemoryStream newMemoryStream = new System.IO.MemoryStream();
                // Eine neue Instanz der Klasse XmlSerializer wird erstellt und dabei wird der angegebene Typ verwendet
            System.Xml.Serialization.XmlSerializer xmlWriter = new System.Xml.Serialization.XmlSerializer(typeof(Type));

                // Das Feld wird in den MemoryStream geschrieben
            xmlWriter.Serialize(newMemoryStream, Array);


                // Eine neue Instanz der Klasse StreamReader wird erstellt,
                // damit der Stream gelesen und als String zurück gegeben werden kann
            System.IO.StreamReader newStreamReader = new System.IO.StreamReader(newMemoryStream);
                // Der StreamReader wird an den Anfang des Streams gesetzt, da er sonst am Ende steht
            newStreamReader.BaseStream.Position = 0;
                // Der Stream wird nun als String-Variable gespeichert
            string result = newStreamReader.ReadToEnd();

                // Alle Instanzen der Stream-Klassen werden geschlossen
            newMemoryStream.Close();
            newStreamReader.Close();

                // Rückgabe
            return result;
        }

        public static Type ArrayCodeInArray<Type>(string Code)
        {
                // Es wird eine neue Instanz der Klasse MemoryStream erstellt
                // und gleichzeitig der Code in ein Byte-Array umgewandelt und der Instanz übergeben
            System.IO.MemoryStream newMemoryStream = new System.IO.MemoryStream(System.Text.ASCIIEncoding.Default.GetBytes(Code));

                // Es wird eine neue Instanz der Klasse StreamReader erstellt und der MemoryStream wird übergeben
            System.IO.StreamReader newStreamReader = new System.IO.StreamReader(newMemoryStream);

                // Eine neue Instanz der Klasse XmlSerializer wird erstellt und dabei wird der angegebene Typ verwendet
            System.Xml.Serialization.XmlSerializer xmlReader = new System.Xml.Serialization.XmlSerializer(typeof(Type));
                // Der Stream wird in der XmlSerializer-Instanz deserialisiert und als Objekt-Variable gespeichert
            object result = xmlReader.Deserialize(newMemoryStream);

                // Alle Instanzen der Stream-Klassen werden geschlossen
            newMemoryStream.Close();
            newStreamReader.Close();

                // Rückgabe
            return (Type)result;
        }
    }

        // Erkläre ich nicht weiter, da das sowieso nur ein Beispiel ist. Die Methoden sollten mit allen Klassen und Datentypen funktionieren
    public class Person
    {
        public string Name = null;
        public int Alter=0;

        public Person()
        { }
        public Person(string newName, int newAlter)
        {
            Name = newName;
            Alter = newAlter;
        }
    }
}




PS: Für schönere Methoden-Namen wäre ich sehr dankbar^^




Edit:
Man kann das ganze dann nun auch als Byte-Array zrück geben lassen, was vielleicht auch effektiver ist, da die Methoden dann beide kleiner sind, allerdings kann man das dann nicht mehr als einfacher Text verschlüsseln und ich weiß nicht, ob wie man Daten über das Internet versendet. Und Geschwindigkeitsunterschiede würde man wahrscheinlich erst bei gigantisch großen Feldern bemerken^^
Ich finde es als String einfach einfacher und außerdem war so das Thema.
 
Zuletzt bearbeitet:
AW: C# - RAM-Speicher als string wiedergeben

Hoppla, einen ganzen Monat zu spät gesehen.

PS: Für schönere Methoden-Namen wäre ich sehr dankbar

Ich mag bei so was auch immer möglichst kurze und aussagekräftige Namen, für deine beiden Methoden z.B. etwa so:


Array2String
String2Array


oder ausgeschrieben:


ArrayToString
StringToArray


Da Programmiersprachen zumeist in Englisch sind, bevorzuge ich idR auch für die eigenen Funktionen/Methoden etc. englische Bezeichnungen.
 
AW: C# - RAM-Speicher als string wiedergeben

Das Thema ist zwar uralt, aber vor einer Weile habe ich mal eine weit bessere Möglichkeit gefunden, das Problem zu lösen.
Es geht auch um die Serialisierung, allerdings die binäre (oder auch einfache) Serialisierung.

Sie ist sehr effektiv und es werden alle Membervariablen serialisiert, auch wenn sie als private markiert wurde. Allerdings wird kein Konstruktor aufgerufen, was gewisse Nachteile mit sich bringen kann. Zusätzlich gibt es auch noch weitere Nachteile, wie z.B. das Wegfallen hoher Unicode-Ersatzzeichen.


Aber alles in allem ist es eine sehr praktische Möglichkeit, z.B. Einstellungen oder Speicher-Daten effektiv zu speichern, wenn man keine Datenbank nutzen will.


Gruß
 
Oben