【问题标题】:How to read a line and write to that line, of a text file?如何读取文本文件的一行并写入该行?
【发布时间】:2018-02-15 18:36:37
【问题描述】:

我正在使用 MS-Visual Studio 2015,用 C# 开发一个 Winforms 应用程序。

我想要达到的是一个读写器,它使用 UTF-8 编码打开一个 CSV 文件,并逐行读取。我的程序实际上读取了一行,将其拆分为分号 (;) 并将该信息发送到我的数据库。 现在它应该通过附加文本或特殊符号将该行标记为已读,例如(“阅读”或“完成”或“§$%”)。

因为某人或某物(ERP 系统)可能会将新数据附加到该 CSV 文件中。因此,下次我的程序遍历该文件时,它只会读取没有我的特殊标记的行。

我的程序:

foreach (string sFile in Directory.GetFiles(sImportPfad, "*.*", SearchOption.TopDirectoryOnly))
{
    var oStream = new FileStream(sFile, FileMode.Append, FileAccess.Write, FileShare.Read);
    var iStream = new FileStream(sFile, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);

    var sw = new System.IO.StreamWriter(oStream);
    var sr = new System.IO.StreamReader(iStream);
    int c = 0;

    //  alle Zeilen jedes Files laden
    while (!sr.EndOfStream)
    {
        String line = sr.ReadLine();
        String[] splitLine = line.Trim().Split(txtDivider.Text.Trim().ToCharArray());

        if (line.Contains("§$%"))
            break;

        DatenbankEintragAuftragsPool dbEintrag = new DatenbankEintragAuftragsPool();

             foreach (myImportFilterObject ob in arrImportFilterObjects)
             {
             .
             .
             .
             }

        String result = Program.myPaletti.AuftragInDieDatenbankSchreiben(dbEintrag);

        if (result.Equals("ok"))
        {
            sw.WriteLine(line + "   §$%"); sw.Flush();
        }
    }
}

我的问题是作者将行+“特殊标记”附加到我的文件末尾。

另外,我不知道如何使用 UTF-8 编码读取文件。

感谢您的回答!!

编辑:##############

这段代码可以解决问题...

string[] lines = System.IO.File.ReadAllLines("test");
lines[0] = lines[0] + " $%&";   /* replace with whatever you need */
System.IO.File.WriteAllLines("test", lines);

但就我的使用而言,不建议阅读所有行,因为这些人有可能在接下来的 20 年内永远不会删除任何数据。

我会进一步逐行寻找解决方案...

【问题讨论】:

  • 您可以创建一个 StreamReader,其编码类似于 new StreamReader(stream, Encodiing.UTF8)。但是你不能在文件中间添加一些东西,但是你可以覆盖数据。但也许最好保存您尚未读取的第一条记录的位置(在文件中),因为您的编写器仅将数据附加到文件中
  • @Casperah:我想保存第一个未读行的位置有点不一致。如何覆盖特殊位置的数据?
  • 读取整个文件,更改要更改的行(在内存中),写回文件。如果文件太大而无法一口气读入内存,请一次读取一行并将该行写回新文件,然后再继续下一行
  • 您能否读取并覆盖文件中的所有行,例如here?此外,您可以使用this 构造函数在StreamReaderStreamWriter 上设置编码。
  • 此外,您不能写入正在读取的同一文本文件。您也许可以诱使类同时打开文件进行读取和写入,但我可以向您保证,如果您做自己想做的事情,您将破坏您的文件。

标签: c# csv filestream streamreader streamwriter


【解决方案1】:

我现在的解决方案是创建一个新文件,写入这个文件,删除原始文件并重命名新文件。

        foreach (string sFile in Directory.GetFiles(sImportPfad, "*.*", SearchOption.TopDirectoryOnly))
        {
            FileStream iStream;
            try
            {
                using (iStream = new FileStream(sFile, FileMode.Open, FileAccess.Read, FileShare.None))
                {
                    var sr = new System.IO.StreamReader(iStream, Encoding.UTF8);

                    if (rbCSVfilesMarkieren.Checked)
                    {
                        using (var oStream = new FileStream(sFile + "_new", FileMode.Create, FileAccess.Write, FileShare.None))
                        {
                            var sw = new System.IO.StreamWriter(oStream, Encoding.UTF8);
                            int c = 0;

                            while (!sr.EndOfStream)
                            {
                                String line = sr.ReadLine();
                                String[] splitLine = line.Trim().Split(txtDivider.Text.Trim().ToCharArray());

                                if (line.Contains("$$$"))
                                {
                                    sw.WriteLine(line);
                                    sw.Flush();
                                    continue;
                                }

                                String result = Program.myPaletti.Irgendwasneues(splitLine, arrImportFilterObjects);

                                if (result.Equals("ok"))
                                {
                                    sw.WriteLine(line + "$$$");
                                    sw.Flush();
                                    anzNeueDatensätze++;
                                }
                            }
                        }
                    }

                    System.IO.File.Delete(sFile);
                    System.IO.File.Move(sFile + "_new", sFile);

                }
            }
        }

我还加入了 UTF-8 编码。 此外,我找到了一种方法来阻止我正在读/写的文件,方法是使用 FileShare.None.

谢谢大家的帮助!!我很感激!

【讨论】:

    【解决方案2】:

    您的代码中存在一些问题,我将在此处尝试解决

    using(var stream = new FileStream(sFile, FileMode.Open, FileAccess.Read)
    using(var reader = new StreamReader(stream, Encoding.UTF8))
    {
        long position = GetFirstNewRecordOfFile(sFile);
        stream.Seek(position, SeekOrigin.Begin);
        while(!reader.EndOfStream)
        {
            var line = reader.ReadLine();
            // Process line 
        }
        SaveFirstNewRecordOfFile(sFile, stream.Position);
    }
    

    现在你只需要弄清楚在哪里以及如何保存文件的位置。

    如果您有一个将数据附加到文件的写入器,则文件可能会随着时间的推移而变得很大,那么在读取文件时截断或删除文件可能会更好。 我建议删除该文件,因为您不必遍历很多空文件,但是这将要求您在处理文件之前重命名/移动文件,以避免编写器进程在您关闭它之后但在您之前将数据附加到它删除它。 如果您只是将文件移动到子文件夹,则可以将其用作备份。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-08-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-10-07
      • 2012-05-24
      相关资源
      最近更新 更多