【问题标题】:Read and write to a file in the same stream读取和写入同一流中的文件
【发布时间】:2016-02-11 12:41:02
【问题描述】:

我正在尝试以一种其他程序无法访问该文件的方式读取和写入同一个文件:

  FileStream fs = new FileStream(filePath, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.None);               
  StreamReader sr = new StreamReader(fs);
  StreamWriter sw = new StreamWriter(fs);
  newString = sr.ReadToEnd() + "somethingNew";
  sw.Write(newString);
  fs.Close();

文件永远不会被写入。如果我调试,我可以看到阅读器设法获取文件的内容,但编写器似乎无法写入文件。什么都没有发生。

我一直在看this question,这似乎和我的一样。但是我无法让它工作。

【问题讨论】:

  • 你遇到了什么错误?
  • Write 之后尝试sw.Flush();
  • StreamReaderStreamWriter 附加到同一个流(只有单个 Position 值)可能会导致各种恶作剧。我会在同一个文件上打开两个流,一个读取和一个写入。
  • 我知道你可能喜欢这种方法,但为什么不以追加模式打开文件,这样它总是会追加到文件中,或者在需要时创建一个新文件?
  • @JoshuaBakker 最好编写一个 Creates the file along with a bool to overwrite / or not 的方法,如果文件存在,则在该方法中写入 / 和或附加相同的东西。我发布了一个简单的工作示例

标签: c#


【解决方案1】:

@EJS 一个简单的静态方法,如果它不存在,你可以使用它来创建一个新文件,如果它存在,你可以写入同一个文件

简单用法

string path = @"C:\SomePath\Name.txt";

if (!System.IO.File.Exists(path))
{
    WriteAndOrAppendText(path, "File Created");
}
else if (System.IO.File.Exists(path))
{
    WriteAndOrAppendText(path, "New Boot.");             
}

private static void WriteAndOrAppendText(string path, string strText)
{
    if (!File.Exists(path))
    {
        using (StreamWriter fileStream = new StreamWriter(path, true))
        {
            fileStream.WriteLine(strText);
            fileStream.Flush();
            fileStream.Close();
        }
    }
    else
    {
        using (StreamWriter fileStream2 = new StreamWriter(path, true))
        {
            fileStream2.WriteLine(strText);
            fileStream2.Flush();
            fileStream2.Close();
        }
    }
}

【讨论】:

  • ifelse中的代码在WriteAndOrAppendText方法中有什么区别?
  • @spender 我完全同意,但这是帮助 OP 理解逻辑流程的快速而肮脏的东西。这样做也可以避免得到infamous File Already in User Error
【解决方案2】:

只需Flush 您对文件的更改,在关闭流之前拥有sw.Flush();。喜欢:

string filePath = "test.txt";
FileStream fs = new FileStream(filePath, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.None);
StreamReader sr = new StreamReader(fs);
StreamWriter sw = new StreamWriter(fs);
newString = sr.ReadToEnd() + "somethingNew";
sw.Write(newString);
sw.Flush(); //HERE
fs.Close();

你可能会看到这个帖子simultaneous read-write a file in C#(打开多个流进行读写)

【讨论】:

  • 还将流包装在 using 语句中将为您调用 Flush()。您还会一眼就知道它们正在被关闭和处理。
  • 添加刷新工作。我之前已经将它包装在使用中,但是没有用。
【解决方案3】:

如上所述 - 只需添加 Flush() 即可强制将流中保存的数据写入文件。在您提到的评论中,您以前使用过“使用”语句,但这没有用。

简单来说,原因如下:

  1. using 语句会自动调用 Flush(),因此您不需要 到。

  2. 当您释放 StreamReader(或 StreamWriter)时 - 例如使用“使用”语句 - 内部流对象也会被释放,并且您会丢失流的句柄。

【讨论】:

    【解决方案4】:

    为了能够创建文件、附加到文件并读取其中的数据,同时仍允许应用程序对其进行写入,我相信您正在尝试这样做,这是我创建的设置:

        string path = @"C:\SomePath\MyLogFile.txt";
    
        public static string Log(string Message)
        {
            try
            {
                if (File.Exists(path) == false)
                    File.Create(path).Close();  // need this .Close()!!!
    
                logCounter++;
                string logString = logCounter + "   " + DateTime.Now.ToShortDateString() + " " + DateTime.Now.ToShortTimeString() + ": " + Message + Environment.NewLine;
    
                using (FileStream fs = new FileStream(path, FileMode.Append, FileAccess.Write, FileShare.ReadWrite))
                {
                    using (StreamWriter sw = new StreamWriter(fs))
                    {
                        sw.Write(logString);
                    }
                }
    
                return logString; // only necessary so we can return an error in the Exception block
            }
            catch (Exception ex)
            {
                return "Logger:  Cannot log data. " + ex.ToString();
            }
        }
    

    如果您使用FileMode.Append,实际上需要使用FileAccess.Write - 而不是能够使用FileAccess.ReadWrite - 但我发现这并不重要,因为任何已写入的内容都会被关闭并刷新到文件中,我仍然可以使用这些打开文件并阅读它(它不会被锁定和空白)。我有sw.Write(),因为我有Environment.NewLine,我添加到我的logString,但如果我愿意,我可以完成sw.WriteLine()并删除它。

    一个警告:如果路径很长,File.Exists() 会出现问题 - 不记得限制,但只知道有一个限制,所以不要将您正在写入的文件放入多层深度。越少越好。

    【讨论】:

      猜你喜欢
      • 2019-03-04
      • 1970-01-01
      • 1970-01-01
      • 2011-03-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多