Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何将数据从.NET持久化到磁盘?_C#_.net_Database_F#_Persistence - Fatal编程技术网

C# 如何将数据从.NET持久化到磁盘?

C# 如何将数据从.NET持久化到磁盘?,c#,.net,database,f#,persistence,C#,.net,Database,F#,Persistence,我有多种丰富的数据结构(主要是树),我希望将它们保存到磁盘上,这意味着我不仅希望将它们写入磁盘,而且希望保证数据已完全写入,并且能够在断电后存活 其他人似乎设计了将平面数据库表中的丰富数据结构编码为从父节点到子节点的查找表的方法。这有助于对数据运行SQL查询,但我不需要这样做:我只想保存和加载我的树 显而易见的解决方案是将所有内容作为一个blob存储在数据库中:单个条目可能包含一个长字符串。这是对数据库的滥用还是一种推荐做法?另一个解决方案可能是使用XML数据库?我是否应该考虑数据库的替代方案

我有多种丰富的数据结构(主要是树),我希望将它们保存到磁盘上,这意味着我不仅希望将它们写入磁盘,而且希望保证数据已完全写入,并且能够在断电后存活

其他人似乎设计了将平面数据库表中的丰富数据结构编码为从父节点到子节点的查找表的方法。这有助于对数据运行SQL查询,但我不需要这样做:我只想保存和加载我的树

显而易见的解决方案是将所有内容作为一个blob存储在数据库中:单个条目可能包含一个长字符串。这是对数据库的滥用还是一种推荐做法?另一个解决方案可能是使用XML数据库?我是否应该考虑数据库的替代方案

最后,我在F#上做这件事,所以从.NET持久化数据的交钥匙解决方案将是理想的

编辑:请注意,格式化(例如序列化)是不相关的,因为我可以用F#在格式之间进行简单的转换。这是关于获得一个确认,即写入操作已经完成,一直到非易失性存储(即磁盘盘),并且写入数据的任何部分都没有保存在易失性存储(例如RAM缓存)中,以便我可以继续安全地了解(例如,从磁盘删除数据的旧版本).

这可以通过

NET Framework包含许多用于将数据序列化到磁盘的内置选项,包括使用二进制或基于XML的格式。MSDN文档中提供了详细信息。

尝试使用XMLSerializer(System.Xml.Serialization)

它可以根据复杂数据结构的属性自动持久化这些结构,如果您愿意,还可以使用属性来控制输出:


为了做到这一点,您需要一个资源,使您能够参与(通常情况下,您会使用)

如果包含
事务,大多数数据库都将参与该事务。磁盘操作也可以由
事务管理,但您必须执行一些操作

另外,请注意,这仅在Windows Vista和更高版本上可用

如果使用数据库路径,则可以将树的序列化内容存储在blob(或文本,具体取决于序列化机制)中

注意,您也可以使用SQL Server中的功能(我相信是2008年及以后的版本)将文件存储在文件系统上可以获得SQL Server中事务的好处。

我以前没有使用过from F#,但这都是关于以事务方式将CLR对象图持久化到磁盘的。如果它可以处理记录和有区别的联合,可能适合您


编辑:我刚刚测试了db4o 8.0(.NET 4版本),它似乎可以很好地处理记录类型和区分的联合层次结构。

一些.NET的FileStream类的构造函数使用类型为的参数。FileOptions的值之一是WRITETHROW,这“指示系统应通过任何中间缓存进行写入,并直接转到磁盘。”


这将确保在您的写入操作(到新文件)返回时,数据已提交到磁盘,并且您可以安全地删除旧文件。

由于OP不需要XML,但看到其他人提到了XML格式化程序。。。 如果需要文本持久性,SoapFormatter将处理案例
(循环/对象图)默认的XML格式化程序没有-其XML的可读性不如XMLFormatter,但它比二进制的可读性更强:)

XMLSerializer无法处理几种F#类型,尤其是记录和区分联合,因为它们没有默认的无参数实例构造函数。这很不幸,因为区分联合提供了一种很好的树建模方法。二进制序列化是最直接的方法。@C.Lawrence Wenham:关于格式的答案是什么与我关于保证磁盘持久性的问题相关吗?不管是XML序列化程序还是任何其他序列化程序都不会做出这样的保证,好吧。没有任何东西可以保证写入磁盘,您需要检查之后是否没有异常,文件是否存在并且不是零字节。您可以实现System.Transactions.IEnlistmentNotifi在一个自定义类中,该类将在一个可分发事务中登记您的写操作,但是,这使您可以在写操作失败时回滚其他操作fails@C.Lawrence Whenham:没有任何东西可以保证写入磁盘的说法有点不正确。事务性NTFS从Vista开始就存在,所以虽然是的,但你不能保证C.Lawrence Wenham:我说的是保证它是作为确认而完成的,而不是将要完成的。使用API检查文件的有效性,但也没有这样的保证,显然并不能解决问题:一些数据仍然可以保存在一个易失性写缓冲区中等待写入到磁盘。数据库提供了这样的数据一致性保证,但我只需要持久化一个二进制blob,不一定是关系数据。重新“交钥匙解决方案”——一些(不是全部)F#构造可能超出了许多持久性层所期望的典型窗口——将使用DTO类层(就在序列化之前)如果它简化了事情,是否可以接受?另外-我怀疑您可能希望分别查看序列化和ACID方面。如果(查看您对Reed的评论)序列化方面不是问题,那么可能是任何ACID文档数据库。@Marc:“ACID文档数据库”“.太棒了,谢谢!作为一个随机的建议;可能值得一试。”look@JonHarrop:序列化不是关于格式化,而是关于持久性。“序列化是将对象的状态转换为可以持久化或传输的形式的过程。”发件人:@Jon Harrop: