Блокнот бьет их всех?

134

В системе Windows Server 2012 R2 программа Kotlin использует FileChannel.tryLock() эксклюзивную блокировку файла, например:

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

С этим замком я не могу открыть файл с помощью:

  • Word Pad
  • Notepad ++
  • Программно с C #, для любого значения FileShare:

    using (var fileStream = new FileStream(processIdPath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
    using (var textReader = new StreamReader(fileStream))
    {
        textReader.ReadToEnd();
    }
  • Из командной строки typeкоманда:

    C:\some-directory>type file.txt
    The process cannot access the file because another process has locked a portion of the file.
  • Internet Explorer (да, я был в отчаянии)

Я могу открыть его с помощью блокнота.

Как, черт возьми, Блокнот может открыть заблокированный файл, который ничто другое не может?

MonoThreaded
источник

Ответы:

202

Блокнот читает файлы, сначала сопоставляя их с памятью, а не использует «обычные» механизмы чтения файлов, предположительно используемые другими редакторами, которые вы пробовали. Этот метод позволяет читать файлы, даже если они имеют эксклюзивную блокировку на основе диапазона.

Вы можете достичь того же в C # с помощью чего-то вроде:

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
Более подробно подтверждено Рэймондом Ченом из Microsoft : « Чтобы загрузить файл, Блокнот отображает представление файла как файл с отображением памяти и использует его в качестве источника. Код вычисляет кодировку, при необходимости выполняет преобразование кодовой страницы в UTF-16LE, помещает результат в блок памяти, а затем использует сообщение EM_SETHANDLE для передачи всего блока в элемент управления редактированием.
Stevoisiak