在C#程序中,我通过MySql .Net Connector的MySqlBulkLoader函数将一个大文本文件(300mb)导入MySQL数据库。
导入需要相当长的时间,并且在运行的Windows 2003 Server上导致几乎100%的磁盘使用率。为了加快导入速度,程序nows将大文件拆分为更小的块。
是否可以将小文件块(8mb)读入内存(即数组),然后将其作为文件传递给MySQLBulkLoader?
批量加载程序查找文件名路径:
MySql.Data.MySqlClient.MySqlBulkLoader myBulk = new MySql.Data.MySqlClient.MySqlBulkLoader(connection);
myBulk.Timeout = 10 * 60; /
myBulk.TableName = "some_table";
myBulk.Local = true;
myBulk.LineTerminator = @"\n";
myBulk.FileName = aFile.FullName;
myBulk.FieldTerminator = "";
答案 0 :(得分:1)
内存不是文件,所以简短的回答是否定的。替代方案是:
System.IO.Path.GetTempFileName()
是您的朋友,提供部分文件的名称)并将该文件名传递给MySqlBulkLoader 答案 1 :(得分:0)
以下类接受它是不可能的,并在批量加载之前将DataTable
写入磁盘。
它可能并不适合所有情况,但它符合我当时的需要。
using MySql.Data.MySqlClient;
using System.Data;
using System.IO;
using System.Text;
namespace ImportDatabase
{
class DataTableToMySql
{
public MySqlConnection Connection { get; set; }
public DataTable SourceDataTable { get; set; }
public string FieldTerminator { get; set; }
public string LineTerminator { get; set; }
public DataTableToMySql(MySqlConnection conn, DataTable table)
{
FieldTerminator = "\t";
LineTerminator = "\n";
Connection = conn;
SourceDataTable = table;
}
public void Execute()
{
string fileName = Path.GetTempFileName();
try
{
byte[] fieldTerm = Encoding.UTF8.GetBytes(FieldTerminator);
byte[] lineTerm = Encoding.UTF8.GetBytes(LineTerminator);
PrepareFile(fileName, fieldTerm, lineTerm);
LoadData(fileName);
}
finally
{
File.Delete(fileName);
}
}
private void LoadData(string fileName)
{
MySqlBulkLoader bl = new MySqlBulkLoader(Connection);
bl.FieldTerminator = FieldTerminator;
bl.LineTerminator = LineTerminator;
bl.TableName = SourceDataTable.TableName;
bl.FileName = fileName;
bl.Load();
}
private void PrepareFile(string fileName, byte[] fieldTerm, byte[] lineTerm)
{
using (FileStream fs = new FileStream(fileName, FileMode.Append))
{
foreach (DataRow row in SourceDataTable.Rows)
{
int i = 0;
foreach (object val in row.ItemArray)
{
byte[] bytes;
if (val is DateTime)
{
DateTime theDate = (DateTime)val;
string dateStr = theDate.ToString("yyyy-MM-dd HH:mm:ss");
bytes = Encoding.UTF8.GetBytes(dateStr);
}
else
bytes = Encoding.UTF8.GetBytes(val.ToString());
fs.Write(bytes, 0, bytes.Length);
i++;
if (i < row.ItemArray.Length)
fs.Write(fieldTerm, 0, fieldTerm.Length);
}
fs.Write(lineTerm, 0, lineTerm.Length);
}
}
}
}
}