记事本能击败所有人吗?


134

在Windows Server 2012 R2系统上,Kotlin程序用于FileChannel.tryLock()在文件上持有排他锁,如下所示:

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

锁定后,我无法使用以下方式打开文件:

  • 写字板
  • 记事本++
  • 使用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(是的,我很绝望)

可以用记事本打开它。

记事本如何能够打开其他没有的锁定文件?

Answers:


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的Raymond Chen更详细地确认:要加载文件,记事本会将文件的视图映射为内存映射文件,并将其用作源。该代码计算出编码,必要时执行代码页转换为UTF-16LE,将结果放入存储块,然后使用EM_SETHANDLE消息将该整个块移交给编辑控件。
Stevoisiak
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.