C# 写入文本文件并不总是有效/保存

C# 写入文本文件并不总是有效/保存,c#,filewriter,C#,Filewriter,我有一个比较两个文本文件并将差异写入日志文件的代码,但由于某些原因,log.txt文件有时是空白的,即使是测试时,某些行以a*开头,这些代码也不总是被写入。完成编写后,我是否必须保存文本文件,尽管这并不能解释为什么有时它会起到任何帮助作用那太好了 private void compare() { string FilePath = @"c:\snapshot\1.txt"; string Filepath2 = @"c:\snapshot\2.txt"; int counter =

我有一个比较两个文本文件并将差异写入日志文件的代码,但由于某些原因,log.txt文件有时是空白的,即使是测试时,某些行以a*开头,这些代码也不总是被写入。完成编写后,我是否必须保存文本文件,尽管这并不能解释为什么有时它会起到任何帮助作用那太好了

private void compare()
{
  string FilePath = @"c:\snapshot\1.txt";
  string Filepath2 = @"c:\snapshot\2.txt";
  int counter = 0;
  string line;
  string line2;

  var dir = "c:\\snapshot\\log.txt";

  using (FileStream fs = File.Create(dir))
  {
    fs.Dispose();
  }

  StreamWriter dest = new StreamWriter(dir);

  if (File.Exists(FilePath) & File.Exists(Filepath2))
  {
    // Read the file and display it line by line.
    using (var file = File.OpenText(FilePath))
    using (var file2 = File.OpenText(Filepath2))
    {
      while (((line = file.ReadLine()) != null & (line2 = file2.ReadLine()) != null))
      {
        if (line.Contains("*"))
        {
          dest.WriteLine(line2);
        }
        else if (!line.Contains(line2))
        {
          dest.WriteLine(line2);
        }
        counter++;
      }
    }
  } 
  dest.Close();
}

在StreamReader上点击close语句后,应该写出缓冲区中剩余的所有内容。如果你丢失了一些东西,那么可能是因为某种原因(例如,你撞车)你没有到达那条线。此外,如果您试图在编写文件时(即程序仍在运行时)查看文件,则不一定会看到所有内容(因为它尚未关闭)


通常,最好在StreamReader中使用using语句。这将确保它始终处于关闭状态。

不确定我是否正确理解您的比较逻辑,但只要我将比较从整个代码中分离出来,您就可以根据自己的需要进行调整:

    public static void WriteDifferences(string sourcePath, string destinationPath, string differencesPath)
    {
        var sourceLines = File.ReadAllLines(sourcePath).ToList();
        var destinationLines = File.ReadAllLines(destinationPath).ToList();            

        // make lists equal size
        if (sourceLines.Count > destinationLines.Count)
        {
            destinationLines.AddRange(Enumerable.Range(0, sourceLines.Count - destinationLines.Count).Select(x => (string)null));
        } 
        else
        {
            sourceLines.AddRange(Enumerable.Range(0, destinationLines.Count - sourceLines.Count).Select(x => (string)null));
        }

        var differences = sourceLines.Zip(destinationLines, (source, destination) => Compare(source, destination));

        File.WriteAllLines(differencesPath, differences.Where(x => x != null));
    }

    private static string Compare(string source, string destination)
    {
        return !source.Contains(destination) || source.Contains("*") ? destination : null;
    }
我向您推荐FileStream的重载。按照我的方式执行,如果运行该流的用户没有所有必需的权限,那么代码将在您实例化该流时崩溃。这是一个很好的方式来显示你的意图,什么你不


PS您知道contains区分大小写和区域性吗?

粗略地看,您的行可能会不同步,因为您正在读取两个数据不同的文件。如果文件不大,您可能希望将它们加载到列表中并进行更正式的比较。代码中有一些混乱,如果您使用“using”,您不需要调用dispose,为什么您不为StreamWriter使用“using”,为什么使用FileStream而不使用它…顺便说一句,
using
语句的全部要点,它将为您调用Dispose,因此在
块中使用
调用Dispose充其量是不需要的。请使用
&&
,而不是
&
。单一的
&
是按位运算,可能最终会做你想做的事情,但通常这里你指的是
&
。我对c#是新手,编程只是自学和获取论坛提示,所以在使用“使用”时不需要使用dispose将两个文本文件加载到列表中,然后比较列表的最佳方式是什么?注意:如果您已经对StreamReader的输入进行了四舍五入操作,例如Filestream,当FileStream实例超出范围时,如果在StreamReader上也安装一个,则会给您一个已经处理过的错误。我不确定是否对您的假设非常感兴趣,即没有足够的内存来保存这两个文件和差异…这取决于。如果我确定,文件永远不会超过1mb,我更喜欢易于维护的代码,如果不确定,逐行读取和比较是没有问题的,这可能会比当前的方法慢(不确定io缓存如何处理逐行读取)。如果我知道文件很小,我没有问题。鉴于我们不知道这一点,我想我会提到这个问题,对于那些不喜欢间歇性OOM的人,他们的代码是:(我认为你不需要手动冲洗:嗯,我知道它说你不应该这样做,但我已经见过它多次以一种皮带和支架综合的方式解决问题。我不相信它会发生,所以我现在称之为自卫。
private void compare()
{
  string FileName1 = @"c:\snapshot\1.txt";
  string FileName2 = @"c:\snapshot\2.txt";
  string FileNameOutput = @"c:\snapshot\log.txt"; //dir ???
  int counter = 0; // um what's this for you aren't using it.

  using (FileStream fso = new FileStream(FileNameOutput, FileMode.Create, FileAccess.Write))
  {
    TextWriter dest = new StreamWriter(fso);
    using(FileStream fs1 = new FileStream(FileName1, FileMode.Open, FileAccess.Read))
    {
      using (FileStream fs2 = new FileStream(FileName2, FileMode.Open, FileAccess.Read))
      {
        TextReader firstFile = new StreamReader(fs1);
        TextReader secondFile = new StreamReader(fs2);
        while (((line1 = firstFile.ReadLine()) != null & (line2 = secondFile.ReadLine()) != null))
        {
          if ((line1.Contains("*") || (!line1.Contains(line2)))
          {
            dest.Write(line2); // Writeline would give you an extra line?
          }
          counter++; // 
        }
      }
    }
  fso.Flush();
}