我有一个文本文件,其中包含我要编辑的一些信息。该文件看起来像这样:
id: 31
name: Anna
profession: Doctor
我可以使用StreamReader
读取该条目,并将其显示在我的应用程序中。然后,我希望用户能够更改条目的name
和profession
,因此我希望将这些特定行编辑为新值,同时保持id
完整(在我的真实代码中,不仅有几行,而且还有很多行,其中只有一些应该更改)。因此,例如,我希望在操作结束时,该文件看起来像这样。
id: 31
name: Emma
profession: Programmer
但是,我还必须考虑到有时行事先不存在。例如,在将Anna
修改为Emma
之前,不确定她是否有专业,该文件可能看起来像这样:
id: 31
name: Anna
在这种情况下,我想将行profession: Programmer
添加到那里。
我尝试使用具有FileStream
访问权限的ReadWrite
,我将其提供给StreamReader
和StreamWriter
,但之后我发现无法更改或替换某行文本,只读它并写一个新的相同的行,同时保持旧的。
using (FileStream fileStream = new FileStream(filePath, FileMode.Open, FileAccess.ReadWrite))
using (StreamReader reader = new StreamReader(fileStream))
using (StreamWriter writer = new StreamWriter(fileStream))
{
bool idExists = false;
bool nameExists = false;
bool tagsExist = false;
string line;
while((line = reader.ReadLine()) != null)
{
if (line.StartsWith("id:"))
idExists = true;
else if (line.StartsWith("name:"))
{
nameExists = true;
line = $"name: {entryToSave.Name}";
writer.WriteLine(line); // Will write an additional line and not replace
}
else if (line.StartsWith("profession:"))
{
professionExists = true;
line = $"profession: {entryToSave.Profession}";
writer.WriteLine(line); // Will write an additional line and not replace
}
}
if (!idExists)
writer.WriteLine($"id: {generatedId}");
if (!nameExists)
writer.WriteLine($"name: {entryToSave.Name}");
if (!professionExists)
writer.WriteLine($"profession: {entryToSave.Profession}");
}
我也尝试使用File.ReadAllLines
,遍历这些行,然后将所有行写回文件,只修改要修改的行。但是,由于某些我无法理解的原因,我无法通过File.WriteAllLines
访问该文件,因为StreamWriter
具有访问权限。代码:
var previousData = File.ReadAllLines(filePath);
var newData = new List<string>();
bool idExists = false;
bool nameExists = false;
bool professionExists = false;
for (int i = 0; i < previousData.Length; i++)
{
var line = previousData[i];
if (line.StartsWith("id:")
idExists = true;
else if (line.StartsWith("name:")
{
nameExists = true;
line = $"name: {entryToSave.Name}";
}
else if (line.StartsWith("profession:"))
{
professionExists = true;
line = $"profession: {entryToSave.Profession}";
}
newData.Add(line);
}
if (!idExists)
newData.Add($"id: {generatedId}");
if (!nameExists)
newData.Add($"name: {entryToSave.Name}");
if (!professionExists)
newData.Add($"profession: {entryToSave.Profession}");
File.WriteAllLines(filePath, newData.ToArray()); // Access denied
如果没有文件流相互干扰,如何最容易实现这一目标?
答案 0 :(得分:0)
如果您已经在条目中向用户显示了数据,并允许用户编辑name
和profession
,您只需阅读该文件,获取ID并填写其余部分具有条目值的文件。以下是控制台应用程序的示例。
static void Main(string[] args)
{
var filePath = "test.txt";
// Simulated input from user
// these should come from entries in the application?
var name = "Foo";
var profession = "Bar";
var personData = new PersonData(); // class declared below
using (FileStream fileStream = new FileStream(filePath, FileMode.Open, FileAccess.ReadWrite))
using (StreamReader reader = new StreamReader(fileStream))
{
string line;
while ((line = reader.ReadLine()) != null)
{
if (line.StartsWith("id:"))
personData.ID = line;
}
} // Now reader and filestream is closed, file is available again.
// You don't specify what you would like to happen if personData.ID is null,
// so I make an assumption the generatedId is what you'd like to use.
if (string.IsNullOrWhiteSpace(personData.ID)
personData.ID = $"id: {generatedId}";
// Add the data from the entries
personData.Name = $"name: {name}";
personData.Profession = $"profession: {profession}";
File.Delete(filePath); // remove the file
using (FileStream fileStream = new FileStream(filePath, FileMode.OpenOrCreate, FileAccess.ReadWrite))
using (StreamWriter writer = new StreamWriter(fileStream))
{
writer.WriteLine(personData.ID);
writer.WriteLine(personData.Name);
writer.WriteLine(personData.Profession);
}
}
private class PersonData
{
public string ID { get; set; }
public string Name { get; set; }
public string Profession { get; set; }
}
现在,如果您遇到权限问题,您只需要了解如何访问该文件。