【问题标题】:The best and right way to close StreamWriter and StreamReader关闭 StreamWriter 和 StreamReader 的最佳和正确方法
【发布时间】:2017-07-17 18:21:57
【问题描述】:

我一直在尝试整理一段代码,发现它是一团糟!此时的第一个也是我最大的问题是我的 StreamWriters 或 StreamReader 之一处于打开状态。使用this link,我正在尝试组织我的代码。但我的问题是我不确定我应该在哪里关闭它:

我的代码是:

public static void ProcessFile(string[] ProcessFile, int id_customer, string directoryinprocess)
{
    StreamWriter Writer = null, Writer2 = null, Writer3 = null;

    foreach (string filename in ProcessFile)
    {

        // Used for the output name of the file
        var dir = Path.GetDirectoryName(filename);
        var fileName = Path.GetFileNameWithoutExtension(filename);
        var ext = Path.GetExtension(filename);
        var folderbefore = Path.GetFullPath(Path.Combine(dir, @"..\"));
        int rowCount = 0;
        string path_body_out = "";
        string outputname = folderbefore + "output_temp\\" + fileName;

        if (filename.Contains("RO_"))
        {
            Writer = new StreamWriter(dir + "\\" + "output_temp\\" + fileName + "_hd_intermediate" + ext) { AutoFlush = true };
            Writer2 = new StreamWriter(dir + "\\" + "output_temp\\" + fileName + "_body_out" + ext) { AutoFlush = true };
            path_body_out = dir + "\\" + "output_temp\\" + fileName + "_hd_intermediate" + ext;
        } // end of if
        else
        {
            Writer3 = new StreamWriter(dir + "\\" + "output_temp\\" + fileName + "_out" + ext) { AutoFlush = true };
        } // end of else

        using (StreamReader Reader = new StreamReader(@filename))
        {
            while (!Reader.EndOfStream)
            {
                string inputLine = string.Empty;
                inputLine = Reader.ReadLine();

                rowCount++;

                if (filename.Contains("RO_"))
                {
                    if (rowCount <= 4)
                    {
                            Writer.WriteLine(inputLine);
                    }
                    if (rowCount >= 5)
                    {
                        Writer2.WriteLine(inputLine);
                    }
                }
                else
                {
                    { Writer3.WriteLine(inputLine); }
                }

            } // end of the while
        } // end of using Stremreader


        if (path_body_out.Contains("_hd_intermediate"))
        {
            ManipulateHeaderFilesTypeRo(dir, path_body_out);
        }
        else
        { }
    } // end of the foreach


    string[] extensions = { "_fv", "_body", "_out" };

    string[] fileEntriesout = System.IO.Directory.EnumerateFiles(directoryinprocess, "*.csv", System.IO.SearchOption.AllDirectories)
    .Where(file => extensions.Any(ex => Path.GetFileNameWithoutExtension(file).EndsWith(ex)))
        .ToArray();


    foreach (string filenameout in fileEntriesout)
    {
        string destinytablename = null;

        if (filenameout.Contains("_hd_intermediate_fv"))
        { destinytablename = "TBL_DATA_TYPE_RO_HEADER"; }
        else if (filenameout.Contains("_body_out"))
        { destinytablename = "TBL_DATA_TYPE_RO_BODY"; }
        else
        { destinytablename = "TBL_DATA_TYPE_LOAD"; }

        string id_file = Get_id_file(filenameout, id_customer);

        DataTable csvFileData = GetDataTabletFromCSVFile(filenameout, id_file);

        InsertDataIntoSQLServerUsingSQLBulkCopy(csvFileData, destinytablename);

    } // end of the foreach

    //} // end of the foreach

} // end of ProcessFile 
  • 问题: 我应该如何关闭该部分:

        if (filename.Contains("RO_"))
        {
            Writer = new StreamWriter(dir + "\\" + "output_temp\\" + fileName + "_hd_intermediate" + ext) { AutoFlush = true };
            Writer2 = new StreamWriter(dir + "\\" + "output_temp\\" + fileName + "_body_out" + ext) { AutoFlush = true };
            path_body_out = dir + "\\" + "output_temp\\" + fileName + "_hd_intermediate" + ext;
        } // end of if
        else
        {
            Writer3 = new StreamWriter(dir + "\\" + "output_temp\\" + fileName + "_out" + ext) { AutoFlush = true };
        } // end of else
    
        using (StreamReader Reader = new StreamReader(@filename))
        {
            while (!Reader.EndOfStream)
            {
                string inputLine = string.Empty;
                inputLine = Reader.ReadLine();
    
                rowCount++;
    
                if (filename.Contains("RO_"))
                {
                    if (rowCount <= 4)
                    {
                            Writer.WriteLine(inputLine);
                    }
                    if (rowCount >= 5)
                    {
                        Writer2.WriteLine(inputLine);
                    }
                }
                else
                {
                    { Writer3.WriteLine(inputLine); }
    

我应该关闭这里吗?

        if (filename.Contains("RO_"))
        {
            Writer = new StreamWriter(dir + "\\" + "output_temp\\" + fileName + "_hd_intermediate" + ext) { AutoFlush = true };
            Writer2 = new StreamWriter(dir + "\\" + "output_temp\\" + fileName + "_body_out" + ext) { AutoFlush = true };
            path_body_out = dir + "\\" + "output_temp\\" + fileName + "_hd_intermediate" + ext;
        } // end of if
        else
        {
            Writer3 = new StreamWriter(dir + "\\" + "output_temp\\" + fileName + "_out" + ext) { AutoFlush = true };
        } // end of else

还是这里?

                if (filename.Contains("RO_"))
                {
                    if (rowCount <= 4)
                    {
                            Writer.WriteLine(inputLine);
                    }
                    if (rowCount >= 5)
                    {
                        Writer2.WriteLine(inputLine);
                    }
                }
                else
                {
                    { Writer3.WriteLine(inputLine); }
                }

【问题讨论】:

    标签: c#


    【解决方案1】:

    如果您无法重新组织此代码,以便将每个 StreamWriter 实例包装在 using() 中,那么也许您可以执行以下操作:

    StreamWriter Writer = null, Writer2 = null, Writer3 = null;
    
    try
    {
        // your existing code
    }
    catch
    {
        // Handle
    }
    finally
    {
        if (Writer != null)
            Writer.Close();
        if (Writer2 != null)
            Writer2.Close();
        if (Writer3 != null)
            Writer3.Close();
    }
    

    这可确保无论try 中发生什么错误,您的作者都将被关闭。

    在我看来,有条件地实例化对象是一种味道,你应该努力基于filename.Contains("RO_") 来实现不同的实现。您可以使用策略模式并具有不同的文件处理器接口实现,根据文件名选择正确的一个。每个实现只知道如何写入它需要的位置。这将允许您在每个作者周围正确使用using()

    【讨论】:

    • 是的,你做对了!现在它正在工作,我将努力改善这个烂摊子,现在我知道这就是问题所在。谢谢。
    【解决方案2】:

    通常,如果您使用一次性物品,我会说使用using 块。但是,由于您有条件地使一次性对象实例化,我认为使用 try-finally 块将是您最好的选择。

    在 try 块之外声明一次性对象并将它们初始化为 null。

    将一次性对象初始化为您想要在 try 块内的实例。一旦创建了一次性对象,请注意不要在 try 块内的任何地方更改此引用。

    同样在你的 try 块内,对一次性对象做你需要做的一切。

    在你的 try 块之后创建一个 finally 块(catch 块是可选的,但是你需要一个 finally 块才能让这个方法完成它的工作。)并在 finally 块中,检查你声明的变量是否持有一次性对象不为空。如果它们不为空,则关闭它们并使它们为空。

    StreamWriter writer = null;
    
    try {
        if (condA) {
           writer = new StreamWriter("filePath1");
        } else if (condB) {
            writer = new StreamWriter("filePath2");
        } else {
            writer = new StreamWriter("filePath3");
        }
    
        // do things with writer
    
    } catch (Exception ex) {
    
    } finally {
        if (writer != null) {
            writer.close();
            writer = null;
        }
    }
    

    【讨论】:

    • 它也适用于这个选项!谢谢你。抱歉,但我将第一个答案标记为已更正,两者都有效!谢谢。
    猜你喜欢
    • 2016-08-23
    • 1970-01-01
    • 1970-01-01
    • 2013-12-17
    • 2014-03-03
    • 1970-01-01
    • 2012-05-21
    • 1970-01-01
    • 2017-09-07
    相关资源
    最近更新 更多