C#读取和写入同一文件

时间:2014-05-26 13:12:27

标签: c# file

我正在经历一个循环,对于每次运行我希望打开一个txt / csv文件并搜索循环中分配的值。如果txt文件中存在该值,我希望在该行上写入它。

可以这样做吗?我一直在玩StreamReader和StreamWriter,但从来没有真正成功地读取和写入同一个文件。

我最初尝试过这个,但显然StreamReader使文件"忙碌"因此StreamWriter无法访问它。

private void WriteTempTXT()
{

    StreamReader sr = new StreamReader(@tmpfile);
    StreamWriter sw = new StreamWriter(@tmpfile);

}

有办法做到这一点吗?

3 个答案:

答案 0 :(得分:2)

首先,它可以完成。您可以创建具有读/写访问权限的FileStream,然后直接写入流。这是一个概念证明:

using (var v = new StreamWriter(File.Create("a.txt"))) {
    v.WriteLine("1234A67890");
}

FileStream fs = new FileStream("a.txt", FileMode.Open, FileAccess.ReadWrite);
while (fs.ReadByte() != 'A') {} // Dangerous.  Loops until 'A' found, infinite loop if none.
fs.Position--;
fs.WriteByte((byte)'5');
fs.Close();  // contents of a.txt now 1234567890

然而,这种方法存在许多基本问题:

  1. 文件损坏风险。如果程序崩溃(或停电等),文件可能会处于不一致状态。
  2. 无法始终如一地使用StreamReader / StreamWriter两者都将数据存储在内部缓冲区中,如果正在同时写入和读取基础流,这可能会过时。您可以调用DiscardBufferedData,但MSDN会注意到“此方法会降低性能,只有在绝对必要时才应调用。”
  3. 复杂性。在文件中就地插入文本是一项代价高昂的操作,需要在内存中移动所有后续数据。
  4. 相反,除了压倒性的考虑因素(例如,文件相对于可用存储空间很大),您可能需要考虑这种方法:

    1. 创建一个新的临时文件。 (您可以将System.IO.Path.GetTempFileName()用于此目的)。
    2. 将现有文件读入临时文件,进行必要的更改。 (使用StreamReader读取旧文件,使用StreamWriter写入新文件。)
    3. 使用临时文件覆盖现有文件。
    4. 这种方法在概念上是相似的,但不会产生同时读取和写入同一个流的风险和复杂性。

答案 1 :(得分:1)

写入CSV文件中的一行有两个问题:

  1. 文件不是基于行的。如果新行的编码数据与原始行的字节数完全相同,则只能替换文件中的行。

  2. CSV数据不是基于行的。换行符用作记录分隔符,但由于值也可以包含换行符,因此您无法逐行可靠地读取CSV文件(除非在特殊情况下您确定不会包含任何值新的一行)。

  3. 如果新行的编码数据的长度与旧行的长度不同,则必须重写文件的其余部分,以便为添加的字节腾出空间或删除未使用的字节。

    通常的方法是读取整个文件并将其解析为记录,更改记录,然后将整个文件写回。

答案 2 :(得分:0)

首先,您需要跟进此Example

然后使用类

string path = Server.MapPath("Twitter Overview Report1.csv"); 
    using (CsvFileReader reader = new CsvFileReader(path))
    {
        CsvRow row = new CsvRow();
        while (reader.ReadRow(row))
        {
            foreach (string s in row)
            {
                string s_row = row[0].ToString();
                s_row.Replace("mahmoude", "Ghandour");
            }
            Console.WriteLine();
        }
    }
    using (CsvFileWriter writer = new CsvFileWriter(path))
    {

    }