Le bloc-notes les bat tous?

134

Sur un système Windows Server 2012 R2, un programme Kotlin utilise FileChannel.tryLock()pour maintenir un verrou exclusif sur un fichier, comme ceci:

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

Avec ce verrou en place, je ne peux pas ouvrir le fichier avec:

  • WordPad
  • Bloc-notes ++
  • Par programme avec C #, pour toute valeur de FileShare:

    using (var fileStream = new FileStream(processIdPath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
    using (var textReader = new StreamReader(fileStream))
    {
        textReader.ReadToEnd();
    }
  • Depuis la ligne de commande, la typecommande:

    C:\some-directory>type file.txt
    The process cannot access the file because another process has locked a portion of the file.
  • Internet Explorer (oui, j'étais désespéré)

Je peux l' ouvrir avec le Bloc-notes.

Comment le bloc-notes est-il capable d'ouvrir un fichier verrouillé que rien d'autre ne peut?

MonoThreaded
la source

Réponses:

202

Le Bloc-notes lit les fichiers en les mappant d'abord en mémoire, plutôt qu'en utilisant les mécanismes de lecture de fichiers "habituels" probablement utilisés par les autres éditeurs que vous avez essayés. Cette méthode permet la lecture des fichiers même s'ils ont des verrous exclusifs basés sur la plage.

Vous pouvez obtenir la même chose en C # avec quelque chose du genre:

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
la source
58
Confirmé plus en détail par Raymond Chen de Microsoft : pour charger un fichier, le Bloc-notes mappe une vue du fichier en tant que fichier mappé en mémoire et l'utilise comme source. Le code calcule l'encodage, effectue une conversion de page de codes en UTF-16LE si nécessaire, place le résultat dans un bloc de mémoire, puis utilise le message EM_SETHANDLE pour remettre ce bloc entier au contrôle d'édition.
Stevoisiak