SqlBulkCopy和文件存档

时间:2013-03-30 00:02:47

标签: c# file-io sqlbulkcopy

我有一个进程将数据从平面文件加载到sql表中,然后需要立即将文件移动到存档文件夹。 但是,在运行代码时,它会导入数据,但会抛出和IOException {“该进程无法访问该文件,因为它正由另一个进程使用。”}

在此过程中似乎存在争议。我应该在哪里以及如何避免这种情况?

 internal class Program
{
    private static void Main(string[] args)
    {
        string sourceFolder = @"c:\ImportFiles\";
        string destinationFolder = @"c:\ImportFiles\Archive\";

        foreach (string fileName in Directory.GetFiles(sourceFolder, "*.*"))
        {
            string sourceFileName = Path.GetFileName(fileName);
            string destinationFileName = Path.GetFileName(fileName) + ".arc";

            ProcessFile(fileName);

            string source = String.Concat(sourceFolder,sourceFileName);
            string destination = String.Concat(destinationFolder,destinationFileName);
            File.Move(source, destination);        
        }
    }



    static void ProcessFile(string fileName)
    {
        Encoding enc = new UTF8Encoding(true, true);
        DataTable dt = LoadRecordsFromFile(fileName, enc, ',');

        SqlBulkCopy bulkCopy = new SqlBulkCopy("Server=(local);Database=test;Trusted_Connection=True;",
                                               SqlBulkCopyOptions.TableLock);
        bulkCopy.DestinationTableName = "dbo.tblManualDataLoad";
        bulkCopy.WriteToServer(dt);
        bulkCopy.Close();

    }


    public static DataTable LoadRecordsFromFile(string fileName, Encoding encoding, char delimeter)
    {
        DataTable table = null;

        if (fileName != null &&
            !fileName.Equals(string.Empty) &&
            File.Exists(fileName))
        {
            try
            {
                string tableName = "DataImport";
                FileStream fs = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);

                List<string> rows = new List<string>();
                StreamReader reader = new StreamReader(fs, encoding);
                string record = reader.ReadLine();

                while (record != null)
                {
                    rows.Add(record);
                    record = reader.ReadLine();
                }

                List<string[]> rowObjects = new List<string[]>();
                int maxColsCount = 0;
                foreach (string s in rows)
                {
                    string[] convertedRow = s.Split(new char[] { delimeter });
                    if (convertedRow.Length > maxColsCount)
                        maxColsCount = convertedRow.Length;
                    rowObjects.Add(convertedRow);
                }

                table = new DataTable(tableName);
                for (int i = 0; i < maxColsCount; i++)
                {
                    table.Columns.Add(new DataColumn());
                }

                foreach (string[] rowArray in rowObjects)
                {
                    table.Rows.Add(rowArray);
                }
                //Remove Header Row From Import file
                DataRow row = table.Rows[0];
                row.Delete();
                table.AcceptChanges();
            }
            catch
            {
                //TODO SEND EMAIL ALERT ON ERROR
                throw new Exception("Error in ReadFromFile: IO error.");
            }
        }
        else
        {
            //TODO SEND EMAIL ALERT ON ERROR
            throw new FileNotFoundException("Error in ReadFromFile: the file path could not be found.");
        }
        return table;
    }
}   

1 个答案:

答案 0 :(得分:1)

您的程序可能会将文件保持打开状态。您应该在FileStream语句中包装StreamReaderusing个对象。这会在using块完成时关闭这些对象。

您的LoadRecordsFromFile函数中读取文件的部分应如下所示:

...
string tableName = "DataImport";
List<string> rows = new List<string>();
using (FileStream fs = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
{
    using (StreamReader reader = new StreamReader(fs, encoding))
    {
        string record = reader.ReadLine();
        while (record != null)
        {
            rows.Add(record);
            record = reader.ReadLine();
        }
    }
}
...