简体   繁体   English

在同一文本文件上使用StreamReader和Writer

[英]Using StreamReader & Writer on same Textfile

I recently run into an issue i wasn't able to find a solution for, that suits my needs. 我最近遇到了一个问题,我无法找到适合我需求的解决方案。 So I am trying to read a textfile line by line and check if the line is a specific string. 所以我试图逐行读取文本文件,并检查该行是否是一个特定的字符串。 If the file doesn't contain that string yet it should be written to the file. 如果文件不包含该字符串,则应将其写入文件。 This is my current approche on this. 这是我目前的问题。

int i = 0;
using (var sw = new StreamWriter(this.filePath))
{
    foreach (SimplePlaylist playlist in myPlaylists)
    {
        this.PlaylistTracks[i] = new List<PlaylistTrack>();
        this.PlaylistTracks[i] = GetPlaylistTracks(playlist.Owner.Id, playlist.Id);
        foreach (PlaylistTrack tr in this.PlaylistTracks[i])
        {
            string write = tr.Track.Name + " // " + string.Join(",", tr.Track.Artists.Select(source => source.Name)) + " // " + tr.Track.Album.Id;
            string line = "";
            bool found = false;
            using (var sr = new StreamReader(this.filePath))
            {
                while ((line = sr.ReadLine()) != null)
                {
                    if (line.Equals(write))
                    {
                        found = true;
                        break;
                    }
                }
                sr.Close();
            }
            if (!found)
            {
                sw.WriteLine(write);
            }
        }
        i++;
    }
    sw.Close();
}

I've read about the problematic of reading and writing to a file at the same time, but i'm wondering if there is a way to achieve this. 我已经读过有关同时读取和写入文件的问题,但我想知道是否有办法实现这一目标。 Any help is appreciated! 任何帮助表示赞赏!

Use a FileStream and use it for both, StreamReader and StreamWriter, here is an example of adding or changing lines of a textFile: 使用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 opens the File for reading and writing FileAccess.ReadWrite打开文件进行读写

FileShare.Read let the be read by other programs as well FileShare.Read让其他程序也可以阅读

Be aware that your current approach is very inefficient, requiring your code to read through the file from disk to search for every string. 请注意,您当前的方法效率非常低,需要您的代码从磁盘读取文件以搜索每个字符串。

You are not going to be able to read and write to the same file at the same time with two different streams like you are attempting to do. 您无法像使用两种不同的流一样同时读取和写入同一文件。 Here are a couple of strategies I suggest without knowing more: 以下是我建议的一些策略,不知道更多:

  1. If the file is small, load the while file into a List, and close the reader. 如果文件很小,请将while文件加载到List中,然后关闭阅读器。 You can then search the list for each string: 然后,您可以在列表中搜索每个字符串:

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

    This will be pretty fast, as the list is in memory and the file is read only once (provided it is fairly small - say < 5000 lines, though it will also work on much larger files). 这将非常快,因为列表在内存中并且文件只读取一次(前提是它相当小 - 比如说<5000行,但它也适用于更大的文件)。

  2. Another approach is to add the missing strings to a List and once you have identified all missing strings, close the reader and use the writer to add the strings. 另一种方法是将缺少的字符串添加到List中,一旦识别出所有缺少的字符串,关闭阅读器并使用writer添加字符串。 This will still be inefficient, because you are reading the through the file (which may be large) for every lookup, so 这仍然是低效的,因为您正在为每次查找读取文件(可能很大),所以

  3. A refinement of this approach is to Read through the file and check each line against all the lines you might want to add. 这种方法的改进是读取文件,并针对您可能想要添加的所有行检查每一行。 This means you only read the file once and run through your playlist collection for each line, which will be more efficient because it is in memory. 这意味着您只需阅读一次文件并浏览每行的播放列表集合,这将更有效,因为它在内存中。 Assuming you only have a few lines you are checking for - say for some new songs which you are adding, this will improve efficiency many times. 假设你只有几行你正在检查 - 比如你要添加的一些新歌,这将提高效率很多倍。

If the file gets really large you probably need some kind of index lookup approach. 如果文件变得非常大,您可能需要某种索引查找方法。

Another option not suggested is to open the reader on the original file, a writer on a temp file. 不建议的另一个选项是打开原始文件上的阅读器,即临时文件上的编写者。 Read from the original write to the temp file and add the missing lines, then replace the original file with the temp file. 从原始写入临时文件读取并添加缺少的行,然后用临时文件替换原始文件。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM