【发布时间】:2012-01-24 14:07:51
【问题描述】:
我觉得问这个问题很尴尬,因为我觉得我应该已经知道了。但是,鉴于我没有......我想知道如何将大文件从磁盘读取到数据库而不会出现 OutOfMemory 异常。具体来说,我需要加载 CSV(或真正的制表符分隔文件)。
我正在尝试CSVReader,特别是this code sample,但我确定我做错了。他们的一些other coding samples 展示了如何读取 any 大小的流文件,这几乎是我想要的(只需要从磁盘读取),但我不知道是什么类型的IDataReader 我可以创建以允许这样做。
我正在直接从磁盘读取,并且我试图通过一次读取太多数据来确保我不会耗尽内存。我不禁想到我应该能够使用BufferedFileReader 或类似的东西,我可以指向文件的位置并指定缓冲区大小,然后CsvDataReader 期望IDataReader 作为它的第一个参数,它可以使用它。请告诉我我的方法的错误,让我摆脱我的GetData 方法及其任意文件分块机制,并帮助我解决这个基本问题。
private void button3_Click(object sender, EventArgs e)
{
totalNumberOfLinesInFile = GetNumberOfRecordsInFile();
totalNumberOfLinesProcessed = 0;
while (totalNumberOfLinesProcessed < totalNumberOfLinesInFile)
{
TextReader tr = GetData();
using (CsvDataReader csvData = new CsvDataReader(tr, '\t'))
{
csvData.Settings.HasHeaders = false;
csvData.Settings.SkipEmptyRecords = true;
csvData.Settings.TrimWhitespace = true;
for (int i = 0; i < 30; i++) // known number of columns for testing purposes
{
csvData.Columns.Add("varchar");
}
using (SqlBulkCopy bulkCopy = new SqlBulkCopy(@"Data Source=XPDEVVM\XPDEV;Initial Catalog=MyTest;Integrated Security=SSPI;"))
{
bulkCopy.DestinationTableName = "work.test";
for (int i = 0; i < 30; i++)
{
bulkCopy.ColumnMappings.Add(i, i); // map First to first_name
}
bulkCopy.WriteToServer(csvData);
}
}
}
}
private TextReader GetData()
{
StringBuilder result = new StringBuilder();
int totalDataLines = 0;
using (FileStream fs = new FileStream(pathToFile, FileMode.Open, System.IO.FileAccess.Read, FileShare.ReadWrite))
{
using (StreamReader sr = new StreamReader(fs))
{
string line = string.Empty;
while ((line = sr.ReadLine()) != null)
{
if (line.StartsWith("D\t"))
{
totalDataLines++;
if (totalDataLines < 100000) // Arbitrary method of restricting how much data is read at once.
{
result.AppendLine(line);
}
}
}
}
}
totalNumberOfLinesProcessed += totalDataLines;
return new StringReader(result.ToString());
}
【问题讨论】:
-
这就是虚拟内存的用途。真正的问题是地址空间。
-
您是否尝试过使用 FileHelpers 类来解析 CSV 数据? filehelpers.com
-
@Kane,不,我不知道。不过看起来还可以。我的文件一开始就有一些元数据,所以它需要迎合这一点。我会看看一些网站,看看它是否有用。谢谢。
标签: sql-server-2005 csv out-of-memory sqlbulkcopy file-processing