思路:
文本文件不能隨意穿插信息,但是通過使用Seek()方法,可以在讀取文本文件中移動光標從而修改所要修改的行.
思路步驟:
1、讀取文件,打開csv文件,獲取文件流,seek移動光標到開始, for循環尋找出字符“\r\n”,運用兩個變量鎖定要修改的行數
2、第二個變量鎖定后,將后面不修改部分保存到緩存區
2、移動到鎖定的位置重寫改行數據——實現修改該行的目標,然后重新寫入緩存區的不變內容。
下面提供覆蓋式修改csv文件的示例代碼:
/// <summary> /// 在csv文件某行中覆蓋重寫 /// </summary> /// <param name="strFilePath">文件路徑</param> /// <param name="rowNumber">修改的行數(不包含0)</param> /// <param name="str">覆蓋的內容</param> /// <returns></returns> public static bool csv_rowWrite(string strFilePath, int rowNumber, string str) { try { if (!File.Exists(strFilePath)) { MessageBox.Show("讀取的文件不存在!!"); return false; } else if (rowNumber <= 0) { MessageBox.Show("該方法不能修改第" + rowNumber + "行"); return false; } using (FileStream fs = new FileStream(strFilePath, FileMode.Open)) { fs.Seek(0, SeekOrigin.Begin); //查找2個換行符位置 //p1定位<修改行的前一個換行符>后一個字節,p2定位<修改行的后一個換行符>后一個字節,用於定位后面的內容緩存到一個緩沖區 long p1 = -1, p2 = -1; var last = 0; //記錄換行符個數 int rowNum = 0; for (int i = 0; i < fs.Length; ++i) { if (rowNumber == 1) { p1 = 0; var c = fs.ReadByte(); if (last == '\r' && c == '\n') { p2 = fs.Position; break; } last = c; } else { var c = fs.ReadByte(); if (last == '\r' && c == '\n') { rowNum++; if (rowNum == rowNumber - 1 || rowNum == rowNumber) { if (p1 == -1) { p1 = fs.Position; } else { p2 = fs.Position; break; } } } last = c; } } //未找到行 if (p1 == -1) { MessageBox.Show("路徑文件" + strFilePath + "中,第" + rowNumber + "行不存在數據"); return false; } //第二個換行符之后的內容,如果是超大文件,分批緩存,避免內存占用過多 var sr = new StreamReader(fs); //流的當前位置是p2,保存后半部分不修改的內容到緩存區end var end = sr.ReadToEnd(); //重新寫入第一個標記點之后的內容 fs.Seek(p1, SeekOrigin.Begin); fs.SetLength(p1); var sw = new StreamWriter(fs); sw.WriteLine(str); sw.Write(end); sw.Flush(); return true; } } catch (Exception ex) { MessageBox.Show("異常:\n" + ex.Message); return false; } }
靈活運用光標位置p1,p2可以實現追加內容的效果。
