开发者

randomly select a line in a textfile c# streamreader

开发者 https://www.devze.com 2023-02-09 13:37 出处:网络
Hi I am reading from a text file and would like each line to be put into a seperate variable. From what I remember from my programming classes arrays cannot be dynamic. So if I set 15 arrays, and the

Hi I am reading from a text file and would like each line to be put into a seperate variable. From what I remember from my programming classes arrays cannot be dynamic. So if I set 15 arrays, and the text file has 1000 lines what can I do and how do I implement it.

The thing is only one line will be needed but I want the line to be randomly selected. the linetext is the whole text file with \r\n appended to the end of ev开发者_Python百科ery request.

Maybe randomly select the \r\n then count 4 and add the string after it till the next \r\n. The problem with this idea is the strings getting called will also contain \ so any ideas?

if (crawler == true)
   {
            TextReader tr = new StreamReader("textfile.txt");
            while (tr.Peek() != -1)
            {
                linktext = linktext + tr.ReadLine() + "\r\n";
            }

            //link = linktext;

            hi.Text = linktext.ToString();

            timer1.Interval = 7000; //1000ms = 1sec 7 seconds per cycle
            timer1.Tick += new EventHandler(randomLink); //every cycle randomURL is called.
            timer1.Start(); // start timer.
        }


File.ReadAllLines(...) will read every line of the given file into an array of strings. I think that should be what you want but your question is kind of hard to follow.


You don't need to keep more than two lines in memory at a time... there's a sneaky trick you can use:

  • Create an instance of Random, or take one as a parameter
  • Read the first line. This automatically becomes the "current" line to return
  • Read the second line, and then call Random.Next(2). If the result is 0, make the second line the "current" line
  • Read the third line, and then call Random.Next(3). If the result is 0, make the third line the "current" line
  • ... etc
  • When you reach the end of the file (reader.ReadLine returns null) return the "current" line.

Here's a general implementation for an IEnumerable<T> - if you're using .NET 4, you can use File.ReadLines() to get an IEnumerable<string> to pass to it. (This implementation has a bit more in it than is really needed - it's optimized for IList<T> etc.)

public static T RandomElement<T>(this IEnumerable<T> source,
                                 Random random)
{
    if (source == null)
    {
        throw new ArgumentNullException("source");
    }
    if (random == null)
    {
        throw new ArgumentNullException("random");
    }
    ICollection collection = source as ICollection;
    if (collection != null)
    {
        int count = collection.Count;
        if (count == 0)
        {
            throw new InvalidOperationException("Sequence was empty.");
        }
        int index = random.Next(count);
        return source.ElementAt(index);
    }
    ICollection<T> genericCollection = source as ICollection<T>;
    if (genericCollection != null)
    {
        int count = genericCollection.Count;
        if (count == 0)
        {
            throw new InvalidOperationException("Sequence was empty.");
        }
        int index = random.Next(count);
        return source.ElementAt(index);
    }
    using (IEnumerator<T> iterator = source.GetEnumerator())
    {
        if (!iterator.MoveNext())
        {
            throw new InvalidOperationException("Sequence was empty.");
        }
        int countSoFar = 1;
        T current = iterator.Current;
        while (iterator.MoveNext())
        {
            countSoFar++;
            if (random.Next(countSoFar) == 0)
            {
                current = iterator.Current;
            }
        }
        return current;
    }
}


A List<T> is a dynamically expanding list. You might want to use that instead of an array.

If there is only 1000 elements, just read them into the list and select a random element.


Regarding the array thing.. you could use a List<> instead, which is dynamic

Here is an example of how this can be achieved:

public static string GetRandomLine(ref string file) {
    List<string> lines = new List<string>();
    Random rnd = new Random();
    int i = 0;

    try {
        if (File.Exists(file)) {
            StreamReader reader = new StreamReader(file);
            while (!(reader.Peek() == -1))
                lines.Add(reader.ReadLine());
            i = rnd.Next(lines.Count);
            reader.Close();
            reader.Dispose();
            return lines[i].Trim();
        }
        else {
            return string.Empty;
        }
    }
    catch (IOException ex) {
        MessageBox.Show("Error: " + ex.Message);
        return string.Empty;
    }
}


If you create the file then the ideal way would be to store meta data about the file, like the number of lines, before hand, and then decide which 'random' line to choose.

Otherwise, you cant get around the "array" problem by not using them. Instead use a List which stores any number of strings. After that picking a random one is as simple as generating a random number between 0 and the size of the list.

Your problem has been done before, I recommend googling for "C# read random line from file".

0

精彩评论

暂无评论...
验证码 换一张
取 消