C#程序能否将文本文件读入内存,然后将该对象传递给需要文件名的方法

本文关键字:对象 方法 文件名 文本 程序 文件 内存 然后 | 更新日期: 2023-09-27 17:59:03

在C#程序中,我通过MySQL.Net连接器的MySqlBulkLoader函数将一个大型文本文件(300mb)导入MySQL数据库。

导入需要相当长的时间,并导致在运行它的Windows 2003 Server上几乎100%的磁盘使用率。为了加快导入速度,该程序现在将大文件拆分为更小的块。

是否可以将小文件块(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 = "";

C#程序能否将文本文件读入内存,然后将该对象传递给需要文件名的方法

内存不是一个文件,所以简短的答案是否定的。替代方案是:

  1. 读取该文件,将其写为临时文件(System.IO.Path.GetTempFileName()是您的朋友,用于指定部分文件的名称),并将该文件名传递给MySqlBulkLoader
  2. 使用"RAM磁盘"工具创建一个基于内存的磁盘,以放置完整300Mb文件的副本,然后将该文件路径传递给MySqlBulkLoader

下面的类接受这是不可能的,并在批量加载之前将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);
                }
            }
        }
    }
}