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