Notepad beats them all?

29,297

Notepad reads files by first mapping them into memory, rather than using the "usual" file reading mechanisms presumably used by the other editors you tried. This method allows reading of files even if they have an exclusive range-based locks.

You can achieve the same in C# with something along the lines of:

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);
}
Share:
29,297
MonoThreaded
Author by

MonoThreaded

There are far more bad questions than good answers

Updated on December 26, 2020

Comments

  • MonoThreaded
    MonoThreaded over 3 years

    On a Windows Server 2012 R2 system, a Kotlin program uses FileChannel.tryLock() to hold an exclusive lock on a file, like this:

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

    With this lock in place, I cannot open the file with:

    • WordPad
    • Notepad++
    • Programmatically with C#, for any value of FileShare:

      using (var fileStream = new FileStream(processIdPath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
      using (var textReader = new StreamReader(fileStream))
      {
          textReader.ReadToEnd();
      }
      
    • From the command line, the type command:

      C:\some-directory>type file.txt
      The process cannot access the file because another process has locked a portion of the file.
      
    • Internet Explorer (yes, I was desperate)

    I can open it with Notepad.

    How the heck is Notepad able to open a locked file that nothing else can?

  • Stevoisiak
    Stevoisiak about 6 years
    Confirmed in more detail by Microsoft’s Raymond Chen: To load a file, Notepad maps a view of the file as a memory-mapped file and uses that as the source. The code figures out the encoding, performs a code page conversion to UTF-16LE if necessary, puts the result in a memory block, and then uses the EM_SET­HANDLE message to hand that entire block to the edit control.
  • SamB
    SamB about 2 years
    That blog post got moved slightly; it's now at devblogs.microsoft.com/oldnewthing/20180521-00/?p=98795 (the domain name changed)
  • Rotem
    Rotem almost 2 years
    Interestingly, when I try to open a locked file in c# this way, it throws an exception on the constructor of the first FileStream, or if I use the overload of MemoryMappedFile.CreateFromFile which accepts a filename, it throw the same exception ("The process can not access the file because it is in use by another process"). The type command however, and of course, Notepad, do succeed.