C# 文件中数据段的重新排序 我试图在C、C++、C、java或任何语言中找到一个算法,以帮助解决我所面临的重新排序问题。

C# 文件中数据段的重新排序 我试图在C、C++、C、java或任何语言中找到一个算法,以帮助解决我所面临的重新排序问题。,c#,java,c++,language-agnostic,C#,Java,C++,Language Agnostic,目标是在一个文件中获取一系列范围,并以新模式重新组织,基本上在不破坏数据完整性的情况下移动数据片段。我更愿意找到一个可以在适当的地方执行它,并使用单个缓冲区进行交换,或者直接从一个地方移动到另一个地方。只要范围在完成时具有相同的长度和数据完整性,重组过程就可以将范围分解为多个部分 例如,给定一组值: Length SrcStart Src End Dst Start Dst End 9178 274054 283231

目标是在一个文件中获取一系列范围,并以新模式重新组织,基本上在不破坏数据完整性的情况下移动数据片段。我更愿意找到一个可以在适当的地方执行它,并使用单个缓冲区进行交换,或者直接从一个地方移动到另一个地方。只要范围在完成时具有相同的长度和数据完整性,重组过程就可以将范围分解为多个部分

例如,给定一组值:

  Length    SrcStart     Src End   Dst Start     Dst End
    9178      274054      283231           0        9177
  274051           0      274050        9178      283228
  582929      283229      866157      283229      866157
  399208      874397     1273604      866158     1265365
    8239    14675709    14683947     1265366     1273604
  986980     1273605     2260584     1273605     2260584
  602862     2811144     3414005     2260585     2863446
  138712     4092072     4230783     2863447     3002158
  116210     3414007     3530216     3002159     3118368
  550559     2260585     2811143     3118369     3668927
  561856     3530217     4092072     3668928     4230783
24319165     4230784    28549948     4230784    28549948
  578539    30246149    30824687    28549949    29128487
  491856    28549949    29041804    29128488    29620343
  593580    29639113    30232692    29620344    30213923
  597308    29041805    29639112    30213924    30811231
   13456    30232693    30246148    30811232    30824687
  633513    31407949    32041461    30824688    31458200
  583261    30824688    31407948    31458201    32041461
40117358    32041462    72158819    32041462    72158819
SrcStart->SrcEnd范围中的所有内容都需要移动到DstStart->DstEnd范围。请注意,在许多情况下,从源位置转移到目标位置会导致目标位置的内容发生更改,因为所需的原始数据已被销毁,因此无法再从该位置复制这些内容

目标是将每个数据段从SrcStart移动到DstStart,长度在第一列中。每一行对应的“结束”只是开始加上长度减一(因此是实际偏移)

我做了很多研究,研究了交换值,并将与其他值交叉的区域以及容器交换中的容器进行了细分,但它们似乎不够。因此,这让我回到了我的第一句话,我希望也许有一种算法或某种来源可以帮助我解决这个问题,而社区的共享知识似乎是一条出路


谢谢

您可以使用磁盘碎片整理程序使用的方法

  • 首先将需要覆盖的数据复制到可用区域
  • 更改引用该数据的任何索引以指向新位置,以便将来使用该副本
  • 如果系统有“未使用”的概念,则可能需要注意任何块是否变为“未使用”

但是,如果索引以字节为单位,则表示整个文件只有80MB。这么小的文件可以很快复制(不到两秒钟),也许真正的例子要长得多。该文件总共有多大?

您提出的问题就像它是一个不透明的二进制文件,出于某种原因,您希望在其中交换块。事实似乎不太可能如此。这个文件肯定有自己的结构吗?你不能利用它来帮你记账吗

  • 文件是否有“已使用”和“未使用”区域的概念
  • 文件是否具有块头的内部结构
  • 文件是否有任何相关的索引或任何需要保持同步的内容?(如果没有,您从哪里获得要移动的块列表?)
  • 要移动的块可以相互重叠吗?请注意,如果可以,操作顺序将变得重要
尽管如此,@Peter Lawrey推荐的方法是好的。如果覆盖块,首先将其复制到文件中的另一个位置,更新所有重叠索引

总的来说,在我看来,你试图解决一个难题,把它分为两个步骤,一个简单,另一个。。。更难。最初的问题是什么


(强制性建议:在Windows上,可以使用事务IO API)。

我认为以下算法最多可以使用两倍于最大卡盘大小的内存来缓存数据。除了数据缓存外,您还需要一个簿记FIFO和原始列表。它是这样的:

  • 如果FIFO和移动表都为空,则完成
  • 如果FIFO为空,将顶部条目从移动表移动到FIFO,并将条目数据读取到数据缓存中
  • 检查是否有任何块与移动表中FIFO中第一个条目的目标区域重叠
  • 如果存在块,将块的数据读取到缓存中,将条目移动到FIFO,转到3
  • 如果没有块,将FIFO项的数据从缓存写入目标,删除第一个FIFO项,转到1
  • 其思想是找到被占用的块,缓存它们以打开空间,并尽快清除缓存中的数据。您可能需要添加一些健全性检查,以查看源地址和目标地址是否相同。您可能还需要执行其他检查,以查看原始表是否有意义(两个块移动到同一位置,等等)


    编辑:我可能已经乐观地陈述了最大区块乘以两个估计值的最大值。我认为它可以超越这一点。我认为乘以3是一个简单(但不严格)的上限


    因为源表中有相当大的块,所以可以将它们拆分以减少缓存使用。比如说,您希望使用最多1 GB的缓存:在运行算法之前,将大于1/3GB的所有块拆分为多个长度为1/3GB的条目。或者,您可以使算法以子块大小工作(而不是将完整块读入缓存,而是只读取相关部分,并将修改后的条目保留在源表中),但我认为这将更难管理/实现。

    您是否考虑过将值读入字典、哈希表、列表或分类列表中?如果您是从文件中读取这些值,您应该能够快速将文件中的数据加载到集合或多个列表或多个哈希表中,并使用添加、删除、,对列表中的方法进行排序。我假设数据的布局与文件中的布局一样。。?如果出现更糟糕的情况,您可以始终使用字段名创建一个枚举,并使用枚举的(int)值,该值将在枚举中声明的字段名表示为标题布局。此移动操作列表实际上是如何计算的?你在整理碎片吗?然后检查这个链接:我想你可以跳过