c#获取文件或文件夹id

文件(夹)比较受诸多因素可能出现错漏,比如大小写,分隔符,还有父路径,短路径等影响,单纯的通过字符串比较出错概率很大,本文但要的方法是获取文件或文件夹的id,再来比较id判断提供的路径是否指向同一对象,代码如下:

复制代码
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Win32.SafeHandles;
using System.IO;
using System.Runtime.InteropServices;
using System.ComponentModel;

namespace Demo
{
    class Program
    {
        const uint FSCTL_GET_OBJECT_ID = 0x0009009c;
        internal const int
        GENERIC_READ = unchecked((int)0x80000000),
        FILE_FLAG_BACKUP_SEMANTICS = unchecked((int)0x02000000),
        OPEN_EXISTING = unchecked((int)3);

        [StructLayout(LayoutKind.Sequential)]
        public struct FILE_OBJECTID_BUFFER
        {
            public struct Union
            {
                [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
                public byte[] BirthVolumeId;

                [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
                public byte[] BirthObjectId;

                [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
                public byte[] DomainId;
            }

            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
            public byte[] ObjectId;

            public Union BirthInfo;

            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 48)]
            public byte[] ExtendedInfo;
        }

        [StructLayout(LayoutKind.Sequential)]
        public struct BY_HANDLE_FILE_INFORMATION
        {
            public uint FileAttributes;
            public FILETIME CreationTime;
            public FILETIME LastAccessTime;
            public FILETIME LastWriteTime;
            public uint VolumeSerialNumber;
            public uint FileSizeHigh;
            public uint FileSizeLow;
            public uint NumberOfLinks;
            public uint FileIndexHigh;
            public uint FileIndexLow;
        }

        [DllImport("kernel32.dll", SetLastError = true)]
        public static extern bool DeviceIoControl(
            SafeFileHandle hDevice,
            uint dwIoControlCode,
            IntPtr lpInBuffer,
            uint nInBufferSize,
            [Out] IntPtr lpOutBuffer,
            int nOutBufferSize,
            ref uint lpBytesReturned,
            IntPtr lpOverlapped
            );

        [DllImport("kernel32.dll", SetLastError = true)]
        public static extern SafeFileHandle CreateFile(
            String fileName,
            int dwDesiredAccess,
            System.IO.FileShare dwShareMode,
            IntPtr securityAttrs_MustBeZero,
            System.IO.FileMode dwCreationDisposition,
            int dwFlagsAndAttributes,
            IntPtr hTemplateFile_MustBeZero
            );

        [DllImport("kernel32.dll", SetLastError = true)]
        public static extern bool GetFileInformationByHandle(
            IntPtr hFile, out BY_HANDLE_FILE_INFORMATION lpFileInformation);

        public static String GetFileId(String path)
        {
            using (var fs = File.Open(
                path,
                FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.ReadWrite)
                )
            {
                BY_HANDLE_FILE_INFORMATION info;
                GetFileInformationByHandle(fs.Handle, out info);
                return String.Format(
                        "{0:x}", ((info.FileIndexHigh << 32) | info.FileIndexLow));
            }
        }

        public static FILE_OBJECTID_BUFFER GetFolderIdBuffer(String path)
        {
            using (var hFile = CreateFile(
                path,
                GENERIC_READ, FileShare.Read,
                IntPtr.Zero,
                (FileMode)OPEN_EXISTING,
                FILE_FLAG_BACKUP_SEMANTICS,
                IntPtr.Zero
                ))
            {
                if (null == hFile || hFile.IsInvalid)
                    throw new Win32Exception(Marshal.GetLastWin32Error());

                var buffer = default(FILE_OBJECTID_BUFFER);
                var nOutBufferSize = Marshal.SizeOf(buffer);
                var lpOutBuffer = Marshal.AllocHGlobal(nOutBufferSize);
                var lpBytesReturned = default(uint);

                var result =
                    DeviceIoControl(
                        hFile, FSCTL_GET_OBJECT_ID,
                        IntPtr.Zero, 0,
                        lpOutBuffer, nOutBufferSize,
                        ref lpBytesReturned, IntPtr.Zero
                        );

                if (!result)
                    throw new Win32Exception(Marshal.GetLastWin32Error());

                var type = typeof(FILE_OBJECTID_BUFFER);

                buffer = (FILE_OBJECTID_BUFFER)
                    Marshal.PtrToStructure(lpOutBuffer, type);

                Marshal.FreeHGlobal(lpOutBuffer);
                return buffer;
            }
        }

        static void Main(string[] args)
        {
            var fileid1 = GetFileId(@"C:\Users\a\Desktop\abc.png");
            var fileid2 = GetFileId(@"C:\Users\a\Desktop\ABC.png");

            var folderid1 = GetFolderIdBuffer(@"C:\Users\a\Desktop\").ObjectId.Reverse()
                .Select(x => x.ToString("x2")).Aggregate(String.Concat);
            var folderid2 = GetFolderIdBuffer(@"c:\users\a\..\a\desktop").ObjectId.Reverse()
                .Select(x => x.ToString("x2")).Aggregate(String.Concat);



        }
    }
}
复制代码

 

posted on   空明流光  阅读(487)  评论(0编辑  收藏  举报

相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!

导航

< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5
点击右上角即可分享
微信分享提示