0

我正在编写一个代码,其中有一个文本文件,其中包含 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 的嵌套。最后,我必须删除刚刚插入到表中的行。

提前致谢,

维克内什

4

2 回答 2

0

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

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

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

我会举个例子,但代码的其他问题意味着我无法完全弄清楚你在做什么(line始终为空,但正在写入,str永远不会为空,但会检查以防万一)。

于 2012-08-29T09:56:34.063 回答
0

我仍然无法对从 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);
}

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

于 2012-08-29T11:51:39.090 回答