【问题标题】:C# Insert data in file without rewriting it [duplicate]C#在文件中插入数据而不重写它[重复]
【发布时间】:2019-11-07 23:25:08
【问题描述】:


我有一个文件,里面有一些数据。现在我想添加一些内容,但不是通过附加它。更像是“在此文件的当前第 10 和第 11 字节之间添加这个 4 字节块”。目前我正在使用 FileStream 来读取和写入文件。
所以我的问题是:有没有办法在不重写整个文件的情况下插入这些数据?
谢谢,
尼尔斯。

【问题讨论】:

    标签: c# file stream filestream


    【解决方案1】:

    编辑 2 - 重写

    经过大量 cmets 后,我发现真正的问题是您的数据库大多像文件系统一样工作。最大的区别可能是集群知道它们所属的文件,而不是相反。我将为DDL/Shema 使用文件系统术语。抱歉,我无法正确突出显示 SQL 语法。

    CREATE TABLE Files(
      ID INTEGER PRIMARY KEY
      /* a bunch of other columns that do not really mater for this */
    );
    
    CREATE TABLE Clusters(
      ID INTEGER PRIMARY KEY,
      FK_FileID INTEGER FOREIGN KEY (Files.ID), -- Special, see text
      ClusterNumber INTEGER, --Special, see text
      Contents --whatver type you need
    );
    

    Clusters 在很多方面都是一个奇怪的表:

    • pirmary 密钥是最不相关的。事实上,您可以适当地删除它的索引。我拥有它的唯一原因是 a) 习惯,b) 因为你可能会后悔没有它,c) 它可能对管理工作有用
    • ClusterNumber 是“FK_FileID 的第 N 个集群”
    • ClusterNumber 和 FK_FileID 应该有一个共享的唯一约束(两者的组合必须是唯一的)并且应该可能位于涵盖两者的索引上。把它们想象成一个复合主键或多行代理键(这听起来像一个矛盾的说法)。你会比官方PK更频繁地使用这些方式。

    你会得到这样一个文件的所有集群:

    SELECT Content FROM Clusters 
    ORDER BY ClusterNumber 
    WHERE FK_FileID = /*The file whose whole data you want*/
    

    那个额外的索引会很好地覆盖。

    如果您想在其中的任何地方推入一个片段,您会:

    1. 将以下所有段 ClusterNumber 1 向上移动
    2. 只需为此文件添加一个带有新释放的 ClusterNumber 的 Cluster 条目
    3. 最后一步可能有点浪费,比如只添加一个 4 个字母的簇。

    假设您将其存储在 HDD/旋转磁盘存储上,您可能无论如何都无法避免定期进行碎片整理,因此您不妨在这样做的同时整合集群以减少浪费。除非您能以某种方式教 DBMS 正确阅读此内容(您需要为此向 DB 专家咨询),否则您希望尽可能多地在 DB 中按顺序排列文件的所有集群,以便将它们一起放在磁盘上出色地。当然是物理介质是合适的SSD,可以跳过碎片整理,只做整合。

    高级选项包括提前为文件(其他文件不会使用)保留扩展空间等内容。所以集群可以保持在一起(即使不按顺序),并且碎片整理的需要更少。

    【讨论】:

    • 所以不是我所希望的,但总比没有好:)。将流位置设置为第 10 个字节并覆盖它就足够了吗?
    • @BDevGW IIRC,大多数 FileStream 类都有插入模式。缓存可能会延迟任何实际工作,直到 Stream 关​​闭,但不能保证。
    • @BDevGW:我找不到插入模式开关。所以我在帖子中给了你我保存的“修改文件”代码。文字处理器使用与此模式非常相似的东西。
    • 所以是的,从那里转到位置并覆盖。
    • @BDevGW 事情是覆盖/插入是非常危险的。忽略性能(这实际上不是您可以避免的),所花费的时间为 Fubar 提供了充足的时间来罢工并切断电源或在重写过程中使程序崩溃。这就是为什么您首先使用修改后的内容创建一个文件。然后把新文件放到旧文件的地方。 |当然,最好还是把这个文件变成一个合适的数据库表。有了这些,您就可以使用 DBMS 来处理所有这些麻烦。
    猜你喜欢
    • 2015-09-24
    • 1970-01-01
    • 1970-01-01
    • 2014-02-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-12-14
    • 1970-01-01
    相关资源
    最近更新 更多