在同一个 FileStream 读取和覆盖
Read and overwrite at the same FileStream
我正在使用 FileStream
将文件锁定为其他进程不可写并对其进行读写,我正在使用以下方法:
public static void ChangeOrAddLine(string newLine, string oldLine = "")
{
string filePath = "C:\test.txt";
FileMode fm = FileMode.Create;
//FileMode fm = FileMode.OpenOrCreate;
using (FileStream fs = new FileStream(filePath, FileMode.Create, FileAccess.ReadWrite, FileShare.Read))
using (StreamReader sr = new StreamReader(fs))
using (StreamWriter sw = new StreamWriter(fs))
{
List<string> lines = sr.ReadToEnd().Split(new string[] { "\r\n" }, StringSplitOptions.None).ToList();
bool lineFound = false;
if (oldLine != "")
for (int i = 0; i < lines.Count; i++)
if (lines[i] == oldLine)
{
lines[i] = newLine;
lineFound = true;
break;
}
if (!lineFound)
lines.Add(newLine);
sw.Write(string.Join("\r\n", lines));
}
}
我想用新内容覆盖它,但找不到正确的 FileMode
,使用 FileMode.OpenOrCreate
只是将新内容附加到旧内容,FileMode.Create
删除当时的文件内容,FileStream
fm已经初始化,所以文件是空的。
我现在只需要清除旧内容,当我在方法 运行 中写入新内容而不丢失其写锁时。
OpenOrCreate just appends ...
因为你看完后没有重新定位。
这也说明了您的方法存在的主要问题:FileStream 只有一个 Position,Reader 和 Writer 大量使用缓存。
但是,只要您想替换所有内容并且确实需要该锁定方案:
using (FileStream fs = new FileStream(filePath,
FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.Read))
{
using (StreamReader sr = new StreamReader(fs))
{
... // all the reading
}
fs.Position = 0;
using (StreamWriter sw = new StreamWriter(fs))
{
sw.Write(string.Join("\r\n", lines));
}
fs.SetLength(fs.Position); // untested, something along this line
}
也许你必须说服 sw 和 sr 让他们的流保持打开状态。
但我必须注意 FileShare.Read
标志在这种情况下没有太大意义。 reader 可能会看到各种不一致的数据,包括断行和损坏的 UTF8 字符。
我正在使用 FileStream
将文件锁定为其他进程不可写并对其进行读写,我正在使用以下方法:
public static void ChangeOrAddLine(string newLine, string oldLine = "")
{
string filePath = "C:\test.txt";
FileMode fm = FileMode.Create;
//FileMode fm = FileMode.OpenOrCreate;
using (FileStream fs = new FileStream(filePath, FileMode.Create, FileAccess.ReadWrite, FileShare.Read))
using (StreamReader sr = new StreamReader(fs))
using (StreamWriter sw = new StreamWriter(fs))
{
List<string> lines = sr.ReadToEnd().Split(new string[] { "\r\n" }, StringSplitOptions.None).ToList();
bool lineFound = false;
if (oldLine != "")
for (int i = 0; i < lines.Count; i++)
if (lines[i] == oldLine)
{
lines[i] = newLine;
lineFound = true;
break;
}
if (!lineFound)
lines.Add(newLine);
sw.Write(string.Join("\r\n", lines));
}
}
我想用新内容覆盖它,但找不到正确的 FileMode
,使用 FileMode.OpenOrCreate
只是将新内容附加到旧内容,FileMode.Create
删除当时的文件内容,FileStream
fm已经初始化,所以文件是空的。
我现在只需要清除旧内容,当我在方法 运行 中写入新内容而不丢失其写锁时。
OpenOrCreate just appends ...
因为你看完后没有重新定位。
这也说明了您的方法存在的主要问题:FileStream 只有一个 Position,Reader 和 Writer 大量使用缓存。
但是,只要您想替换所有内容并且确实需要该锁定方案:
using (FileStream fs = new FileStream(filePath,
FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.Read))
{
using (StreamReader sr = new StreamReader(fs))
{
... // all the reading
}
fs.Position = 0;
using (StreamWriter sw = new StreamWriter(fs))
{
sw.Write(string.Join("\r\n", lines));
}
fs.SetLength(fs.Position); // untested, something along this line
}
也许你必须说服 sw 和 sr 让他们的流保持打开状态。
但我必须注意 FileShare.Read
标志在这种情况下没有太大意义。 reader 可能会看到各种不一致的数据,包括断行和损坏的 UTF8 字符。