2013-10-16 27 views
0

我想在C#中同時讀寫一個文件。我在這裏和MSDNA中閱讀了許多主題,但沒有一篇似乎能滿足我的需求。 我的文件有一系列用逗號分隔的數字。大量的數字是確切的。我的數據樣本行是這樣的在C中同時讀寫一個文件#

-0.1171695,0.03270377,2.420116,-0.02128719,0.9612453,0.2460478,-0.1225349,-0.110185,0.07739609,2.500247,-0.2783474,-0.06909045,-0.01818598,0.9578197,-0.1089995,0.456151,2.639686,0.3486561,-0.0008622027,-0.002657401,0.9372466,-0.1170361,0.6441286,2.674476,0.08662115,0.001171953,-0.01347759,0.9961495,-0.2623751,0.3104511,2.600713,-0.002028131,0.004831213,0.9220369,-0.3870664,-0.3145202,0.123338,2.49155,0.217727,0.4528476,-0.2009471,0.8409188,-0.2771441,-0.07509593,2.299996,0.2185546,3.817581E-09,7.635163E-09,0.9758247,-0.2690773,-0.1254997,2.259336,-0.02814693,0.0009682054,-0.03436448,0.9990125,0.01672855,0.3196935,2.572941,0.001961287,0.005368799,0.9392719,0.3431264,0.08505877,0.1033191,2.450031,0.1364797,-0.3903133,0.161962,0.8959894,0.03953359,-0.08940583,2.255897,0.2523192,7.699712E-09,0,0.967644,0.01856858,-0.1507191,2.211281,0.004362902,0.0004109977,0.09378911,0.9955825,-0.1821601,-0.03123568,2.403718,4.035548E-09,-3.067017E-07,0.9231187,-0.384515,-0.2238743,-0.4083549,2.266029,-0.05534944,0.02699615,-0.3286877,0.9424288,-0.2095885,-0.7422835,2.178757,-0.06393463,-0.003723484,-0.0580211,0.9962591,-0.2166772,-0.7653325,2.087598,0.5079094,0.03407073,-0.05760901,0.8588064,-0.05478298,-0.01793054,2.37413,8.070093E-09,-3.066635E-07,0.9232336,0.3842392,0.004473582,-0.3737353,2.252681,-0.09306445,-0.04594634,0.3224528,0.9408783,0.004849254,-0.7096405,2.178587,-0.03546751,0.003154774,0.08854229,0.9954358,-0.005173458,-0.7367281,2.088935,0.5053017,0.02486493,-0.04239483,0.861542,63507242650167 

它實際上佔用了24行的寫字板。每一行。我想要做的是去每行的最後一個數字,改變它,並將其保存迴文件中。我發現的所有同步作者閱讀器源代碼正在使用append。我不希望在文件末尾追加。我希望從每行中獲取最後一個數字,並將修改後的數據放回。我希望其餘數據保持不變。我該怎麼做?

+2

我不明白爲什麼這需要同時讀取和寫入。 – tnw

+0

您無法同時讀取和寫入。您必須將文件讀入字符串或對象,進行編輯,然後覆蓋文件。 – tmoore82

+0

類似的問題和一些可以讓你開始的代碼:http://stackoverflow.com/questions/1368539/how-do-i-read-and-edit-a-txt-file-in-c – tmoore82

回答

0

讀取和保存文件:

StringBuilder newTextFile = new StringBuilder(); 
string[] lines = File.ReadAllLines(@"1.txt"); 
foreach (string l in lines) 
{ 
    // logic to replace last number, saved in string newLine 
    // you can find the last   
    newTextFile.Append(newLine + "\r\n"); 
} 
File.WriteAllText(@"1.txt", newTextFile.ToString()); 

更改線路(從我的頭頂,測試一下吧!):

int locationAt = line.LastIndexOf(','); 
string newLine = line.Substring(0, locationAt) + newValue + line.Substring(locationAt); 

OR:

string[] values = line.Split(','); 
values[values.Length - 1] = 'somethingelse'; 
string newLine = string.Join(",", values); 
+0

請注意,此程序的內存佔用量是整個文件大小的兩倍多。 – Servy

