2015-07-02 11 views
6

Sto provando a effettuare la transizione da C a C# e ho alcune domande sul salvataggio di oggetti su file e serializzazione.Salvataggio oggetti/serializzazione

In C se si desidera salvare una struttura dati, mi è stato insegnato che salvarlo in un formato di testo come una stringa è spesso inutile e un file binario che esiste come un'istantanea della memoria è spesso meglio perché non lo fa t bisogno di codificare/decodificare e abbinare le stringhe ai campi. In C# l'approccio sembra essere diverso, converte i campi oggetto separatamente in una stringa o in un altro formato e quindi ricostruisce l'oggetto quando necessario. Non sono sicuro di come funzioni la serializzazione binaria, ma ritengo che converta i dati in un formato e non esista come un'istantanea di memoria pura non formattata.

Perché il metodo "snapshot della memoria" senza codifica/decodifica non è utilizzato in C#? L'unica ragione per cui posso pensare è la compatibilità con altri codici e ambienti, e forse ha a che fare con la complessità degli oggetti rispetto alle strutture regolari.

+0

Cosa succede se l'oggetto ha proprietà complesse, non solo tipi di valore; quindi ogni "parte" dell'oggetto verrà memorizzata su una diversa posizione di memoria; anche questi oggetti possono includere altri oggetti. Solo una semplice ipotesi, ma sarebbe davvero complesso eseguire una tale logica per salvare oggetti. – daryal

+0

Una delle grandi riduzioni di costi e benefici per la produttività è l'astrazione della memoria di .NET e l'hardware in generale. Se hai bisogno di persistere con i requisiti di base, lascia che il framework gestisca il lavoro pesante (come spesso accade) e segna la classe con [Serializable] e usa le classi disponibili in System.Runtime.Serialization.Formatters.Binary. – Michael

risposta

2

In C# non è possibile accedere al layout di memoria di un oggetto. Non è possibile ottenere l'istantanea di memoria di un oggetto o creare un oggetto dall'istantanea. In effetti, non hai nemmeno punti (sì, li hai in codice non sicuro, ma raramente scrivi codice non sicuro).

Anche se si ha accesso alla memoria utilizzata dall'oggetto, potrebbe non sopravvivere per essere salvato su disco e quindi ricaricato. Se si aggiorna l'ambiente .NET, è possibile ottenere un ottimizzatore migliore che decide di riordinare i campi dell'oggetto in modo diverso o utilizzare un diverso allineamento della memoria.

Quindi, in breve, nessun accesso alla memoria oggetto, quindi è necessario serializzare campo per campo.

Il lato positivo è che, poiché .NET ha la riflessione, la serializzazione di un oggetto in questo modo non è difficile. In effetti, è molto più semplice della serializzazione di una classe C++ che contiene puntatori ad altre classi C++.

+0

Quindi a causa del.NET framework fa così tanto sulla gestione della memoria, non hai accesso diretto alla memoria e anche se lo facessi sarebbe pericoloso. Questo ha molto senso, grazie! :) – user3604097

1

Il formato di serializzazione binario .NET definisce i tipi in cui vorrebbero essere memorizzati e inserisce alcuni metadati in modo da sapere come decodificarlo (quale tipo, quale nome di campo, ecc.).

Questo non è principalmente per l'interoperabilità con i linguaggi .NET, anche se potrebbe esserlo. È per l'interoperabilità con versioni passate e future degli stessi oggetti, che possono essere scritte in un modo per essere resilienti a quei cambiamenti - o almeno sapere di rifiutarli.

In C, se si modifica una struttura in alcun modo - e si è appena utilizzato write() per archiviare la memoria, si potrebbe anche scegliere di scrivere alcuni metadati in modo da poter sapere se si dispone della versione corretta (e necessario per convertire).

Un altro vantaggio è che i linguaggi .NET sanno cosa fare con i riferimenti. Per impostazione predefinita, C sarebbe write() un indirizzo, che sarebbe inutile in seguito. .NET supporta anche l'idea di campi che non dovrebbero essere serializzati (come una password) - un'altra cosa che avresti bisogno di scrivere a mano nella versione C.