0

I get a random line from file:

using (FileStream ifs = new FileStream(path, FileMode.Open, FileAccess.Read)) {
    using (StreamReader sr = new StreamReader(ifs, Encoding)) {
        long lastPos = ifs.Seek(0, SeekOrigin.End);
        long rndPos = 0;
          do {
              rndPos = (long)(Random.NextDouble() * lastPos);// Random is property
              ifs.Seek(rndPos, SeekOrigin.Begin);
              sr.ReadLine();
              line = sr.ReadLine();
          } while (string.IsNullOrWhiteSpace(line));
    }
}

But sometimes it turns out that the line is always null and loop is infinite. Please, where am I wrong?

This function is called 1000 times (for example). The first 100 calls are successful, but then the position of the main stream is the last position, and seek not worked.

ps: I want to get a random position in the file. Then read through the line on which this position to the end and return as result the following line. It is the fastest algorithm to obtain a random string of a large file in a loop. And yes, I know that this function never returns the first row.

Slovo
  • 212
  • 2
  • 11
  • `while (string.IsNullOrWhiteSpace(line));` does look like a dangerous way to go.. have a look here http://stackoverflow.com/questions/3745934/read-random-line-from-a-file-c-sharp – Najzero Feb 14 '13 at 06:59
  • Can you please explain what you expect from your code? Randomly reading values from a file do not guarantee your loop to terminate irrespective of your condition on the string... – Alexei Levenkov Feb 14 '13 at 06:59
  • I would assume when the file is empty you would never find a row and will be searching for any random content – Boas Enkler Feb 14 '13 at 07:02
  • 1
    ... or if there's only a single line in the file. Your code would *never* return the first line of the file, because you always read two lines. – Jon Skeet Feb 14 '13 at 07:03
  • Najzero, this solution does not fit, I call this many times. – Slovo Feb 14 '13 at 07:03
  • Boas Enkler, Jon Skeet, thank you, I know. – Slovo Feb 14 '13 at 07:07
  • Alexei Levenkov, I want to get a random position in the file. Then read through the line on which this position to the end and return as result the following line. It is the fastest algorithm to obtain a random string of a large file in a loop. And yes, I know that this function never returns the first row. – Slovo Feb 14 '13 at 07:12
  • Can you show code for "Random is property" - any chance that it looks like `get { return new Random(0);}` ? – Alexei Levenkov Feb 14 '13 at 07:23
  • just put a breakpoint when you get in an infinite loop and _observe_ why it is looping infinitely. – Eren Ersönmez Feb 14 '13 at 07:26
  • @Alexei Levenkov, no.`public static Random Random = new Random();` – Slovo Feb 14 '13 at 07:28
  • @Eren Ersönmez, done. No ideas. – Slovo Feb 14 '13 at 07:28
  • The biggest flaw here is using both the `StreamReader` and underlying stream at the same time. – leppie Feb 14 '13 at 07:34
  • @leppie, I'd vote for "biggest flaw is trying to read string from the middle byte of multibyte UTF8 characters, or odd byte of UTF16". – Alexei Levenkov Feb 14 '13 at 07:39
  • @AlexeiLevenkov: That too, but messing around with the position of a stream while using a reader, is just looking for problems. – leppie Feb 14 '13 at 07:40
  • My problem: this function is called 1000 times (for example). The first 100 calls are successful, but then the position of the main stream is the last position, and seek not worked. – Slovo Feb 14 '13 at 07:46
  • @AlexeiLevenkov in my case it is the best choice. – Slovo Feb 14 '13 at 07:48
  • 1
    This would have all been handy to know **in the question** whereas now, this is becoming a multi-book adventure... – Wim Ombelets Feb 14 '13 at 07:54

2 Answers2

0

Well if the line is null, and your condition says string.IsNullOrWhiteSpace(line), it will be an infinite loop.

petko_stankoski
  • 10,459
  • 41
  • 127
  • 231
  • Why line is null? =) File is not empty, random is realy random every time. May be some feature of the stream? – Slovo Feb 14 '13 at 07:15
  • @Slovo Check this out: http://stackoverflow.com/questions/1450263/c-sharp-streamreader-readline-does-not-work-properly – petko_stankoski Feb 14 '13 at 07:23
0
public string ReturnRandomLine(string path, ref Random r)
{
    string[] lines = File.ReadAllLines(path);
    string randomLine = String.Empty;
    int randomLineNumber;

    do
    {
        randomLineNumber = r.Next(0, lines.Length - 1);
        randomLine = lines[randomLineNumber];
    } while (String.IsNullOrWhiteSpace(randomLine));

    return @"Line #" + randomLineNumber + " " + randomLine;
}
Wim Ombelets
  • 5,097
  • 3
  • 39
  • 55