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