SqlBulkCopy 및 파일 보관

c# file-io sqlbulkcopy

문제

플랫 파일에서 SQL 테이블에 데이터를로드하는 프로세스가 있으며 파일을 즉시 보관 폴더로 이동해야합니다. 그러나 코드를 실행할 때 데이터를 가져 오지만 throws 및 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;
    }
}   

수락 된 답변

프로그램이 파일을 열어 두었을 가능성이 높습니다. 문을 using FileStreamStreamReader 개체를 래핑해야합니다. 이것은 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();
        }
    }
}
...


아래 라이선스: CC-BY-SA with attribution
와 제휴하지 않음 Stack Overflow
이 KB는 합법적입니까? 예, 이유를 알아보십시오.
아래 라이선스: CC-BY-SA with attribution
와 제휴하지 않음 Stack Overflow
이 KB는 합법적입니까? 예, 이유를 알아보십시오.