Il blocco note li batte tutti?


134

Su un sistema Windows Server 2012 R2, un programma Kotlin utilizza FileChannel.tryLock()per contenere un blocco esclusivo su un file, come questo:

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

Con questo blocco in atto, non riesco ad aprire il file con:

  • Taccuino
  • Notepad ++
  • Programmaticamente con C #, per qualsiasi valore di FileShare:

    using (var fileStream = new FileStream(processIdPath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
    using (var textReader = new StreamReader(fileStream))
    {
        textReader.ReadToEnd();
    }
    
  • Dalla riga di comando, il typecomando:

    C:\some-directory>type file.txt
    The process cannot access the file because another process has locked a portion of the file.
    
  • Internet Explorer (sì, ero disperato)

Io posso aprirlo con il Blocco note.

Come diavolo Notepad è in grado di aprire un file bloccato che nient'altro può fare?

Risposte:


202

Il Blocco note legge i file mappandoli prima nella memoria, anziché utilizzare i "soliti" meccanismi di lettura dei file presumibilmente utilizzati dagli altri editor che hai provato. Questo metodo consente la lettura di file anche se hanno blocchi esclusivi basati su intervallo.

Puoi ottenere lo stesso in C # con qualcosa sulla falsariga di:

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

58
Confermato in modo più dettagliato da Raymond Chen di Microsoft : Per caricare un file, Blocco note mappa una vista del file come file mappato in memoria e lo utilizza come origine. Il codice calcola la codifica, esegue una conversione della tabella codici in UTF-16LE, se necessario, inserisce il risultato in un blocco di memoria e quindi utilizza il messaggio EM_SETHANDLE per consegnare l'intero blocco al controllo di modifica.
Stevoisiak,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.