【问题标题】:How to get file information using Mono on Linux如何在 Linux 上使用 Mono 获取文件信息
【发布时间】:2014-03-03 14:06:49
【问题描述】:

使用 Mono,我想获取有关 Linux 系统上文件的各种信息。

特别是,我想获取文件属性、文件权限、所有者以及文件是实际文件还是某种类型的链接。

在 Windows 中,我会使用 FileInfo.Attributes 获取文件属性 - 但在 Linux 上这只会返回 FileAttributes.Normal,即使 lsattr 命令报告 ----ia-------e--(例如)。

在 Windows 中,我会使用 FileSecurity 来获取所有者和文件权限 - 但在 Linux 上使用 PlatformNotSupportedException 会抛出异常。

【问题讨论】:

    标签: c# linux mono filesystems fileinfo


    【解决方案1】:

    您可能希望有条件地使用来自Mono.Unix 的类,尤其是UnixFileInfo,具体取决于Environment.OSVersion.Platform

    【讨论】:

    • 这是一个很好的提示 - 我不知道 Mono.Unix 命名空间中的好东西!除了 AFAICS,通过lsattr 提供的文件属性之外,这将为我提供一切 - 任何线索?
    • lsattr 使用依赖于文件系统支持的FS_IOC_GETFLAGS ioctl。如果你想尝试,你必须使用DllImport
    【解决方案2】:

    我有同样的要求,不得不自己破解一个解决方案,希望你会喜欢它:)

    using System;
    using System.Runtime.InteropServices;
    
    partial class FileProvider
    {
        private const uint IOCPARM_MASK = 0x7f; /* parameters must be < 128 bytes */
        private const uint IOC_VOID = 0x20000000; /* no parameters */
        private const uint IOC_IN = 0x40000000; /* copy out parameters */
        private const uint IOC_OUT = 0x80000000; /* copy in parameters */
        private const uint IOC_INOUT = (IOC_IN | IOC_OUT);
        /* the 0x20000000 is so we can distinguish new ioctl's from old */
    
        private static uint _IOXXX(uint ioc, int x, int y, int l)
        {
            return ioc | (((uint)l & IOCPARM_MASK) << 16) | ((uint)x << 8) | (uint)y;
        }
    
        private static uint _IO(int x, int y)
        {
            return _IOXXX(IOC_VOID, x, y, 0);
        }
    
        private static int SizeOf<T>()
        {
            var type = typeof (T);
            if (type.IsEnum)
                return Marshal.SizeOf(type.GetEnumUnderlyingType());
            return Marshal.SizeOf(type);
        }
    
        private static uint _IOR<T>(int x, int y)
        {
            return _IOXXX(IOC_OUT, x, y, SizeOf<T>());
        }
    
        private static uint _IOW<T>(int x, int y)
        {
            return _IOXXX(IOC_IN, x, y, SizeOf<T>());
        }
    
        private static uint _IORW<T>(int x, int y)
        {
            return _IOXXX(IOC_INOUT, x, y, SizeOf<T>());
        }
    
        public static uint EXT2_IOC_GETFLAGS
        {
            get { return _IOR<IOC_FLAGS>('f', 1); }
        }
    
        public static uint EXT2_IOC_SETFLAGS
        {
            get { return _IOW<IOC_FLAGS>('f', 2); }
        }
    
        [Flags]
        private enum IOC_FLAGS : long
        {
            EXT2_SECRM_FL = 0x00000001, /* Secure deletion */
            EXT2_UNRM_FL = 0x00000002, /* Undelete */
            EXT2_COMPR_FL = 0x00000004, /* Compress file */
            EXT2_SYNC_FL = 0x00000008, /* Synchronous updates */
            EXT2_IMMUTABLE_FL = 0x00000010, /* Immutable file */
            EXT2_APPEND_FL = 0x00000020, /* writes to file may only append */
            EXT2_NODUMP_FL = 0x00000040, /* do not dump file */
            EXT2_NOATIME_FL = 0x00000080, /* do not update atime */
            /* Reserved for compression usage... */
            EXT2_DIRTY_FL = 0x00000100,
            EXT2_COMPRBLK_FL = 0x00000200, /* One or more compressed clusters */
            EXT2_NOCOMPR_FL = 0x00000400, /* Access raw compressed data */
            EXT2_ECOMPR_FL = 0x00000800, /* Compression error */
            /* End compression flags --- maybe not all used */
            EXT2_BTREE_FL = 0x00001000, /* btree format dir */
            EXT2_INDEX_FL = 0x00001000, /* hash-indexed directory */
            EXT2_IMAGIC_FL = 0x00002000,
            EXT3_JOURNAL_DATA_FL = 0x00004000, /* file data should be journaled */
            EXT2_NOTAIL_FL = 0x00008000, /* file tail should not be merged */
            EXT2_DIRSYNC_FL = 0x00010000, /* Synchronous directory modifications */
            EXT2_TOPDIR_FL = 0x00020000, /* Top of directory hierarchies*/
            EXT4_HUGE_FILE_FL = 0x00040000, /* Set to each huge file */
            EXT4_EXTENTS_FL = 0x00080000, /* Inode uses extents */
            EXT4_EA_INODE_FL = 0x00200000, /* Inode used for large EA */
            /* EXT4_EOFBLOCKS_FL 0x00400000 was here */
            FS_NOCOW_FL = 0x00800000, /* Do not cow file */
            EXT4_SNAPFILE_FL = 0x01000000, /* Inode is a snapshot */
            EXT4_SNAPFILE_DELETED_FL = 0x04000000, /* Snapshot is being deleted */
            EXT4_SNAPFILE_SHRUNK_FL = 0x08000000, /* Snapshot shrink has completed */
            EXT2_RESERVED_FL = 0x80000000, /* reserved for ext2 lib */
        }
    
        [DllImport("libc", EntryPoint = "ioctl", SetLastError = true)]
        private extern static int ioctl(int fd, uint request, ref IOC_FLAGS data);
    

    然后您只需要使用Syscall.open 打开文件,使用FileProvider.ioctl 和给定的文件描述符以及EXT2_IOC_GETFLAGSEXT2_IOC_SETFLAGS(您可能还需要更改一些权限,这是一个原始的复制/粘贴)你想要的方式,然后使用Syscall.close

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2010-12-16
      • 2019-08-06
      • 2011-07-08
      • 1970-01-01
      • 1970-01-01
      • 2010-09-08
      • 2010-12-04
      相关资源
      最近更新 更多