为什么我的文件流不正确



我正在尝试修改文件流中线,因为文件有可能非常大,我不想将其加载到内存中。我要编辑的信息始终是相同的长度,因此从理论上讲,我可以使用流读取器将内容交换,但似乎并没有写入正确的位置

我创建了一个代码部分,该部分使用流读取器将逐行读取,直到找到正则匹配匹配,然后尝试将字节与编辑的行交换。代码如下:

private void UpdateFile(string newValue, string path, string pattern)
{
    var regex = new Regex(pattern, RegexOptions.IgnoreCase);
    int index = 0;
    string line = "";
    using (var fileStream = File.OpenRead(path))
    using (var streamReader = new StreamReader(fileStream, Encoding.Default, true, 128))
    {
        while ((line = streamReader.ReadLine()) != null)
        {
            if (regex.Match(line).Success)
            {
                break;
            }
            index += Encoding.Default.GetBytes(line).Length;
        }
    }
    if (line != null)
    {
        using (Stream stream = File.Open(path, FileMode.Open))
        {
            stream.Position = index + 1;
            var newLine = regex.Replace(line, newValue);
            var oldBytes = Encoding.Default.GetBytes(line);
            var newBytes = Encoding.Default.GetBytes("n" + newLine);
            stream.Write(newBytes, 0, newBytes.Length);
        }
    }
}

该代码几乎可以按预期工作,它插入了更新的行,但是它总是很早地完成,只是根据我正在编辑的文件,早期的变化略有变化。我希望这与我管理流立场的方式有关,但我不知道正确的方法。

不幸的是,我正在处理的确切文件在NDA下。

结构如下:文件将具有无关的数据,然后是已知格式的行,例如:描述:ABCDEF我知道"描述:"以下部分将始终是6个字符,因此我在行上进行替换以替换为uvwxyz。问题是例如,如果文件读为

'...不重要的数据描述:ABCDEF更多数据...'

它将像

之类的东西出现
'...不重要的ddescription:uvwxyzdef更多数据...'

我认为这里的问题是您没有考虑要获得的每条线,因此您的索引不正确地设置了流的位置。尝试以下代码:

private void UpdateFile(string newValue, string path, string pattern)
{
   var regex = new Regex(pattern, RegexOptions.IgnoreCase);
   int index = 0;
   string line = "";
   using (var fileStream = File.OpenRead(path))
   using (var streamReader = new StreamReader(fileStream, Encoding.Default, true, 128))
   {
       while ((line = streamReader.ReadLine()) != null)
       {
           if (regex.Match(line).Success)
           {
            break;
           }
           index += Encoding.ASCII.GetBytes(line + "n").Length;
       }
   }
   if (line != null)
   {
       using (Stream stream = File.Open(path, FileMode.Open))
       {
           stream.Position = index;
           var newBytes = Encoding.Default.GetBytes(regex.Replace(line + "n", newValue));
           stream.Write(newBytes, 0, newBytes.Length);
       }
   }
}

在您的示例中,您是4个字符的"关闭"。不是很常见的"一个错误",而是关闭。但是,也许不同的模式最有帮助?

如今的程序很少像这样"在文件上"工作。在中期过程中,有太多的问题要出错。相反,他们:

  • 在同一位置创建一个空的新文件。通常命名和隐藏。
  • 将输出写入新文件
  • 一旦完成并且eveyrthing很好 - 所有的缓存都被冲洗了,并且一切都在磁盘上(通过stream.close((或dispose((完成( - 只需使用OS移动使用新文件替换旧文件操作。

优势是不可能拥有数据损失。即使计算机失去了功率中型操作,在顶部,临时文件也会混乱。您仍然得到了Orignal文件,如果您也需要,您可以只使用临时文件并从头开始重新启动工作。确实,恢复仅在极少数情况下(文字处理器(

是有意义的

用新文件替换旧文件是通过移动订单完成的。如果它们在同一分区上,那实际上只是文件类上的重命名操作。而且,由于现代FS基本上的设计就像顶线一样,因此稳健的关系数据库中没有危险。

您可以在从您选择的porcessor到backup程序的所有内容中找到该模式,即Firefox的下载管理器(您可能是覆盖了Befroe的文件(,甚至是zipping程序。每当您有一个漫长的写作阶段并想最大程度地减少危险时,就可以使用模式。

,您可以完全在记忆中工作,而无需处理读/写的头部,它也会解决您的问题。

编辑:我从内存/文档制作了一些源代码。可能包含语法错误

string sourcepath; //containts the source file path, set by other code
string temppath; //containts teh path of the tempfile. Should be in the same folder, and thus same partiion
//Open both Streams, can use a single using for this
//The supression of any Buffering on the output should  be optional and will be detrimental to performance
using(var sourceStream = File.OpenRead(sourcepath), 
  outStream = File.Create(temppath, 0, FileOptions.WriteThrough )){
    string line = "";
    //itterte over the input
    while((line = streamReader.ReadLine()) != null){
        //do processing on line here
        outStream.Write(line);
    }
}

//替换文件。可以肯定的是,它会覆盖而无需问file.move(temppath,sourcepath(;

相关内容

  • 没有找到相关文章

最新更新