Arsen Zahray
Arsen Zahray

Reputation: 25287

Is there any way to read data from a locked file?

Here's what I have in mind:

        var file = @"myfile";
        File.Open(file,
                  FileMode.Open, FileAccess.ReadWrite, FileShare.None);

        using (StreamReader rdr = new StreamReader(File.Open(file, FileMode.Open, FileAccess.Read, FileShare.Read)))
        {
            rdr.ReadToEnd();
        }
        var t = File.ReadAllBytes(file);

Neigther File.Open(file, FileMode.Open, FileAccess.Read, FileShare.Read) nor File.ReadAllBytes can read file data.

From my old c++ and winapi days, I do remember, that there used to be a good way to read locked files, if you have backup priviledges, but I have no idea how obtain and use those in c#.

Can anyone provide me with a sample on how to read a file after it has been locked?

Upvotes: 4

Views: 8459

Answers (2)

Daniel Peñalba
Daniel Peñalba

Reputation: 31847

Well, if the file is totally locked (no sharing) you will not be able to read it. If the file was opened to share read, you will be able to read using a non intrusive method:

string fileName = @"myfile";
using (FileStream fileStream = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
using (StreamReader fileReader = new StreamReader(fileStream ))
{
    while (!fileReader .EndOfStream)
    {
        string line = fileReader .ReadLine();
        // Your code here
    }
}

Upvotes: 6

Arsen Zahray
Arsen Zahray

Reputation: 25287

What I was trying to do in fact is impossible, and backup privilege doesn't help either:

       [DllImport("kernel32.dll", CharSet = CharSet.Auto,
        CallingConvention = CallingConvention.StdCall,
        SetLastError = true)]
            public static extern SafeFileHandle CreateFile(
                string lpFileName,
                uint dwDesiredAccess,
                uint dwShareMode,
                IntPtr SecurityAttributes,
                uint dwCreationDisposition,
                uint dwFlagsAndAttributes,
                IntPtr hTemplateFile
            );

    private static uint READ_CONTROL = 0x00020000;
    private static uint OPEN_EXISTING = 3;
    private static uint FILE_FLAG_BACKUP_SEMANTICS = 0x02000000;


        var file = @"myfile";
        File.Open(file,
                  FileMode.Open, FileAccess.ReadWrite, FileShare.None);

        using(PrivilegeEnabler pe = new PrivilegeEnabler(Process.GetCurrentProcess(), Privilege.Backup))
        {
            var hFile = CreateFile(file,           // lpFileName
                       READ_CONTROL,               // dwDesiredAccess
                       0,                          // dwShareMode
                       IntPtr.Zero,                // lpSecurityAttributes
                       OPEN_EXISTING,              // dwCreationDisposition
                       FILE_FLAG_BACKUP_SEMANTICS, // dwFlagsAndAttributes
                       IntPtr.Zero);               // hTemplateFile
            using (var fs=new  FileStream(hFile.DangerousGetHandle(),FileAccess.Read))
            {
                using (StreamReader rdr=new StreamReader(fs))
                {
                    rdr.ReadToEnd();
                }
            }
        }

will still result in an error.

Upvotes: 1

Related Questions