случайным образом выбрать строку в текстовом файле c # streamreader - PullRequest
1 голос
/ 08 февраля 2011

Привет, я читаю из текстового файла и хотел бы, чтобы каждая строка помещалась в отдельную переменную.Из того, что я помню из моих классов программирования, массивы не могут быть динамическими.Итак, если я установил 15 массивов, а текстовый файл содержит 1000 строк, что я могу сделать и как это реализовать.

Дело в том, что потребуется только одна строка, но я хочу, чтобы линия была выбрана случайным образом.linetext - это весь текстовый файл с \ r \ n, добавляемым в конце каждого запроса.

Возможно, случайным образом выберите \ r \ n, затем посчитайте 4 и добавьте строку после него до следующего \ r \ n.Проблема с этой идеей в том, что вызываемые строки также будут содержать \ так что, какие-либо идеи?

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.
        }

Ответы [ 5 ]

4 голосов
/ 08 февраля 2011

File.ReadAllLines (...) будет считывать каждую строку данного файла в массив строк. Я думаю, что это должно быть то, что вы хотите, но ваш вопрос довольно трудно понять.

3 голосов
/ 08 февраля 2011

Вам не нужно хранить более двух строк в памяти одновременно ... есть хитрый прием, который вы можете использовать:

  • Создайте экземпляр Random или возьмите его в качествепараметр
  • Читать первую строку.Это автоматически становится «текущей» строкой для возврата
  • Прочитайте вторую строку и затем вызовите Random.Next(2).Если результат равен 0, сделайте вторую строку «текущей» строкой
  • Прочитайте третью строку и затем вызовите Random.Next(3).Если результат равен 0, сделайте третью строку "текущей" строкой
  • ... и т. Д.
  • Когда вы достигнете конца файла (reader.ReadLine возвращает ноль), верните "текущий""line.

Вот общая реализация IEnumerable<T> - если вы используете .NET 4, вы можете использовать File.ReadLines(), чтобы получить IEnumerable<string> для передачи на него.(В этой реализации немного больше, чем нужно - она ​​оптимизирована для IList<T> и т. Д.)

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;
    }
}
1 голос
/ 08 февраля 2011

Относительно массива .. вы можете использовать вместо него List <>, который является динамическим

Вот пример того, как этого можно достичь:

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;
    }
}
1 голос
/ 08 февраля 2011

A List<T> - это динамически расширяющийся список.Возможно, вы захотите использовать его вместо массива.

Если имеется только 1000 элементов, просто прочитайте их в список и выберите случайный элемент.

0 голосов
/ 08 февраля 2011

Если вы создадите файл, то идеальным способом будет сохранить метаданные о файле, например количество строк, перед рукой, а затем решить, какую «случайную» строку выбрать.

В противном случае,Вы не можете обойти проблему «массива», не используя их.Вместо этого используйте список, который хранит любое количество строк.После этого выбрать случайный случай так же просто, как сгенерировать случайное число в диапазоне от 0 до размера списка.

Ваша проблема уже была решена ранее, я рекомендую поискать "C # прочитать случайную строку из файла".1005 *

...