使用SQL Server打开锁定的文本文件

时间:2013-03-06 23:27:39

标签: c# sql-server locking

当我尝试

BULK INSERT table FROM 'c:\file.txt'

我得到了

Msg 4861, Level 16, State 1, Line 1
Cannot bulk load because the file "c:\file.txt" could not be opened. Operating system error code 32(The process cannot access the file because it is being used by another process.).

错误,因为该文件是由另一个进程打开的日志文件。

但是使用C#,我可以使用System.IO.FileShare.ReadWrite打开文件:

using (System.IO.FileStream fileStream = new System.IO.FileStream("c:\\file.txt", System.IO.FileMode.Open, System.IO.FileAccess.Read, System.IO.FileShare.ReadWrite))
        {
            using (System.IO.StreamReader streamReader = new System.IO.StreamReader(fileStream))
            {
                file = streamReader.ReadToEnd();
            }
        }

有没有办法在SQL Server(批量插入或任何其他)中拥有ReadWrite共享功能?

由于

2 个答案:

答案 0 :(得分:2)

由于您无法控制SQL Server在后台使用的OpenFile标志,因此您可能必须在执行批量插入之前将文件复制到临时文件中。

答案 1 :(得分:0)

(自我删除问题以来,我在DBA.SE上的回答中转发。)

BULK INSERT尝试对源文件执行写锁定,以确保在读取发生时没有其他进程同时修改文件。这样做是为了稳定文件格式,因为读取可能最终会尝试处理由并发编写器写入的部分行。

由于日志文件已被其他进程打开以供写入,因此这是不兼容的访问,并且您会收到该错误。

关于代码:

  • FileAccess确定将如何处理该文件。
  • FileShare确定在您打开文件时允许其他人对该文件执行的操作。

日志记录过程将使用FileAccess.WriteFileAccess.ReadWrite,并且假设您的代码成功,可能FileShare.Read - 这会阻止其他人同时写入文件,但允许他们阅读内容。您的代码仅请求读取访问权限,因此这是兼容的。如果您重新运行代码并请求写访问权限(FileAccess.Write),代码将失败。

要使用BULK INSERT导入此文件,您必须复制并导入该文件,然后才会涉及任何文件锁定。