2012-06-20 3 views
3

Вот что я имею в виду:Есть ли способ прочитать данные из заблокированного файла?

 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) ни File.ReadAllBytes может считывать данные файла.

Из моих старых дней C++ и winapi я помню, что когда-то был хороший способ читать заблокированные файлы, если у вас есть резервные привилегии, но я понятия не имею, как их получить и использовать в C#.

Может ли кто-нибудь предоставить мне образец того, как читать файл после его блокировки?

+0

Если он заблокирован, вы не должны его читать. Это своего рода точка замка. – Servy

+0

Замок, о котором идет речь, выполняется другим процессом. Я собираюсь использовать это в updater, чтобы проверить, нуждаются ли файлы в замене или нет (например, если процесс обновления требует перезагрузки) –

+1

«FileShare.None» - это полный замок, поэтому попытка чтения из него не будет работать , Оригинальный open должен как минимум разрешить «FileShare.Read» – Quintium

ответ

6

Ну, если файл полностью заблокирован (нет sharing), вы не сможете его прочитать. Если файл был открыт для share read, вы будете иметь возможность читать с помощью неинтрузивной методы:

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 
    } 
} 
+0

, это одна из вещей, которые я пробовал. Здесь не работает –

+0

Итак, я боюсь, что файл полностью заблокирован другим процессом. Вы можете использовать ProcessExplorer (http://technet.microsoft.com/en-us/sysinternals/bb896653.aspx), чтобы узнать, какой процесс блокирует файл. –

1

То, что я пытался сделать, на самом деле невозможно, а резервная привилегия не помогает:

 [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(); 
       } 
      } 
     } 

все равно приведет к ошибке.

Смежные вопросы