【问题标题】:Nesting of StreamReader and StreamWriter inside a while loop in C#在 C# 的 while 循环中嵌套 StreamReader 和 StreamWriter
【发布时间】:2012-08-29 09:40:35
【问题描述】:

我正在编写一个代码,其中我有一个文本文件,其中包含 10000 多行唯一键(每个键在一个新行中)。我需要将密钥与我提供的 ProductID 和 ProductFeatures 一起插入到表中。

我通过使用以下代码来实现这一点,该代码检查表中已经存在的键并减少键的冗余(表中没有键会出现两次)。

public void reader(string productid,string productfeature)
{
    con.Open();
    using (StreamReader sr = new StreamReader(Server.MapPath("keys.txt")))
    {
        while(sr.Peek() >=0)
        {
            string str = sr.ReadLine();
            SqlCommand cmd = new SqlCommand("select count(newkey) from serialkey where newkey ='"+str.ToString()+"'", con);
            int keyvalue = Convert.ToInt32(cmd.ExecuteScalar());
            if (keyvalue == 0)
            {
                com = new SqlCommand("insert into SerialKey (productid,productfeatures,newkey) values ('" + productid.ToString() + "','" + productfeature.ToString() + "','" + key + "')", con);
                com.ExecuteNonQuery();
            }
        }
    }
    con.Close();
}

这段代码对我来说绝对没问题,但是我决定在这个过程中做一些修改。

  1. 只要将键插入表中,就应该从文本文件中删除键(行)。

为此,我想我必须在同一个 while 循环中使用 StreamWriter/Textwriter,所以我尝试使用此代码。

using (StreamReader sr = new StreamReader(Server.MapPath("keys.txt")))
{
    while (sr.Peek() >= 0)
    {
        string str = sr.ReadLine();
        SqlCommand cmd = new SqlCommand("select count(newkey) from serialkey where newkey ='" + str.ToString() + "'", con);
        int keyvalue = Convert.ToInt32(cmd.ExecuteScalar());

        if (keyvalue == 0)
        {
            string line = null;
            sr.Close();
            TextWriter writer = new StreamWriter(Server.MapPath("keys.txt"), true);
            if (insert(productid, productfeature, str))
            {
                if (str != null)
                {
                    writer.WriteLine(line);
                }
                writer.Flush();
                writer.Close();
            }                    
        }
    }
}

我认为我使用了正确的逻辑来删除已插入的行。 如果我保留这行代码

sr.Close();

我收到以下错误

“无法从关闭的 TextReader 中读取。”

如果我删除该行

sr.Close();

我得到了错误

"进程无法访问文件'myfolderpath\keys.txt',因为它 正在被另一个进程使用。”

我可以在 whileloop 中使用 StreamReader 和 StreamWriter 的嵌套吗?最后,我必须删除刚刚插入到表中的行。

提前致谢,

维克内什

【问题讨论】:

  • 为什么需要在循环中“删除”该行,如果您只是根据插入的键在末尾重写文件,它会不会更有效并且更不容易出错?顺便说一句,你应该使用using-statement 来处理方法中的连接,如果这是 ASP.NET 的话。

标签: c# streamreader streamwriter


【解决方案1】:

问题归结为在您阅读文件时写入文件。

低于某个最大可能文件大小,最简单的方法是首先将整个内容读入内存,这样您就有了一个可以使用的行列表。只需添加将保留到列表中的行,并在关闭阅读器后写入。

达到一定大小后,会占用过多内存,但您可以写入其他文件,然后将其复制到旧文件上。

我会给出示例,但代码的其他问题意味着我无法完全弄清楚您在做什么(line 始终为 null,但正在写入,str 永远不会为 null,但已签入就是这样)。

【讨论】:

  • 这里我只是试图将空值写入文本文件中存在键的特定位置。 Str 只不过是存储在字符串中的键值。
  • null 对文本作者没有任何作用。我看不出str 如何不再是ReadLine() 的值,它不为空。 line 但是始终为空,因此您打开要附加到的流(在末尾添加内容),然后什么也不做。或者,如果您将其打开为未附加,则末尾将有一个零字节文件。
  • 是我想做的事。如果keys.txt文件里面没有任何东西,它不会打扰我。即使它的零字节对我来说没问题。换句话说,我可以说我只想用空值替换包含我的键的行。
【解决方案2】:

我仍然无法对从 keys.txt 文件中获取内容的方法进行排序,然后将密钥插入到我的表中,然后从 keys.txt 文件中删除行(其中存在密钥)。 一旦将特定的键插入表中,就应该从 txt 文件中删除一个键,但不知何故,我以另一种方式排序,但我认为它的效率不够。

在这里,我获取所有键并将它们存储在一个数组中,然后使用 foreach 循环将它们插入,然后清除 txt 文件的内容。

但由于性能问题,我仍然更喜欢前一种方法。然而任何人都可以尝试这段代码。

从文件 keys.txt 中获取 3000 行密钥然后将它们插入表中的时间延迟大约需要 8 秒。

我仍然在以下几行中引用源代码

using (StreamReader sr = new StreamReader(Server.MapPath("keys.txt")))
    {

        string keys = sr.ReadToEnd();
        string[] allkeys = Regex.Split(keys, "\r\n");
        foreach (string values in allkeys)
        {
            SqlCommand cmd = new SqlCommand("select count(newkey) from serialkey where newkey ='" + values.ToString() + "'", con);
            int keyvalue = Convert.ToInt32(cmd.ExecuteScalar());

            if (keyvalue == 0)
            {
                com = new SqlCommand("insert into SerialKey (productid,productfeatures,newkey) values ('" + productid.ToString() + "','" + productfeature.ToString() + "','" + key + "')", con);
                com.ExecuteNonQuery();
            }

        }
        sr.Close();
        File.WriteAllText(Server.MapPath("keys.txt"), string.Empty);
}

希望这段代码可以帮助遇到同样问题的人。这对我来说只是另一种方式,而不是我的查询的解决方案。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-10-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-11-02
    • 1970-01-01
    相关资源
    最近更新 更多