精华内容
下载资源
问答
  • Windows平台C语言获取文件的一些属性

    千次阅读 2013-05-26 11:03:21
    Windows平台有一个WIN32_FIND_DATA结构,用来存储文件的一些属性(这里指的属性和下面结构中文件属性成员不同。这里的属性是指下面结构的所有成员)。 该结构的定义如下。 typedef struct _WIN32_FIND_DATA { ...

             Windows平台有一个WIN32_FIND_DATA结构,用来存储文件的一些属性(这里指的属性和下面结构中文件属性成员不同。这里的属性是指下面结构的所有成员)。

    该结构的定义如下。

    typedef struct _WIN32_FIND_DATA {
    DWORD dwFileAttributes; //文件属性
    FILETIME ftCreationTime; // 文件创建时间
    FILETIME ftLastAccessTime; // 文件最后一次访问时间
    FILETIME ftLastWriteTime; // 文件最后一次修改时间
    DWORD nFileSizeHigh; // 文件长度高32位
    DWORD nFileSizeLow; // 文件长度低32位
    DWORD dwReserved0; // 系统保留
    DWORD dwReserved1; // 系统保留
    TCHAR cFileName[ MAX_PATH ]; // 长文件名
    TCHAR cAlternateFileName[ 14 ]; // 8.3格式文件名
    } WIN32_FIND_DATA, *PWIN32_FIND_DATA;

            

    遍历文件:

            可以使用FindFirstFile()和 FindNextFile()函数可以得到 某个文件夹里面所有的文件(包括子文件夹)的WIN32_FIND_DATA结构信息。

            FindFirstFile的原型如下:

    HANDLE FindFirstFile(
       LPCTSTR lpFileName,
       LPWIN32_FIND_DATA lpFindFileData
    );

            FindFirstFile()函数中,第一个参数是一个字符串。可以是一个路径名或者文件名,并且支持通配符 * 和 ?。比如想查找D盘下的所有文件,可以写成D:\\*.* 或者 D:\\*。

            如果只想查找D盘下的txt文件,那么可以写成D:\\*.txt。

            第二个参数是指向WIN32_FIND_DATA结构体的一个指针。正如函数的名字FindFirstFile那样, 该函数会查找第一个符合查找条件的文件(使用通配符可以有多少文件满足查找条件)。然后把这个文件的一些信息写入这个结构里面。如果第一个参数没有使用通配符,而是一个文件名,那么将只能找到一个符合条件的文件。

            函数的返回值是一个句柄HANDLE,说白了也就是一个整型。这个返回值可以用来查找下一个符合查找条件的文件。这就是下面的FindNextFile函数了。如果函数调用失败,将返回INVALID_HANDLE_VALUE

            FindNextFile的原型如下

    BOOL FindNextFile(
      HANDLE hFindFile,
      LPWIN32_FIND_DATA lpFindFileData
    );

            第一个参数就是FindFirstFile函数的返回值。第二个参数和FindFirstFile一样,在一个指针,用来存放被查找到的文件的一些信息。

            如果查找成功,函数返回非0值。否则返回0。可以调用GetLastError()函数来查看失败原因。如果没有符合要求的文件了,那么也将返回0。此时,调用GetLastError()函数将返回ERROR_NO_MORE_FILES。

            在使用完上面两个函数后,要记得使用CloseFile(HANDLEhFindFile)函数来关闭这个句柄。

            上面三个函数需要包括windows.h头文件.

            说了这么多,下面给出一个例子代码。


    #include<iostream>
    #include<windows.h>
    using namespace std;
    
    int main()
    {
    	WIN32_FIND_DATA  fileAttr;
    	HANDLE  handle;
    	handle = FindFirstFile("D:\\*", &fileAttr);
    
    	if( handle == INVALID_HANDLE_VALUE ) 
    	{
    		cout<<"invalid handle value "<<GetLastError()<<endl;
    	}
    	else
    	{
    		cout<<fileAttr.cFileName<<endl; //输出查找到的文件名
    
    		while(  FindNextFile(handle, &fileAttr)  )
    		{
    			cout<<fileAttr.cFileName<<endl; //输出每一个查找到的文件名
    		}
    
    		if( GetLastError() == ERROR_NO_MORE_FILES )
    		{
    			cout<<"查找完毕"<<endl;
    		}
    		else 
    		{
    			cout<<"查找过程出现错误"<<endl;
    		}
    
    		FindClose(handle);
    	}
    
    	return 0;
    }
    

            上面的程序会遍历D盘下面的所有文件和文件夹。包括当前目录和父目录,这两个目录对应的文件名为.和..,即一个点和两个点。熟悉Linux的读者就很容易明白。

            也可以查找相对路径的文件,比如"*.txt",就查找当前目录下的所有txt文件

            如果在编译的时候出现了cannot convert 'const char*' to 'LPCWSTR' 错误,可以把WIN32_FIND_DATA换成WIN32_FIND_DATAA,即在最后追加一个A,FindFirstFile和FindNextFile也要追加一个A。



    文件属性:

            现在看一下WIN32_FIND_DATA结构的一些成员信息。



    大小属性:

            首先看一下文件的大小信息。该信息用了两个成员存储。分别是:

            DWORD  nFileSizeHigh;// 文件长度高32位

            DWORD  nFileSizeLow;// 文件长度低32位

            其中,单位是 字节数。

            由于nFileSizeHigh存储的是文件长度的高位,所以当文件的大小小于MAXDWORD时,该成员的值为0。最后,可以用 (nFileSizeHigh * (MAXDWORD+1)) +  nFileSizeLow 来计算文件大小。

            文件夹的大小是 0。

     

    文件类型属性:


            文件类型属性由dwFileAttributes成员指明。最常用的类型当然就是:普通文件和文件夹,分别对应FILE_ATTRIBUTE_ARCHIVE和FILE_ATTRIBUTE_DIRECTORY。更多的属性可以参照这里。因为一个文件可能包含多个属性,所以判断的时候使用诸如:FILE_ATTRIBUTE_ARCHIVE & dwFileAttributes。而不是使用==符号。



    时间属性:

            现在看一下与文件有关的时间属性。有三个时间,创建时间、访问时间、修改时间。三者都差不多。只需弄懂一个,其他两个就自然知道怎么用了。

            从文章最前面的WIN32_FIND_DATA结构体可以看到其ftCreationTime 成员是一个FILETIME类型。声明如下:

    typedef struct _FILETIME {
      DWORD dwLowDateTime;
      DWORD dwHighDateTime;
    } FILETIME, *PFILETIME;

            一眼看过去,都不知道怎么使用。就像C语言标准库里面的time()函数一样,返回一个从1970年到现在的秒数。这个值很难使用。还好Windows还提供了另外一个结构 SYSTEMTIME。其声明如下:

    typedef struct _SYSTEMTIME {
      WORD wYear;
      WORD wMonth;
      WORD wDayOfWeek;
      WORD wDay;
      WORD wHour;
      WORD wMinute;
      WORD wSecond;
      WORD wMilliseconds;
    } SYSTEMTIME, *PSYSTEMTIME;

            这个结构看起来才像人使用的,刚才那个完全是机器使用的。

            同样,Windows提供了两者相互转换的函数.

    BOOL FileTimeToSystemTime(
      const FILETIME *lpFileTime,
      LPSYSTEMTIME lpSystemTime
    );


    BOOL SystemTimeToFileTime(
      const SYSTEMTIME *lpSystemTime,
      LPFILETIME lpFileTime
    );

    两个函数都需要对应结构体的指针。

     

            还有一个东西需要注意。

            通过FindFirstFile、FindNextFile获取的WIN32_FIND_DATA结构。其FILETIME成员的值都是使用UTC时间,就是中学地理学的格林尼治时间。我们中国用东8区时间。所以我们还要在这些成员值的基础上加上 8 小时。微软不推荐我们直接对FILETIME结构进行 加上 或者减少 某个时间。如果我们要转换成我们当地的时间(就是从UTC时间转换成东8区时间),可以使用函数 FileTimeToLocalFileTime。其声明如下:

    BOOL FileTimeToLocalFileTime(
      const FILETIME *lpFileTime,
      LPFILETIME lpLocalFileTime
    );

             另外,不能就地修改。就是说,第一个参数和第二个参数要指向不同的内存。


             给一个例子吧。


    #include<iostream>
    #include<windows.h>
    using namespace std;
    
    ostream& operator << (ostream& os, const SYSTEMTIME& t)
    {
    	os<<t.wYear<<"-"<<t.wMonth<<"-"<<t.wDay<<"  ";
    	os<<t.wHour<<": "<<t.wMinute<<": "<<t.wSecond<<endl;
    	return os;
    }
    
    int main()
    {
    	
    	WIN32_FIND_DATA fileAttr;
    	HANDLE handle;
    	
    	SYSTEMTIME sysTime;
    	FILETIME localFileTime;
    	
    	handle = FindFirstFile("D:\\*.txt", &fileAttr);
    	
    	if( handle == INVALID_HANDLE_VALUE )
    	{
    		cout<<"invalid handle value "<<GetLastError()<<endl;
    	}
    	else
    	{
    		cout<<fileAttr.cFileName<<" size is "<<((fileAttr.nFileSizeHigh * (MAXDWORD+1))  +  fileAttr.nFileSizeLow) <<endl;
    		FileTimeToLocalFileTime(&fileAttr.ftCreationTime, &localFileTime); //转换成当地时间
    		
    		FileTimeToSystemTime(&localFileTime, &sysTime); //转换成人看的时间类型
    		cout<<sysTime<<endl;
    		
    		FindClose(handle);
    	}
    	
    	return 0;
    }
    









    展开全文
  • C++如何获取文件属性

    千次阅读 2017-10-25 10:02:52
    C++如何获取文件属性,stat系统调用系列包括了fstat、stat和lstat,它们都是用来返回“相关文件状态信息”的,三者的不同之处在于设定源文件的方式不同。stat系统调用系列包括了fstat、stat和lstat,它们都是用来...
    C++ 如何获取文件属性,stat 系统 调用系列包括了fstat、stat和lstat,它们都是用来返回“相关文件状态信息”的,三者的不同之处在于设定源文件的方式不同。 stat系统调用系列包括了fstat、stat和lstat,它们都是用来返回“相关文件状态信息”的,三者的不同之处在于设定源文件的方式不同。

    1

    首先隆重介绍的是一个非常重要的”VIP”人物,他是fstat, stat和lstat三者都要用到的一个结构体类型,名字叫做struct stat。可以说,没有这个struct stat的支持,上述三个系统调用将寸步难行。

    这个struct stat结构体在不同的Unix/Linux系统中的定义是有小的区别的,但你完全不用担心,这并不会影响我们的使用。

    在struct stat结构体中我们常用的且各个平台都一定有的域是:

    st_mode 文件权限和文件类型信息

    st_ino   与该文件关联的inode

    st_dev   保存文件的设备

    st_uid   文件属主的UID号

    st_gid   文件属主的GID号

    st_atime 文件上一次被访问的时间

    st_ctime 文件的权限、属主、组或内容上一次被修改的时间(windows系统中为文件创建时间)

    st_mtime 文件的内容上一次被修改的时间。(和st_ctime的不同之处显而易见)

    st_nlink  该文件上硬连接的个数

    我分别提取了solaris(UNIX)和fedora(Linux)的struct stat结构体的原始定义:大家可以自己比对一下便可以发现两者确实有所不同,但主要的域是完全相同的。

    solaris的struct stat定义:

    struct stat {
    dev_t           st_dev;
    ino_t           st_ino;
    mode_t          st_mode;
    nlink_t         st_nlink;
    uid_t           st_uid;
    gid_t           st_gid;
    dev_t           st_rdev;
    off_t           st_size;
    timestruc_t     st_atim;
    timestruc_t     st_mtim;
    timestruc_t     st_ctim;
    blksize_t       st_blksize;
    blkcnt_t        st_blocks;
    char            st_fstype[_ST_FSTYPSZ];
    };

    fedora的struct stat定义:

    struct stat
    {
    __dev_t st_dev;                     /* Device.  */
    unsigned short int __pad1;
    __ino_t st_ino;                     /* File serial number.  */
    __mode_t st_mode;                   /* File mode.  */
    __nlink_t st_nlink;                 /* Link count.  */
    __uid_t st_uid;                     /* User ID of the file’s owner. */
    __gid_t st_gid;                     /* Group ID of the file’s group.*/
    __dev_t st_rdev;                    /* Device number, if device.  */
    unsigned short int __pad2;
    __off_t st_size;                    /* Size of file, in bytes.  */
    __blksize_t st_blksize;             /* Optimal block size for I/O.  */
    __blkcnt_t st_blocks;               /* Number 512-byte blocks allocated. */
    struct timespec st_atim;            /* Time of last Access.  */
    struct timespec st_mtim;            /* Time of last modification.  */
    struct timespec st_ctim;            /* Time of last status change.  */
    unsigned long int __unused4;
    unsigned long int __unused5;
    };

    大家一定注意到了,在上面列举域的时候,我在st_mode处使用了黑体橘红色标识,原因在于这个域不像其他域那么容易使用,其他的域的值显而易见,而st_mode域是需要一些宏予以配合才能使用的。其实,通俗说,这些宏就是一些特定位置为1的二进制数的外号,我们使用它们和st_mode进行”&”操作,从而就可以得到某些特定的信息。

    文件类型标志包括:

    S_IFBLK:文件是一个特殊的块设备

    S_IFDIR:文件是一个目录

    S_IFCHR:文件是一个特殊的字符设备

    S_IFIFO:文件是一个FIFO设备

    S_IFREG:文件是一个普通文件(REG即使regular啦)

    S_IFLNK:文件是一个符号链接

    其他模式标志包括:

    S_ISUID:文件设置了SUID位

    S_ISGID:文件设置了SGID位

    S_ISVTX:文件设置了sticky位

    用于解释st_mode标志的掩码包括:

    S_IFMT:文件类型

    S_IRWXU:属主的读/写/执行权限,可以分成S_IXUSR, S_IRUSR, S_IWUSR

    S_IRWXG:属组的读/写/执行权限,可以分成S_IXGRP, S_IRGRP, S_IWGRP

    S_IRWXO:其他用户的读/写/执行权限,可以分为S_IXOTH, S_IROTH, S_IWOTH

    还有一些用于帮助确定文件类型的宏定义,这些和上面的宏不一样,这些是带有参数的宏,类似与函数的使用方法:

    S_ISBLK:测试是否是特殊的块设备文件

    S_ISCHR:测试是否是特殊的字符设备文件

    S_ISDIR:测试是否是目录(我估计find . -type d的源代码实现中就用到了这个宏)

    S_ISFIFO:测试是否是FIFO设备

    S_ISREG:测试是否是普通文件

    S_ISLNK:测试是否是符号链接

    S_ISSOCK:测试是否是socket

    3

    我们已经学习完了struct stat和各种st_mode相关宏,现在就可以拿它们和stat系统调用相互配合工作了!

    int fstat(int filedes, struct stat *buf);

    int stat(const char *path, struct stat *buf);

    int lstat(const char *path, struct stat *buf);

    聪明人一眼就能看出来fstat的第一个参数是和另外两个不一样的,对!fstat区别于另外两个系统调用的地方在于,fstat系统调用接受的是 一个“文件描述符”,而另外两个则直接接受“文件全路径”。文件描述符是需要我们用open系统调用后才能得到的,而文件全路经直接写就可以了。

    stat和lstat的区别:当文件是一个符号链接时,lstat返回的是该符号链接本身的信息;而stat返回的是该链接指向的文件的信息。(似 乎有些晕吧,这样记,lstat比stat多了一个l,因此它是有本事处理符号链接文件的,因此当遇到符号链接文件时,lstat当然不会放过。而 stat系统调用没有这个本事,它只能对符号链接文件睁一只眼闭一只眼,直接去处理链接所指文件喽)

    展开全文
  • 因为这设计到具体操作系统中文件系统的设计。在Linux和Windows程序库下面都有一个sys目录,里面包含系统相关的头文件,如下: Windows下: C:\Program Files\Microsoft Visual Studio 9.0\VC\include\sy

    我们知道C/C++都提供了标准的文件I/O库以便我们对文件进行读写。但我们无法通过标准的I/O库对文件系统进行更进一步的操作。因为这设计到具体操作系统中文件系统的设计。在Linux和Windows程序库下面都有一个sys目录,里面包含系统相关的头文件,如下:

    Windows下:

    C:\Program Files\Microsoft Visual Studio 9.0\VC\include\sys>dir
     驱动器 C 中的卷是 wins
     卷的序列号是 6C27-6F61
     C:\Program Files\Microsoft Visual Studio 9.0\VC\include\sys 的目录
    
    2013-08-26  22:50    <DIR>          .
    2013-08-26  22:50    <DIR>          ..
    2002-05-29  04:48               997 locking.h
    2007-01-06  08:59             6,722 stat.h
    2004-01-09  22:27             1,856 stat.inl
    2007-01-06  08:59             3,139 timeb.h
    2004-03-30  06:34             1,414 timeb.inl
    2006-11-09  01:45             2,033 types.h
    2007-01-06  08:59             3,805 utime.h
    2004-11-13  22:45             2,881 utime.inl
    2006-11-09  01:45             1,917 wstat.inl
                   9 个文件         24,764 字节
                   2 个目录 11,852,636,160 可用字节

    Linux下面:

    [anonymalias@localhost ~]$ ls /usr/include/sys
    acct.h       io.h           ptrace.h     stat.h         ucontext.h
    acl.h        ipc.h          queue.h      statvfs.h      uio.h
    asoundlib.h  kdaemon.h      quota.h      swap.h         ultrasound.h
    bitypes.h    kd.h           raw.h        syscall.h      un.h
    cdefs.h      klog.h         reboot.h     sysctl.h       unistd.h
    debugreg.h   mman.h         reg.h        sysinfo.h      user.h
    dir.h        mount.h        resource.h   syslog.h       ustat.h
    epoll.h      msg.h          select.h     sysmacros.h    utsname.h
    errno.h      mtio.h         sem.h        termios.h      vfs.h
    eventfd.h    param.h        sendfile.h   timeb.h        vlimit.h
    fcntl.h      pci.h          shm.h        time.h         vt.h
    file.h       perm.h         signalfd.h   timerfd.h      vtimes.h
    fsuid.h      personality.h  signal.h     times.h        wait.h
    gmon.h       poll.h         socket.h     timex.h        xattr.h
    gmon_out.h   prctl.h        socketvar.h  ttychars.h
    inotify.h    procfs.h       soundcard.h  ttydefaults.h
    ioctl.h      profil.h       statfs.h     types.h

    我们可以看到在Windows和Linux下面的sys目录中都存在一个stat.h头文件,也是仅有的一个相同的文件。

    Linux和Windows include目录下的sys/stat.h头文件都主要描述了对文件和目录的属性信息进行读取的操作。主要是通过struct stat结构体和stat()函数来实现的。在Windows的sys/stat.h头文件中的开头有下面一段说明:

    /***
    *sys/stat.h - defines structure used by stat() and fstat()
    *       Copyright (c) Microsoft Corporation. All rights reserved.
    *Purpose:
    *       This file defines the structure used by the _stat() and _fstat()
    *       routines.
    *       [System V]
    *       [Public]
    ****/

    可以看出该头文件遵循System V标准,所以Windows下的stat结构和Linux下面的基本属性都一致,所以下面主要以Linux下符合POSIX标准的stat进行介绍。

    1 stat结构

    stat结构如下(从linux的<bits/stat.h>中截取,成员类型名有所修改,主要是删除了有些下划线):

    struct stat
    {
    	dev_t st_dev;				/* 设备编号(文件系统)*/
    	ino_t st_ino;				/* 文件索引节点的编号 */
    	mode_t st_mode;				/* 文件的类型和访问权限 */
    	nlink_t st_nlink;			/* 硬链接计数*/
    	uid_t st_uid;				/* 文件所有者的用户ID */
    	gid_t st_gid;				/* 文件所有者的组ID*/
    	dev_t st_rdev;				/* 设备编号(特殊文件) */
    	off_t st_size;				/* 文件大小(B) */
    	blksize_t st_blksize;			/* 块大小(文件系统的I/O 缓冲区大小,最佳I/O块大小)  */
    	blkcnt_t st_blocks;			/* 文件的块数*/
    	time_t st_atime;			/* 最后访问时间*/
    	time_t st_mtime;			/* 文件内容最后修改时间*/
    	time_t st_ctime				/* 文件状态最后修改时间*/
    };

    上面的rdev,st_blksizest_blocks都不属于POSIX标准,且后面两个不存在与Windows的头文件中。

    其中我们最常使用的属性有以下两个字段:st_mode和st_size。其中通过st_mode字段可以判断文件的类型:普通文件,目录,管道文件等。st_size用了查看一个文件的大小。

    关于文件类型和访问权限字段st_mode使用位来标识每一种属性,该字段是一个16位的整数,Linux下,对于该字段的值在<sys/stat.h><bits/stat.h>中进行了定义,主要有以下属性:

    /* Encoding of the file mode.  */
    
    //掩码值都是8进制整数(即最高位0标识8进制),16位整数需要6位8进制数, 掩
    //码值用到的位数为:0177777
    
    #define S_IFMT        0170000 /* 高4位标识文件类型 */
    
    /* File types.  */
    #define S_IFDIR       0040000 /* 目录  */
    #define S_IFCHR       0020000 /* 字符设备文件  */
    #define S_IFREG       0100000 /* 普通文件  */
    #define S_IFIFO       0010000 /* FIFO文件 */
    #define S_IFBLK       0060000 /* 块设备文件  */
    #define S_IFLNK       0120000 /* 符号链接文件  */
    #define S_IFSOCK      0140000 /* socket文件  */
    
    /* Protection bits.  */
    #define S_ISUID       04000   /* Set user ID on execution.  */
    #define S_ISGID       02000   /* Set group ID on execution.  */
    #define S_ISVTX       01000   /* Save swapped text after use (sticky).  */
    #define S_IREAD       0400    /* Read by owner.  */
    #define S_IWRITE      0200    /* Write by owner.  */
    #define S_IEXEC       0100    /* Execute by owner.  */
    
    #define S_IRUSR S_IREAD       /* Read by owner.  */
    #define S_IWUSR S_IWRITE      /* Write by owner.  */
    #define S_IXUSR S_IEXEC       /* Execute by owner.  */
    /* Read, write, and execute by owner.  */
    #define S_IRWXU (__S_IREAD|__S_IWRITE|__S_IEXEC)
    
    #define S_IRGRP (S_IRUSR >> 3)  /* Read by group.  */
    #define S_IWGRP (S_IWUSR >> 3)  /* Write by group.  */
    #define S_IXGRP (S_IXUSR >> 3)  /* Execute by group.  */
    /* Read, write, and execute by group.  */
    #define S_IRWXG (S_IRWXU >> 3)
    
    #define S_IROTH (S_IRGRP >> 3)  /* Read by others.  */
    #define S_IWOTH (S_IWGRP >> 3)  /* Write by others.  */
    #define S_IXOTH (S_IXGRP >> 3)  /* Execute by others.  */
    /* Read, write, and execute by others.  */
    #define S_IRWXO (S_IRWXG >> 3)

    在Windows下面只定义了上面的一部分,其中上面数值常量是8进制,这里是16进制:

    #define _S_IFMT         0xF000          /* file type mask */
    #define _S_IFDIR        0x4000          /* directory */
    #define _S_IFCHR        0x2000          /* character special */
    #define _S_IFIFO        0x1000          /* pipe */
    #define _S_IFREG        0x8000          /* regular */
    #define _S_IREAD        0x0100          /* read permission, owner */
    #define _S_IWRITE       0x0080          /* write permission, owner */
    #define _S_IEXEC        0x0040          /* execute/search permission, owner */

    st_mode是stat最常用的字段,其中Linux下sys/stat.h中还定义了如下判断文件类型的宏:

    /* Test macros for file types.  */
    
    #define __S_ISTYPE(mode, mask)  (((mode) & __S_IFMT) == (mask))
    
    #define S_ISDIR(mode)    __S_ISTYPE((mode), __S_IFDIR)
    #define S_ISCHR(mode)    __S_ISTYPE((mode), __S_IFCHR)
    #define S_ISBLK(mode)    __S_ISTYPE((mode), __S_IFBLK)
    #define S_ISREG(mode)    __S_ISTYPE((mode), __S_IFREG)
    #ifdef __S_IFIFO
    # define S_ISFIFO(mode)  __S_ISTYPE((mode), __S_IFIFO)
    #endif
    #ifdef __S_IFLNK
    # define S_ISLNK(mode)   __S_ISTYPE((mode), __S_IFLNK)
    #endif
    
    #if defined __USE_BSD && !defined __S_IFLNK
    # define S_ISLNK(mode)  0
    #endif
    
    #if (defined __USE_BSD || defined __USE_UNIX98 || defined __USE_XOPEN2K) && defined __S_IFSOCK
    # define S_ISSOCK(mode) __S_ISTYPE((mode), __S_IFSOCK)
    #elif defined __USE_XOPEN2K
    # define S_ISSOCK(mode) 0
    #endif

    2 stat函数

    在linux的<sys/stat.h>文件中存在如下的三个函数,这三个函数都是用于查看一个文件的文件的属性信息,其中stat()和fstat()函数在Windows的头文件也进行了定义:

    #include <sys/stat.h>
    int stat(const char *path, struct stat *buf);
    int fstat(int fd, struct stat *buf);
    int lstat(const char *path, struct stat *buf);
    				//成功返回0, 出错返回-1

    stat函数返回一个文件的属性信息,fstat返回一个已在fd文件描述符打开的文件的属性信息。lstat是Linux下特有的,返回符合链接文件的信息,而不是所链接文件的信息。

    下面一段文字是摘自维基百科关于文件描述符的介绍:”文件描述符在形式上是一个非负整数。实际上,它是一个索引值,指向内核为每一个进程所维护的该进程打开文件的记录表。当程序打开一个现有文件或者创建一个新文件时,内核向进程返回一个文件描述符。在程序设计中,一些涉及底层的程序编写往往会围绕着文件描述符展开。但是文件描述符这一概念往往只适用于UNIX、Linux这样的操作系统。”

    下面一段代码是对stat的测试,在Windows和Linux下都可以运行:

    #include <iostream>
    #include <string>
    #include <ctime>
    
    #include <sys/stat.h>
    
    using namespace std;
    
    void printStat(struct stat *statBuf)
    {
    	if(statBuf == NULL)
    		return;
    
    	cout<<"stat.st_dev:"<<statBuf->st_dev<<endl;
    	cout<<"stat.st_ino:"<<statBuf->st_ino<<endl;
    	cout<<"stat.st_mode:"<<statBuf->st_mode<<endl;
    	cout<<"stat.st_nlink:"<<statBuf->st_nlink<<endl;
    	cout<<"stat.st_uid:"<<statBuf->st_uid<<endl;
    	cout<<"stat.st_gid:"<<statBuf->st_gid<<endl;
    	cout<<"stat.st_rdev:"<<statBuf->st_rdev<<endl;
    	cout<<"stat.st_size:"<<statBuf->st_size<<endl;
    	cout<<"stat.st_atime:"<<ctime(&statBuf->st_atime);
    	cout<<"stat.st_ctime:"<<ctime(&statBuf->st_ctime);
    	cout<<"stat.st_mtime:"<<ctime(&statBuf->st_mtime);
    }
    
    int main()
    {
    	struct stat fileInfoBuf;
    	string fileName;
    
    	while(1)
    	{
    		cout<<"please input the file path:";
    		cin>>fileName;
    
    		if(stat(fileName.c_str(), &fileInfoBuf) < 0)
    		{
    			cout<<"cann't get the information of file "<<fileName<<endl;
    			continue;
    		}
    	
    		printStat(&fileInfoBuf);
    	}
    
    	return 0;
    }
    

    3 Linux目录读取

    目录的读取操作设计到具体的系统实现,C和C++都没有这方面的标准库。Windows和Linux下对目录的操作都不一样。Linux下面提供了下面的函数来进行目录的读取操作,其中前面三个是最常用的:

    #include <dirent.h>
    DIR *opendir(const char *name);
    struct dirent *readdir(DIR *dirp);
    			//成功返回指针,失败返回NULL
    int closedir(DIR *dirp);
    			//成功返回0,失败返回-1
    void rewinddir(DIR *dirp);
    void seekdir(DIR *dirp, long offset);
    long telldir(DIR *dirp);
    			//成功返回当前条目的位置,失败返回-1

    opendir()用于打开一个目录,如果打开成功则会返回一个DIR指针,该指针指向已打开的目录流。该目录流被定位到该目录的第一个条目。如果失败这返回NULL。

    readdir()用于读取已打开目录中的条目。如果读取成功则返回一个dirent结构指针,该结构保存的是目录流所定位的目录中第n个条目的内容信息,并使DIR指针指向下一个目录条目。如果目录读取完毕或者出错返回NULL。

    rewinddir()用于将DIR指针重新定位到目录的第一个条目。

    seekdir()用于设置DIR所指向的目录流的位置,以提供给readdir()使用。Offset参数一般是根据telldir()获得的。

    telldir()返回当前DIR指向目录流所在的位置,该位置是相对于目录的第一个条目而言的。

    closedir()用于关闭DIR指针所关联的目录流,即关闭打开的目录。执行该函数后DIR所指向的结构将失效。

    dirent的结构定义如下:

    #include <bits/dirent.h>
    struct dirent {
    	ino_t d_ino;	/* inode number */
    	off_t d_off;	/* offset to the next dirent */
    	unsigned short d_reclen; /* length of this record */
    	unsigned char  d_type;   /* type of file; not supported by all file system types */
    	char d_name[256];	 /* filename */
    };

    其中d_inod_name字段是POSIX标准所规定必须定义的字段。其中d_type字段的取值有如下:

    #include <dirent.h> 
    DT_BLK      This is a block device.
    DT_CHR      This is a character device.
    DT_DIR      This is a directory.
    DT_FIFO     This is a named pipe (FIFO).
    DT_LNK      This is a symbolic link.
    DT_REG      This is a regular file.
    DT_SOCK     This is a Unix domain socket.
    DT_UNKNOWN  The file type is unknown.

    下面是测试代码,遍历指定目录下的文件名:

    #include <iostream>
    #include <cstring>
    
    #include <dirent.h>
    
    using namespace std;
    
    void FileHandle(string filePath)
    {
    	cout<<filePath<<endl;
    }
    
    int DirProcess(string dirPath)
    {
    	DIR *pDir;
    	struct dirent *pDirent;
    
    	pDir = opendir(dirPath.c_str());
    	if(pDir == NULL)
    	{
    		cout<<dirPath<<" is not directory..."<<endl;
    		return -1;
    	}
    
    	while((pDirent = readdir(pDir)) != NULL)
    	{
    		//ignore the hidden directory "." & ".."
    		if(strcmp(pDirent->d_name, ".") == 0 || strcmp(pDirent->d_name, "..") == 0)
    			continue;
    
    		//judge the directory entry is a directory or not
    		if(pDirent->d_type == DT_DIR)
    		{//recursive process the directory
    			DirProcess(dirPath + '/' + pDirent->d_name);
    		}
    		else
    		{
    			 FileHandle(dirPath + '/' + pDirent->d_name);
    		}
    	}
    
    	closedir(pDir);
    
    	return 0;
    }
    
    int main(int argc, char **argv)
    {
    	if(argc == 1)
    	{
    		cout<<".:"<<endl;
    		DirProcess(string("."));
    	}
    	else
    	{
    		for(int i = 1; i < argc; ++i)
    		{
    			cout<<argv[i]<<":"<<endl;
    			DirProcess(string(argv[i]));
    		}
    	}
    }

    4 Windows目录读取

    Windows下面的目录读取,底层的操作需要用到下面三个函数:

    #include <io.h>
    long _findfirst( char *filespec, struct _finddata_t *fileinfo );
    int _findnext(long handle, struct _finddata_t *fileinfo);
    int _findclose(long handle);

    下面先介绍需要使用到的数据结构_finddata_t,该数据结构用于存储文件的相关信息。它的定义如下:

    #include <io.h>
    struct _finddata_t {
            unsigned    attrib; /*文件的属性字段,下面详细介绍*/
            __time32_t  time_create;	/* -1 for FAT file systems */
            __time32_t  time_access;	/* -1 for FAT file systems */
            __time32_t  time_write;
            _fsize_t    size;		/*文件的大小*/
            char        name[260];		/*文件名*/
    };

    其中attrib字段用于标识文件的属性,用位来进行标识,具体的值对应的属性如下:

    /* File attribute constants for _findfirst() */
    #define _A_NORMAL       0x00    /* Normal file - No read/write restrictions */
    #define _A_RDONLY       0x01    /* Read only file */
    #define _A_HIDDEN       0x02    /* Hidden file */
    #define _A_SYSTEM       0x04    /* System file */
    #define _A_SUBDIR       0x10    /* Subdirectory */
    #define _A_ARCH         0x20    /* Archive file */

    可以看出来,_finddata_t数据结构的元素除了name字段外,在stat数据结构中都存在。_finddata_t结构相对简单,是专门用来进行文件搜索使用的数据结构,匹配文件搜索的函数使用(_findfirst, _findnext, _findclose)。

    下面将详细介绍上面三个函数:

    _findfirst()用于搜索与指定的文件名称匹配的第一个实例,若成功则返回第一个实例的句柄,否则返回-1L。文件名filespec可以包含通配符:’*’(任意多个字符)和’?’(任意一个字符)。使用方式可以如下:

    struct _finddata_t fileInfo;
    _findfirst(“./*”), &fileInfo)) 		//搜索当前目录下的所有文件
    _findfirst(“./*.txt”), &fileInfo)) 	//搜索当前目录下的所有txt文件

    _findnext()用于搜索与_findfirst()函数提供的文件名称匹配的下一个实例,若成功则返回0,否则返回-1。

    _findclose()用于关闭指定搜索句柄并释放关联的资源。

    下面是测试代码,遍历指定目录下的文件名:

    #include <iostream>
    #include <cstring>
    #include <string>
    #include <vector>
    
    #include <io.h>
    
    using namespace std;
    
    void FileHandle(string filePath)
    {
    	cout<<filePath<<endl;
    }
    
    int DirProcess(string dirPath)
    {
    	long handle;
    	struct _finddata_t fileInfo;
    	
    	dirPath += "/*";
    	
    	if ((handle = _findfirst(dirPath.c_str(), &fileInfo)) == -1)
    	{
    		cout<<dirPath<<" is not directory..."<<endl;
    		return -1;
    	}
    
    	do 
    	{
    		//ignore the hidden directory "." & ".."
    		if(strcmp(fileInfo.name, ".") == 0 || strcmp(fileInfo.name, "..") == 0)
    			continue;
    
    		if (fileInfo.attrib & _A_SUBDIR)
    		{//is a directory
    			DirProcess(string(fileInfo.name));
    		}
    		else
    		{//is a normal file
    			FileHandle(string(fileInfo.name));
    		}
    	} while (_findnext(handle, &fileInfo) == 0);
    
    	_findclose(handle);
    
    	return 0;
    }
    
    int main(int argc, char **argv)
    {
    	if(argc == 1)
    	{
    		cout<<".:"<<endl;
    		DirProcess(string("."));
    	}
    	else
    	{
    		for(int i = 1; i < argc; ++i)
    		{
    			cout<<argv[i]<<":"<<endl;
    			DirProcess(string(argv[i]));
    		}
    	}
    
    	system("pause");
    }

    5 低级文件操作

    Windows下面<io.h>文件中定义了一些低级的文件操作和I/O函数。这些函数都是符合POSIX标准的,所以和Linux的同名函数功能上都是相似的。下面是<io.h>中的主要定义的函数:

    int access(const char * _Filename, int _AccessMode);
    int chmod(const char * _Filename, int _AccessMode);
    int chsize(int _FileHandle, long _Size);
    int close(int _FileHandle);
    int creat(const char * _Filename, int _PermissionMode);
    int dup(int _FileHandle);
    int dup2(int _FileHandleSrc, int _FileHandleDst);
    int eof(int _FileHandle);
    long filelength( int _FileHandle);
    int isatty(int _FileHandle);
    int locking(int _FileHandle, int _LockMode, long _NumOfBytes);
    long lseek(int _FileHandle, long _Offset, int _Origin);
    char * mktemp(char * _TemplateName);
    int open(const char * _Filename, int _OpenFlag, ...);
    int read(int _FileHandle, void * _DstBuf, unsigned int _MaxCharCount);
    int setmode(int _FileHandle, int _Mode);
    int sopen(const char * _Filename,int _OpenFlag, int _ShareFlag, ...);
    long tell(int _FileHandle);
    int umask(int _Mode);
    int write(int _Filehandle, const void * _Buf, unsigned int _MaxCharCount);
    

    Create Time:Nov. 30, 2013

    Last Modified Date:Nov. 30, 2013

    展开全文
  • 上一篇将了如何去获取一个文件的文件属性,那么我们有些时候还要对一个文件进行设置其文件属性值。 比方说:我在服务器上下载一个文件,我要求下载的文件属性要和服务器上的文件属性一致。 那么我们就要对下载后的...

    上一篇将了如何去获取一个文件的文件属性,那么我们有些时候还要对一个文件进行设置其文件属性值。

    比方说:我在服务器上下载一个文件,我要求下载的文件属性要和服务器上的文件属性一致。

    那么我们就要对下载后的文件进行修改其文件属性参数了。

    那么怎么修改呢?

    BOOL SetFileAttributes(time_t  createTime, time_t accessTime, time_t  modifyTime)

    {

    CFile cfile;
    CFileStatus  status;
    if(!cfile.GetStatus(status))
    {
    //AfxMessageBox("获取文件属性失败!!!");
    return false;
    }

    status.m_ctime =  createTime;
    status.m_atime =  accessTime;
    status.m_mtime = modifiTime;
    status.m_attribute = 0x00; //文件正常(主要考虑权限问题)

    try
    {
    cfile.SetStatus(strpath, status);         //设置文件属性
    }

    catch(CFileException e)
    {
    char buf[256];
    e.GetErrorMessage(buf,256);
    //AfxMessageBox(buf);

    return false;
    }

    return true;

    }

    好了,今天的修改文件属性就介绍到这里,如果大家有什么不懂的或者我哪里说错了请及时联系我,新浪邮箱:chao_song2011@sina.cn    不胜感激!!!

    展开全文
  • windows常用文件操作dos命令

    千次阅读 多人点赞 2019-07-15 12:50:12
    文章目录dir 命令文件、目录(创建、修改、删除、复制、移动)创建目录创建文件,查看、追加、修改文件内容删除文件删除目录修改、替换目录或文件名复制、移动文件、目录复制移动other常用、实用的DOS命令 windows dos...
  • 文章目录find 在文件中搜索字符串。findstr 在文件中寻找字符串。where 显示符合搜索模式的文件位置 在文件中搜索指定字符串时,建议使用findstr而非find. 查找文件位置的命令用where. find 在文件中搜索字符串。 ...
  • 基于QT+Linux/Windows的简易文件管理器

    热门讨论 2013-09-08 23:16:59
    基于QT+Linux的简易文件管理器 包括文件(夹)的创建删除复制粘贴等
  • 1.点—此电脑右键—管理—服务—Windows update右键属性—自动启动—确定 –右键启动 ok 主要是Windows 更新关闭了
  • 文件属性----解除锁定(Windows

    万次阅读 2014-03-27 09:18:26
    从坊间上下载来了不少.chm文件,可以刚开始打开,以为是没有插件,可是之前在电脑上的.chm文件都可以正常打开了,最后让我阅网无数,才发现时由于文件属性-----解除锁定在作怪,可是自己下了很多文件,能这样一...
  • Linux文件属性详解

    千次阅读 2019-05-05 12:05:16
    文件存储在硬盘上,硬盘的最小存储单位叫做"扇区"(sector)。每个"扇区"的大小为512字节(byte), ,操作系统读取硬盘的时候,不会一个个扇区的读取,这样效率太慢。他是一次性读取多个扇区,即一次性读取一个...
  • 最近 工作中用到windows的脚本命令处理文件,这里记录一下; 首先是xcopy, 这个命令我们可以在cmd里去使用 xcopy/? 查看帮助文档; C:\Users\Administrator>xcopy/? 复制文件和目录树。 XCOPY source ...
  • Windows文件系统审核的完整指南

    千次阅读 2020-02-03 11:30:40
    Windows文件系统审核是保留在网络安全取证工具箱的重要工具。 继续阅读以了解有关Windows上的文件系统审核的更多信息,以及为什么需要替代解决方案来获取可用的文件审核数据的信息。 审核文件系统的原因 如何...
  • windows文件权限管理dos命令

    万次阅读 2019-07-15 13:07:31
    文章目录前言windows dos 文件权限操作命令:Icacls or Cacls。Cacls示例Icacls详细示例1.ICACLS /save & /restore2. ICACLS /setownerwindows sid 简介及相关的whoami dos命令3. ICACLS /findsid4. ICACLS /...
  • Windows 10 no longer has built-in help for File Explorer, as Windows 7 does. Microsoft makes you search the web for information, so here’s what you need to know about using Windows 10’s file manager...
  • Windows中文件夹属性加密的作用?

    万次阅读 2012-10-09 14:24:28
    文件属性里的加密功能是非常有用的。你自己依然能打开能改写那是因为这个文件是你自己用户名建立的,加密也是你自己加密的,为方便起见,自然支持你改写。但是如果其他用户不是用的你用户名登陆Windows系统,那么被...
  • Windows Server2012R2文件服务器安装与配置

    万次阅读 多人点赞 2019-10-11 13:08:45
    为了配合文件服务器的权限管理,从Windows Server 2008新增了文件服务器资源管理器,其实在Windows Server 2003里面也有文件服务器资源管理器的功能,只是放于DFS功能模块里面了。 文件服务器资源管理器是一组可让你...
  • Windows驱动开发之文件操作

    千次阅读 2016-07-06 15:02:11
    内核态文件操作 内核态字符串操作 内核态动态内存申请/释放
  • 包含等待某些特殊文件的数据。 -Size of the file in bytes, if it is a regular file or a symbolic link. The size of a symbolic link is the length of the pathname it contains, without a terminating null ...
  • Windows上基于windows.h的文件操作

    千次阅读 2018-08-13 17:00:52
    1._lcreat 函数创建文件 1.1 函数原型: ...lpPathName:文件的名称,该字符串必须包含Windows ANSI字符集中的字符。 iAttribute:文件属性: 值 含义 0 正常。可以读取或写入。 ...
  • Windows AD批量修改用户属性

    千次阅读 2015-10-22 19:54:08
    Windows AD是之前其他人创建的,但是初始创建的一些...好吧,由于三方系统的要求,现在需要往Windows AD添加EmployeeID字段,将大概1200的EmployeeID添加到AD用户信息去,做完之后,记下操作流程,以免类似的杯具重
  • 微软官方免费数据恢复工具Windows File Recovery Windows File Recovery是由微软推出的一款免费的文件数据恢复工具,这款工具可以用来恢复那些被删除的文件,或者从格式化或损坏的硬盘、储存卡恢复文件
  • Windows系统中文件大小和占用空间不同的原因解析 1.“文件大小”与“所占空间”的差别  为了便于大家理解,我们先来看两个例子: 例1:找到D盘上的Ersave2.dat文件,用鼠标右键单击该文件,选择“属性”,即可...
  • 简述在 Qt 之 WAV文件解析 给出了WAV文件属性的计算,具体包括文件大小、音频时长、比特率等属性,这里我们再次验证一下这些属性值的计算 。在计算之前,我们要知道一下wav文件的三个参数 采样频率、音频通道数...
  • linux及windows文件共享

    万次阅读 2016-07-02 20:44:57
    http://blog.csdn.net/pipisorry/article/details/51812022本文主要说明 linux和windows文件共享, ...(ubuntu16.04, 14.04和win7测试通过)linux和windows文件共享window对linux文件内容进行操作,利用linux samba
  • 相对于DOSBox而言PCem对Windows 98的支持性要好上太多,这也就是为什么博主把Windows 95和Windows 98拆到两个平台来写的原因,而且相对于DOSBox复杂难懂的配置文件,PCem明显就友好很多,简直是小清新啊。...
  • maven的pom文件中Properties属性

    千次阅读 2020-02-21 16:57:05
    Maven属性是值占位符,就像Ant属性一样。它们的值可以通过使用${X}符号在POM的任何地方访问,其中X是属性。或者它们可以被插件用作默认值,例如 <project> ... <properties> <maven....
  • Windows系统在安装虚拟机centos系统之后,如何进行两者之间的文件传输和互操作,或者如何在Windows端使用Xshell对Linux端进行远程操作?使用centos的文件上传下载小工具,可以快速的帮助我们从本地上传文件至Linux...
  • 同学让我帮忙处理数据,但是有365天的数据也就是365个文件夹,整体文件好几十个G,但是每个文件夹有用的文件只有几个且很小,于是就准备写一个脚本文件对其进行批处理,反正也没学过,就搜集资料搞吧,搞好了详细...
  • Linux最多的一种文件类型, 包括 纯文本文件(ASCII);二进制文件(binary);数据格式的文件(data);各种压缩文件.第一个属性为 [-] 目录文件 就是目录, 能用 # cd 命令进入的。第一个属性为 [d],例如 [drwxrwxrwx] ...
  • windows PE文件结构及其加载机制

    万次阅读 多人点赞 2016-04-29 15:00:50
    1. 概述PE文件的全称是Portable Executable,意为可移植的可执行的文件,常见的EXE、DLL、OCX、SYS、COM都是PE文件,PE文件是微软Windows操作系统上的程序文件(可能是间接被执行,如DLL)。它是1993年Windows NT...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 411,499
精华内容 164,599
关键字:

windows98中文件的属性不包括