将StreamReader和StreamWriter嵌套在C#中的while循环中

时间:2012-08-29 09:40:35

标签: c# streamreader streamwriter

我正在编写一个代码,其中我有一个文本文件,其中包含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. 一旦将密钥插入表中,就应该从文本文件中删除密钥(行)。
  2. 为此,我想我必须在同一个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',因为它   正在被另一个进程使用。“

    我是否可以在while循环中使用StreamReader和StreamWriter的嵌套。最后,我必须删除刚刚插入表中的行。

    提前致谢,

    Viknesh

2 个答案:

答案 0 :(得分:0)

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

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

在一定大小之后,会占用太多内存,但您可以写入不同的文件,然后将其复制到旧文件上。

我会给出示例,但代码的其他问题意味着我无法弄清楚你在做什么(line总是为空,但正在编写,str永远不会为空但如果是,则进行检查。

答案 1 :(得分:0)

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

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

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

从文件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);
}

希望这段代码可以帮助有同样问题的人。对于我而言,这只是一种替代方法,而不是我查询的解决方案。