2017-04-02 116 views
1

我有一个文本文件,其中包含一些我想要编辑的信息。该文件看起来是这样的:C#更改文件中的特定行

id: 31 
name: Anna 
profession: Doctor 

我可以读一个StreamReader该条目,并在我的应用程序出示。然后我希望用户能够更改条目的nameprofession,所以我想将这些特定行编辑为新值,同时保持id完整(在我的真实代码中,不仅有几行,但很多行只有一些应该改变)。因此,例如,我希望在我的操作结束时将文件看起来像这样。

id: 31 
name: Emma 
profession: Programmer 

但是,我也必须考虑到,有时候行并不是事先存在的。例如,编辑AnnaEmma之前,它并不一定是她有一个行业,该文件可能是这个样子的:

id: 31 
name: Anna 

而且在这种情况下,我想行profession: Programmer添加到结束。

我尝试使用FileStreamReadWrite访问,我给一个StreamReaderStreamWriter,但后来我发现没有更改或替换文本行,只有阅读它,写一个相同的新线,同时保持的方式旧。

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

我刚刚发现我自己现在我无法做File.WriteAllLines的原因不是文件很忙,因为某种原因访问被拒绝,我不知道如何解决。我会编辑我的问题。 – Helena

+0

如果您发现我的解决方案有帮助,我会非常感激,如果您将其标记为答案:) – CitiZen

+0

哦,对,对不起,我忘了!会做。 – Helena

回答

0

如果您已经在条目中向用户显示了数据,使用户能够编辑nameprofession,那么您只需读取文件,获取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; } 
} 

现在你只需要找出如何获得文件的权限,如果你有权限问题。

+1

从一个文件读取,删除它并写入一个新文件确实是最简单的方法! – Helena