2011-01-19 9 views
9

Tengo una variedad de estructuras de datos ricas (principalmente árboles) que me gustaría conservar en el disco, lo que significa que no solo quiero escribirlas en el disco, sino que quiero una garantía de que los datos se han escrito completamente y sobrevivirán a un poder -abajo.¿Cómo se persisten los datos en el disco desde .NET?

Otros parecen diseñar formas de codificar estructuras de datos ricas en tablas de bases de datos planas como tablas de búsqueda de nodos primarios a secundarios. Esto facilita la ejecución de consultas SQL con los datos, pero no lo necesito: solo quiero guardar y cargar mis árboles.

La solución obvia es almacenar todo como un blob en la base de datos: una sola entrada que quizás contenga una cadena larga. ¿Es eso un abuso de la base de datos o una práctica recomendada? Otra solución podría ser usar una base de datos XML? ¿Hay alguna alternativa a las bases de datos que debería considerar?

Por último, estoy haciendo esto desde F # por lo que una solución llave en mano para los datos de la persistencia de .NET sería ideal ...

EDIT: Tenga en cuenta que al formatear (por ejemplo, la serialización) es irrelevante como pueda Convertir trivialmente entre formatos con F #. Se trata de obtener un reconocimiento de que se ha completado una escritura hasta el almacén no volátil (es decir, el disco) y que ninguna parte de los datos escritos se mantiene en un almacén volátil (por ejemplo, un caché de RAM) para que Puedo continuar a salvo en ese conocimiento (por ejemplo, eliminando la versión anterior de los datos del disco).

+1

Re "solución llave en mano" - algunas (no todas) construcciones F # pueden estar fuera de la ventana * típica * que muchas capas de persistencia esperan ¿Sería aceptable usar una capa de clase DTO (justo antes de la serialización) si simplifica las cosas? Además, sospecho que es posible que desee ver los aspectos de * serialización * y * ACID * por separado. –

+1

Si (mirando su comentario a Reed) el aspecto de serialización no es un problema, entonces tal vez cualquier base de datos * de ACID *. –

+0

@Marc: "Base de datos de documentos ACID". Fantástico, gracias! –

Respuesta

9

Algunos de los constructores para la clase FileStream de .NET toman un parámetro del tipo FileOptions. Uno de los valores para FileOptions es WriteThrough, que "Indica que el sistema debe escribir a través de cualquier caché intermedio e ir directamente al disco".

Esto debería garantizar que, cuando regrese su operación de escritura (a un archivo nuevo), los datos se confirmen en el disco y pueda eliminar de manera segura el archivo anterior.

+0

Perfecto, gracias! –

+2

Gracias por la respuesta. Nunca fui consciente de la existencia de esas opciones de archivo: WriteThrough, Asynchronous, RandomAccess, DeleteOnClose, SequentialScan y Encrypted. Mirar cada uno de ellos puede merecer una buena publicación en el blog. – Cygwin98

7

Esto puede hacerse a través de Serialization.

.NET Framework incluye muchas opciones incorporadas para serializar sus datos en el disco, incluido el uso de formatos binarios o basados ​​en XML. Los detalles How-To articles se proporcionan en la Documentación de MSDN.

+0

XMLSerializer no funcionará con varios tipos de F #, especialmente registros y uniones discriminadas, ya que estos no tienen constructores de instancias sin parámetros predeterminados. Esto es desafortunado, ya que las uniones discriminadas proporcionan una excelente manera de modelar árboles. La serialización binaria es el enfoque más directo – pblasucci

+0

@pblasucci: cierto: la serialización binaria (o un serializador personalizado) puede ser necesaria si está usando F # –

+0

@Reed: ¿Cómo es relevante esta respuesta sobre el formato a mi pregunta sobre la garantía de persistencia? –

0

Pruebe usar XMLSerializer (System.Xml.Serialization).

http://msdn.microsoft.com/en-us/library/system.xml.serialization.xmlserializer.aspx

puede persistir de forma automática estructuras complejas de datos en base a sus propiedades, y se puede utilizar atributos para controlar la salida, si lo desea:

http://msdn.microsoft.com/en-us/library/83y7df3e.aspx

+0

XMLSerializer no funcionará con varios tipos de F #, en particular registros y uniones discriminadas, ya que estos no tienen constructores de instancias sin parámetros predeterminados. Esto es desafortunado, ya que las uniones discriminadas proporcionan una excelente manera de modelar árboles. La serialización binaria es el enfoque más directo. – pblasucci

+0

@C. Lawrence Wenham: ¿Cómo es esta respuesta sobre el formato relevante para mi pregunta sobre la persistencia garantizada en el disco? Ni el serializador XML ni ningún otro serializador hacen tales garantías, AFAIK. –

+0

Nada garantiza que se escriba en el disco, luego deberá verificar que no haya excepciones, que el archivo exista y que no tenga cero bytes. Sin embargo, puede implementar System.Transactions.IEnlistmentNotification en una clase personalizada que alistará su escritura en una transacción distribuible, lo que le ofrece un recurso para deshacer otras operaciones si la escritura falla –

3

Con el fin de hacer esto, necesitará un recurso que le permita participar en un Transaction (la mayoría de las veces, usaría un TransactionScope.

La mayoría de las bases de datos participará en un Transaction si uno está contenido. Las operaciones de disco también pueden ser administradas por un Transaction, pero tendrías que hacer un poco de specific work in order to utilize it in .NET.

Además, tenga en cuenta que esto solo está disponible en Windows Vista y posterior.

Si va por la ruta de la base de datos, puede almacenar el contenido serializado de sus árboles en un blob (o texto, según el mecanismo de serialización).

nota, también puede utilizar la funcionalidad FILESTREAM en SQL Server (2008 y hasta, creo) para almacenar sus archivos en el sistema de archivos y obtener los beneficios de transacciones en SQL Server.

1

No he usado db4o de F # antes, pero se trata de persistir gráficos de objetos CLR en el disco de forma transaccional. Si funciona con registros y sindicatos discriminados, podría ser adecuado para usted.

Edición: Acabo de probar db4o 8.0 (versión .NET 4) y parece manejar perfectamente ambos tipos de registros y las jerarquías sindicales discriminadas.

0

Ligeramente OT como el PO no quería XML, pero al ver que otros se menciona el formateador XML ... Si desea persistencia textual, la SoapFormatter maneja los casos (ciclos/objeto-gráficos) que el formateador XML por defecto hace no - su XML no es tan legible como XMLFormatter, pero es más legible que el binario :)

Cuestiones relacionadas