批判这段代码:内存映射文件

一则或许对你有用的小广告

欢迎加入小哈的星球 ,你将获得:专属的项目实战 / 1v1 提问 / Java 学习路线 / 学习打卡 / 每月赠书 / 社群讨论

  • 新项目:《从零手撸:仿小红书(微服务架构)》 正在持续爆肝中,基于 Spring Cloud Alibaba + Spring Boot 3.x + JDK 17...点击查看项目介绍 ;
  • 《从零手撸:前后端分离博客项目(全栈开发)》 2 期已完结,演示链接: http://116.62.199.48/ ;

截止目前, 星球 内专栏累计输出 54w+ 字,讲解图 2476+ 张,还在持续爆肝中.. 后续还会上新更多项目,目标是将 Java 领域典型的项目都整一波,如秒杀系统, 在线商城, IM 即时通讯,权限管理,Spring Cloud Alibaba 微服务等等,已有 1900+ 小伙伴加入学习 ,欢迎点击围观

我们在生产中的以下代码中遇到错误。我们正在努力确保我们有良好的错误,这使我们能够轻松地解决问题。

在这种情况下,代码……并不是很有帮助。为什么?看看代码,我将在下面解释原因……


 public CodecIndexInput(FileInfo file, Func<Stream, Stream> applyCodecs)
{
    try
    {
        this.file = file;
        this.applyCodecs = applyCodecs;
    fileHandle = Win32NativeFileMethods.CreateFile(file.FullName,
        Win32NativeFileAccess.GenericRead,
        Win32NativeFileShare.Read | Win32NativeFileShare.Write | Win32NativeFileShare.Delete,
        IntPtr.Zero,
        Win32NativeFileCreationDisposition.OpenExisting,
        Win32NativeFileAttributes.RandomAccess,
        IntPtr.Zero);

    if (fileHandle.IsInvalid)
    {
        const int ERROR_FILE_NOT_FOUND = 2;
        if (Marshal.GetLastWin32Error() == ERROR_FILE_NOT_FOUND)
            throw new FileNotFoundException(file.FullName);
        throw new Win32Exception();
    }

    mmf = Win32MemoryMapNativeMethods.CreateFileMapping(fileHandle.DangerousGetHandle(), IntPtr.Zero, Win32MemoryMapNativeMethods.FileMapProtection.PageReadonly,
        0, 0, null);
    if (mmf == IntPtr.Zero)
    {
        throw new Win32Exception();
    }

    basePtr = Win32MemoryMapNativeMethods.MapViewOfFileEx(mmf,
        Win32MemoryMapNativeMethods.NativeFileMapAccessType.Read,
        0, 0, UIntPtr.Zero, null);
    if (basePtr == null)
        throw new Win32Exception();

    stream = applyCodecs(new MmapStream(basePtr, file.Length));
}
catch (Exception)
{
    Dispose(false);
    throw;
}

}

你看见了吗?

此代码有多个位置可以引发 Win32Exception。问题在于,此模式下的 Win32Exception 几乎只是一段代码,我们在该方法中有多个位置可以抛出。

发生这种情况时,如果我们没有部署 PDB 文件,我们无法仅从堆栈跟踪(没有行号)知道是哪个方法调用导致了错误。这会在事后导致一些混乱。

我们通过为每个选项添加描述文本来解决这个问题,包括让我们知道发生了什么的附加信息。特别是,我们不仅包括失败的操作,更重要的是,我们包括失败的文件。