简体   繁体   English

写入文本文件 C# 时出现问题

[英]Problem writing to a text file C#

Here is my program:这是我的程序:

protected int CheckExisting(string item_id)
{
            StreamReader sr = new StreamReader(@"D:\ItemID.txt");
            string line = sr.ReadLine();

            while (line != null)
            {
                if (0 == string.Compare(line, item_id))
                    return 1;

                line = sr.ReadLine();
            }

            sr.Close();
            return 0;
}

protected void WriteNewLog(string item_id)
{
            using (StreamWriter sw = File.AppendText(@"D:\ItemID.txt"))
            {
                sw.WriteLine(item_id);
            }
}

protected void xHandler(int num)
{
    for(int i= 0; i< num; i++)
        if (0 == CheckExisting(item_id))
        {                       
            WriteNewLog(item_id);
        }
}

When o run the program, an exception unhandled occur: "The process cannot access the file 'D:\ItemID.txt' because it is being used by another process."运行程序时,出现未处理的异常: “进程无法访问文件'D:\ItemID.txt',因为它正被另一个进程使用。” Can u guys help me fix that?你们能帮我解决这个问题吗? Thanks so much!非常感谢!

If this executes:如果执行:

if (0 == string.Compare(line, item_id))
    return 1;

then you won't close your StreamReader .那么你不会关闭你的StreamReader Use a using block when reading as well as writing.在阅读和写作时使用using块。

Additionally:此外:

  • I'd suggest using bool instead of an integer to indicate yes/no results我建议使用bool而不是 integer 来表示是/否结果
  • I'd use a simple equality check instead of calling Compare and checking the results against 0我会使用简单的相等性检查,而不是调用Compare并对照0检查结果
  • If you're using .NET 4, File.ReadLines is a simpler way of reading lines如果您使用的是 .NET 4,则File.ReadLines是一种更简单的读取行的方法
  • LINQ makes it easier to implement CheckExisting to start with LINQ 使实施CheckExisting更容易开始
  • The name xHandler doesn't follow .NET naming conventions名称xHandler不遵循 .NET 命名约定
  • Underscores in parameter names don't follow .NET naming conventions参数名称中的下划线不遵循 .NET 命名约定
  • I would suggest using braces for clarity everywhere, even where they're not strictly necessary为了清楚起见,我建议在任何地方都使用大括号,即使它们不是绝对必要的
  • I would put the constants in comparisons at the end of the comparison instead of at the start;我会在比较结束而不是开始时将常量放在比较中; I believe most people find that more readable我相信大多数人会发现它更具可读性
  • There's no indication that the CheckExisting and WriteNewLog methods need to be protected rather than private没有迹象表明CheckExistingWriteNewLog方法需要保护而不是私有
  • You're not actually using your i variable in xHandler你实际上并没有在xHandler使用你的i变量

Here's the implementation I'd use:这是我要使用的实现:

const string FileName = @"D:\ItemID.txt";

private bool CheckExisting(string itemId)
{
    return File.ReadLines(FileName)
               .Contains(itemId);
}

private void WriteNewLog(string itemId)
{
    using (TextWriter writer = File.AppendText(FileName))
    {
        writer.WriteLine(itemId);
    }
}

// Adjust name appropriately
protected void FooHandler(int num)
{
    for (int i = 0; i < num; i++)
    {
        // Probably use i here somewhere?
        if (!CheckExisting(itemId))
        {
            WriteNewLog(itemId);
        }  
    }    
}

try putting the stream reader in a using so that its dispose is called.尝试将 stream 阅读器放入 using 中,以便调用它的 dispose。

right now your code will return before sr.Close() is called.现在您的代码将在调用 sr.Close() 之前返回。

You are not closing the file when you return 1 from CheckExisting.当您从 CheckExisting 返回 1 时,您没有关闭文件。 Also use the using (StringReader rdr =...) .也使用using (StringReader rdr =...)

Because the file is still locked open by your process, it cannot be opened again.由于该文件仍被您的进程锁定打开,因此无法再次打开它。 That's why you see this Exception: The process cannot access the file 'D:\ItemID.txt' because it is being used by another process .这就是您看到此异常的原因: The process cannot access the file 'D:\ItemID.txt' because it is being used by another process

You should either use using or try/finally to make sure your recourse is closed, in your code the exception is thrown because of return 1;您应该使用usingtry/finally来确保您的追索权已关闭,在您的代码中,由于return 1; the method will exit without closing the stream and so you getting file in use by another process.该方法将在不关闭 stream 的情况下退出,因此您可以让另一个进程使用文件。 example on try/finally try/finally示例

StreamReader sr = new StreamReader(@"D:\ItemID.txt");
try
{
    string line = sr.ReadLine();

    while (line != null)
    {
        if (0 == string.Compare(line, item_id))
            return 1;

        line = sr.ReadLine();
    }
}
finally
{ 
    sr.Close();
}

return 0;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM