Notepad schlägt sie alle?

134

Auf einem Windows Server 2012 R2-System verwendet ein Kotlin-Programm FileChannel.tryLock()eine exklusive Sperre für eine Datei wie folgt:

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

Mit dieser Sperre kann ich die Datei nicht öffnen mit:

  • WordPad
  • Editor ++
  • Programmatisch mit C # für jeden Wert von FileShare:

    using (var fileStream = new FileStream(processIdPath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
    using (var textReader = new StreamReader(fileStream))
    {
        textReader.ReadToEnd();
    }
  • Über die Befehlszeile den typeBefehl:

    C:\some-directory>type file.txt
    The process cannot access the file because another process has locked a portion of the file.
  • Internet Explorer (ja, ich war verzweifelt)

Ich kann es mit Notepad öffnen.

Wie zum Teufel kann Notepad eine gesperrte Datei öffnen, die sonst nichts kann?

MonoThreaded
quelle

Antworten:

202

Notepad liest Dateien, indem es sie zuerst dem Speicher zuordnet, anstatt die "üblichen" Dateilesemechanismen zu verwenden, die vermutlich von den anderen Editoren verwendet werden, die Sie ausprobiert haben. Diese Methode ermöglicht das Lesen von Dateien, auch wenn diese über exklusive bereichsbasierte Sperren verfügen.

Sie können dasselbe in C # erreichen, indem Sie Folgendes tun:

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
quelle
58
Ausführlicher bestätigt von Raymond Chen von Microsoft : Um eine Datei zu laden, ordnet Notepad eine Ansicht der Datei als Speicherzuordnungsdatei zu und verwendet diese als Quelle. Der Code ermittelt die Codierung, führt bei Bedarf eine Codepage-Konvertierung in UTF-16LE durch, speichert das Ergebnis in einem Speicherblock und übergibt dann mit der Nachricht EM_SETHANDLE den gesamten Block an das Bearbeitungssteuerelement.
Stevoisiak