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

发布于 2024-11-15 09:09:18 字数 610 浏览 1 评论 0原文

在 C# 程序中,我通过 MySql .Net Connector 的 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 = "";

In a C# program I am importing a large text file (300mb) into a MySQL database via the MySqlBulkLoader function of the MySql .Net Connector.

The import takes quite a long time and results in almost 100% disk usage on the Windows 2003 Server it is running on. In an attempt to speed up the import the program nows splits the big file into smaller chunks.

Would it be possible to read the small file chunk (8mb) into memory (ie array) and then pass it to the MySQLBulkLoader as a file?

The bulk loader looks for a filename path:

 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 = "";

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

↙厌世 2024-11-22 09:09:18

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

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

Memory isn't a file, so the short answer is no. The alternatives are:

  1. Read through the file, writing it out as a temporary file (System.IO.Path.GetTempFileName() is your friend here, for the name to give the partial file) and passing that filename to MySqlBulkLoader
  2. Use a "RAM Disk" tool to create a memory based disk to put a copy of the full 300Mb file on, then pass that files path to MySqlBulkLoader.
倒带 2024-11-22 09:09:18

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

The following class accepts that it is not possible and writes the DataTable to disk before bulkloading.

It may not be suited to all circumstances, but it suited my needs at the time.

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);
                }
            }
        }
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文