1

嗨,我正在从文本文件中读取数据,并希望将每一行放入一个单独的变量中。从我的编程课程中我记得,数组不能是动态的。因此,如果我设置了 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.
        }
4

5 回答 5

4

File.ReadAllLines(...)会将给定文件的每一行读入字符串数组。我认为这应该是你想要的,但你的问题有点难以理解。

于 2011-02-08T18:13:12.547 回答
3

您一次不需要在内存中保留超过两行......您可以使用一个偷偷摸摸的技巧:

  • 创建一个 Random 的实例,或将一个作为参数
  • 阅读第一行。这会自动成为要返回的“当前”行
  • 阅读第二行,然后调用Random.Next(2). 如果结果为 0,则将第二行设为“当前”行
  • 阅读第三行,然后调用Random.Next(3). 如果结果为 0,则将第三行设为“当前”行
  • ... ETC
  • 当您到达文件末尾时(reader.ReadLine返回 null)返回“当前”行。

这是 an 的一般实现IEnumerable<T>- 如果您使用的是 .NET 4,则可以使用File.ReadLines()to get anIEnumerable<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;
    }
}
于 2011-02-08T18:15:33.340 回答
1

AList<T>是一个动态扩展的列表。您可能想使用它而不是数组。

如果只有 1000 个元素,只需将它们读入列表并选择一个随机元素。

于 2011-02-08T18:13:31.840 回答
1

关于数组的事情..你可以使用 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;
    }
}
于 2011-02-08T18:19:04.833 回答
0

如果您创建文件,那么理想的方法是预先存储有关文件的元数据,例如行数,然后决定选择哪个“随机”行。

否则,您无法通过不使用它们来解决“数组”问题。而是使用存储任意数量字符串的列表。之后,选择一个随机数就像生成一个介于 0 和列表大小之间的随机数一样简单。

您的问题之前已经解决过,我建议使用谷歌搜索“C# 从文件中读取随机行”。

于 2011-02-08T18:14:28.887 回答