+0

@Servy你是對的。但文本文件本身是一個錯誤。數據應該採用適當的格式。 – lolol

+0

數據是從kinect獲取的動作捕捉數據,無論如何,最後一個字符串是不是新行?它是最後一個字符串的一部分嗎?還是完全被忽略? –

2

你想做的事情在Windows和POSIX的底層文件I/O API中都受到限制;特別是,不可能插入或刪除文件中間的字節,除了重寫整個文件。有兩種常用的方法來「改寫整個文件」:

  • 閱讀整個文件,並將其寫回到一個文件,用所需的更改。完成後,關閉這兩個文件,刪除舊文件,並將新文件重命名爲舊名稱。 (只有在Windows上才需要「刪除舊文件」步驟,不幸的是,它引入了一個競賽窗口,在該窗口中同時發生的讀者可能會發現文件不存在於正確的名稱下。)這是首選技術,因爲它更容易要正確編碼,並不要求你暫時保存整個文件在內存中,如果計算機在操作過程中崩潰,並且保證併發讀取器將看到新文件或者舊的,而不是兩者的組合。但是,它要求暫存磁盤空間等於較大的舊文件或新文件。

  • 將整個文件讀入內存。對文件的內存中表示進行更改(可能與大字符串或字符串列表一樣簡單)。倒轉文件句柄並從頭開始寫回所有內容。 (從技術上講,只需要在第一次更改後寫入所有內容,但這要求您知道第一次更改的字節偏移量,這通常比其值得的更麻煩。)如果結果比原始值短,請使用truncate或相當於切斷多餘部分。這不需要額外的暫存磁盤空間,但併發讀取器可能會看到這兩個文件的混亂組合,如果計算機在操作過程中崩潰,該文件可能會被破壞。您可以通過文件鎖定來緩解併發讀者問題,但請注意,某些文件鎖定機制是建議,即僅對識別鎖定可能正在進行的讀者有效。

一些操作系統和/或文件系統需要在新文件fsync一個電話,之前的重命名,以確保數據的完整性,如果計算機崩潰的數萬的分鐘長的窗口之後的重命名。這是這些系統中的一個錯誤。

+0

這不是* only *的方式。在這種情況下,將整個文件讀入內存然後覆蓋文件的內容也是一種選擇。 – Servy

+1

但是請注意,Servy的解決方案將一場比賽換成另一場比賽,讀者可以閱讀一半的書面文件。 –

+0

@ScottChamberlain確實。理想情況下,您只需將所有文件訪問權限同步到一個線程,並且只要有可能就擁有多個工作人員。 – Servy

1

爲什麼不用ReadAllLines()讀取文件,用Regex.Replace()替換,然後WriteAllLines()

編輯: 詳細:

string[] lines = File.WreadAllLines("file.txt"); 
int lastnum; 
for(int i=0;i<lines.Count;i++) 
    lines[i]=System.Text.RegularExpressions.Regex.Replace(lines[i], @",(\d+)$", m => 
    { 
     lastnum = Convert.ToInt32(m.Groups[1].Value); 
     // Do any operations on lastnum 
     return "," + lastnum.ToString(); 
    }); 

File.WriteAllLines("file.txt",lines); 
+0

你可以用更多關於Regex.Replace的信息來編輯你的答案嗎? –

+0

請檢查編輯 – Jerry

0

,因爲你只有每一行的逗號後更改的最後一個號碼,你可以做什麼用線讀取線,並得到逗號的最後一個索引,然後獲取子字符串。您可以將所有這些最後的數字添加到列表中。在這個列表上工作並最終寫入文件。

+0

我希望它能夠在我編輯的編號的位置上正確添加,但這是我的實際問題 –

1

應該是如此簡單:

List<string> myLines = File.ReadAllLines("file.txt").ToList(); 
foreach (string s in myLines) 
{ 
    //whatever you're doing to each line 
} 

File.WriteAllLines("file.txt", myLines); 
+0

請問writeAllLines是否覆蓋舊文件? –

+1

@JohnDemetriou,是的。如果您想保留舊文件,則必須將其備份,或以不同的名稱保存新文件。 – tmoore82