将表数据导出到文本文件+ C#+ SQL Server

时间:2011-01-24 01:12:06

标签: c# sql-server bcp

我正在尝试将SQL表数据导出到C#代码中带有“〜”分隔符的文本文件中。 当数据很小时就可以了。当它很大时,它会抛出一个内存不足的例外。

我的代码:

public static void DataTableToTextFile(DataTable dtToText, string filePath)
{
   int i = 0;
   StreamWriter sw = null;

   try
   {
       sw = new StreamWriter(filePath, false); /*For ColumnName's */
       for (i = 0; i < dtToText.Columns.Count - 1; i++)
       {
           sw.Write(dtToText.Columns[i].ColumnName + '~');
       }
       sw.Write(dtToText.Columns[i].ColumnName + '~');
       sw.WriteLine(); /*For Data in the Rows*/

       foreach (DataRow row in dtToText.Rows)
       {
          object[] array = row.ItemArray;
          for (i = 0; i < array.Length - 1; i++)
          {
              sw.Write(array[i].ToString() + '~');
          }
          sw.Write(array[i].ToString() + '~');
          sw.WriteLine();
       }
       sw.Close();
    }
    catch (Exception ex)
    {
       throw new Exception("");
    }
 }

在存储过程或BCP命令中有更好的方法吗?

2 个答案:

答案 0 :(得分:1)

如果没有使用〜分隔符格式的具体原因,您可以尝试使用DataTable WriteXml函数(http://msdn.microsoft.com/en-us/library/system.data.datatable.writexml.aspx

例如:     dtToText.WriteXml( “C:\ data.xml中”)

如果您需要稍后将此文本转换回DataTable,可以使用ReadXml(http://msdn.microsoft.com/en-us/library/system.data.datatable.readxml.aspx

如果你真的需要让现有的代码工作,我可能会尝试以设定的间隔关闭并调用StreamWriter上的Dispose,然后重新打开并附加到现有文本。

答案 1 :(得分:0)

我意识到这个问题已有数年之久,但我最近遇到了类似的问题。解决方案:简而言之,我认为您遇到了Windows大对象堆的问题。相关链接: https://www.simple-talk.com/dotnet/.net-framework/the-dangers-of-the-large-object-heap/

总结上面的文章:当你分配超过85K长的内存块时(如果你的DataTable中的值足够大,这似乎可能发生在你的StreamWriter对象的幕后),它们会进入一个单独的堆,大对象堆(LOH)。 LOH中的内存块通常在其生存期到期时被释放,但堆不会被压缩。最终结果是抛出System.OutOfMemoryException,不是因为实际上没有足够的内存,而是因为在某些时候堆中没有足够的连续内存

如果您正在使用.NET Framework 4.5.1或更高版本(它不能在Visual Studio 2010或以前工作;它可能适用于VS2012),您可以使用此命令:

System.Runtime.GCSettings.LargeObjectHeapCompactionMode = GCLargeObjectHeapCompactionMode.CompactOnce;

此命令强制LOH压缩在下一次垃圾收集时发生。只需将该命令作为函数的第一行;每次调用此函数时都会将其设置为CompactOnce,这将在调用函数后在某个不确定点处导致LOH压缩。

如果你没有.NET 4.5.1,它会变得更加丑陋。问题是内存分配不明确;它最有可能发生在StreamWriter的幕后。尝试不时地调用GC.Collect(),强制进行垃圾收集 - 也许每隔3次调用一次这个函数。

警告:很多人会建议您直接致电GC.Collect()是一个坏主意,会减慢您的申请速度 - 而且他们是对的。我只是不知道更好的方法来处理这个问题。