私はすでに知っているべきだと思うので、この質問をするのは恥ずかしいです. ただし、私はそうではありません.... OutOfMemory例外を発生させずに、ディスクからデータベースに大きなファイルを読み取る方法を知りたいです。具体的には、CSV (または実際にはタブ区切りファイル) を読み込む必要があります。
私はCSVReader
特にこのコードサンプルを試していますが、間違っていると確信しています。彼らの他のコーディング サンプルのいくつかは、任意のサイズのストリーミング ファイルを読み取る方法を示しています。これは、私が望んでいるものです (ディスクから読み取る必要があるだけです) IDataReader
。
私はディスクから直接読み込んでいますが、一度に大量のデータを読み込んでメモリ不足にならないようにする試みを以下に示します。BufferedFileReader
ファイルの場所を指定してバッファサイズを指定し、最初のパラメータとしてa をCsvDataReader
期待できる a または同様のものを使用できるはずだと考えずにはいられません。それを使用することができます。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());
}