Notatnik pokonuje je wszystkie?

134

W systemie Windows Server 2012 R2 program Kotlin używa FileChannel.tryLock()do utrzymywania wyłącznej blokady pliku, na przykład:

val fileRw = RandomAccessFile(file, "rw")
fileRw.channel.tryLock()

Po założeniu tej blokady nie mogę otworzyć pliku za pomocą:

  • WordPad
  • Notepad ++
  • Programowo z C # dla dowolnej wartości FileShare:

    using (var fileStream = new FileStream(processIdPath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
    using (var textReader = new StreamReader(fileStream))
    {
        textReader.ReadToEnd();
    }
  • Z wiersza typepoleceń polecenie:

    C:\some-directory>type file.txt
    The process cannot access the file because another process has locked a portion of the file.
  • Internet Explorer (tak, byłem zdesperowany)

Mogę go otworzyć za pomocą Notatnika.

Jak do cholery Notatnik jest w stanie otworzyć zablokowany plik, czego nic innego nie może?

Mono Threaded
źródło

Odpowiedzi:

202

Notatnik odczytuje pliki najpierw mapując je do pamięci, zamiast używać „zwykłych” mechanizmów odczytu plików, prawdopodobnie używanych przez inne edytory, których próbowałeś. Ta metoda umożliwia odczyt plików, nawet jeśli mają one wyłączne blokady oparte na zakresie.

Możesz osiągnąć to samo w C # za pomocą czegoś w rodzaju:

using (var f = new FileStream(processIdPath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
using (var m = MemoryMappedFile.CreateFromFile(f, null, 0, MemoryMappedFileAccess.Read, null, HandleInheritability.None, true))
using (var s = m.CreateViewStream(0, 0, MemoryMappedFileAccess.Read))
using (var r = new StreamReader(s))
{
    var l = r.ReadToEnd();
    Console.WriteLine(l);
}
Iridium
źródło
58
Potwierdzone bardziej szczegółowo przez Raymonda Chena firmy Microsoft : Aby załadować plik, Notatnik mapuje widok pliku jako plik mapowany w pamięci i używa go jako źródła. Kod analizuje kodowanie, w razie potrzeby przeprowadza konwersję strony kodowej do UTF-16LE, umieszcza wynik w bloku pamięci, a następnie używa komunikatu EM_SETHANDLE do przekazania całego bloku kontrolce edycji.
Stevoisiak