Notepad mengalahkan mereka semua?

134

Pada sistem Windows Server 2012 R2, program Kotlin menggunakan FileChannel.tryLock()untuk menahan kunci eksklusif pada file, seperti ini:

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

Dengan kunci ini di tempat, saya tidak bisa membuka file dengan:

  • WordPad
  • Notepad ++
  • Pemrograman dengan C #, untuk setiap nilai FileShare:

    using (var fileStream = new FileStream(processIdPath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
    using (var textReader = new StreamReader(fileStream))
    {
        textReader.ReadToEnd();
    }
  • Dari baris perintah, typeperintah:

    C:\some-directory>type file.txt
    The process cannot access the file because another process has locked a portion of the file.
  • Internet Explorer (ya, saya putus asa)

Saya bisa membukanya dengan Notepad.

Bagaimana sih Notepad bisa membuka file yang terkunci yang tidak bisa dilakukan oleh yang lain?

MonoThreaded
sumber

Jawaban:

202

Notepad membaca file dengan terlebih dahulu memetakannya ke dalam memori, daripada menggunakan mekanisme membaca file "biasa" yang mungkin digunakan oleh editor lain yang Anda coba. Metode ini memungkinkan membaca file bahkan jika mereka memiliki kunci berbasis rentang eksklusif.

Anda dapat mencapai hal yang sama dalam C # dengan sesuatu di sepanjang baris:

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
sumber
58
Dikonfirmasi secara lebih rinci oleh Microsoft Raymond Chen : Untuk memuat file, Notepad memetakan tampilan file sebagai file yang dipetakan memori dan menggunakannya sebagai sumber. Kode tersebut keluar dari penyandian, melakukan konversi halaman kode ke UTF-16LE jika perlu, menempatkan hasilnya dalam blok memori, dan kemudian menggunakan pesan EM_SETHANDLE untuk menyerahkan seluruh blok itu ke kontrol edit.
Stevoisiak