使用StreamReader& Writer在同一个Textfile上

时间:2017-02-10 15:40:35

标签: c# streamreader streamwriter

我最近遇到了一个问题,我无法找到适合我需求的解决方案。所以我试图逐行读取文本文件,并检查该行是否是一个特定的字符串。如果文件不包含该字符串,则应将其写入文件。这是我目前的问题。

if ($credentials_file = checkServiceAccountCredentialsFile()) {
  // set the location manually
  $client->setAuthConfig($credentials_file);
} elseif (getenv('GOOGLE_APPLICATION_CREDENTIALS')) {
  // use the application default credentials
  $client->useApplicationDefaultCredentials();
} else {
  echo missingServiceAccountDetailsWarning();
  return;
}
$client->setSubject('j******@gmail.com');
$client->setScopes(['https://www.googleapis.com/auth/drive']);
$service = new Google_Service_Drive($client);
$files = $service->files->listFiles();

我已经读过有关同时读取和写入文件的问题,但我想知道是否有办法实现这一目标。任何帮助表示赞赏!

3 个答案:

答案 0 :(得分:1)

使用FileStream并将它用于StreamReader和StreamWriter,下面是添加或更改textFile行的示例:

public static void ChangeOrAddLine(string filePath, string newLine, string oldLine = "")
{
    using (FileStream fs = new FileStream(filePath, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.Read))
    using (StreamReader sr = new StreamReader(fs))
    using (StreamWriter sw = new StreamWriter(fs))
    {
        List<string> lines = sr.ReadToEnd().Split(new string[] { "\r\n" }, StringSplitOptions.None).ToList();
        fs.Position = 0;
        bool lineFound = false;
        if (oldLine != "")
            for (int i = 0; i < lines.Count; i++)
                if (lines[i] == oldLine)
                {
                    lines[i] = newLine;
                    lineFound = true;
                    break;
                }
        if (!lineFound)
            lines.Add(newLine);
        sw.Write(string.Join("\r\n", lines));
        fs.SetLength(fs.Position);
    }
}

FileAccess.ReadWrite打开文件进行读写

FileShare.Read让其他程序也可以阅读

答案 1 :(得分:1)

请注意,您当前的方法效率非常低,需要您的代码从磁盘读取文件以搜索每个字符串。

您将无法使用两个不同的流同时读取和写入同一文件,就像您尝试的那样。以下是我建议的一些策略,不知道更多:

  1. 如果文件很小,请将while文件加载到List中,然后关闭阅读器。然后,您可以在列表中搜索每个字符串:

    if(!list.Any(write))
        // Write the string to the file  
    

    这将非常快,因为列表在内存中并且文件只读一次(假设它相当小 - 比如说&lt; 5000行,虽然它也适用于更大的文件)。

  2. 另一种方法是将缺少的字符串添加到List中,一旦识别出所有缺少的字符串,请关闭阅读器并使用writer添加字符串。这仍然是低效的,因为您正在为每次查找读取文件(可能很大),所以

  3. 此方法的一个改进是读取文件,并针对您可能要添加的所有行检查每一行。这意味着您只需阅读一次文件并浏览每行的播放列表集合,这将更有效,因为它在内存中。假设你只有几行你正在检查 - 比如你要添加的一些新歌,这会多次提高效率。

  4. 如果文件变得非常大,您可能需要某种索引查找方法。

答案 2 :(得分:1)

未建议的另一个选项是在原始文件上打开阅读器,即临时文件上的编写者。从原始写入读取临时文件并添加缺少的行,然后用临时文件替换原始文件。