2017-07-17 108 views
1

我一直在试图组织一个代码,它是一团糟!在这一点上,第一个也是我最大的问题是我的StreamWriters或StreamReader中的一个保持打开状态。使用this link,我试图组织我的代码。但我的问题是,我不知道我应该关闭它:关闭StreamWriter和StreamReader的最佳和正确的方法

我的代码是:

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); } 
       } 

回答

5

如果让每一位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(); 
} 

这保证了无论什么错误(s)在try内发生,您的作者将被关闭。

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

+0

是的,你去吧!现在它正在工作,我会努力改善这个混乱,现在我现在认为这是问题所在。谢谢。 –

1

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

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

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

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

在你的try块之后创建一个finally块(一个catch块是可选的,但是你需要一个finally块来完成它的工作)和finally块内部,检查你声明的变量是否保存了一次性对象不为null。如果它们不为null,则关闭它们并使它们为空。

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; 
    } 
} 
+0

它也适用于这个选项!谢谢。对不起,但我标记为纠正了第一个答案,两个工作!谢谢。 –

相关问题