文件属性操作

stat/lstat

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

stat穿透
lstat不穿透
两者主要的区别在于连接文件

struct stat {
   dev_t     st_dev;         /* ID of device containing file */
   ino_t     st_ino;         /* inode number */
   mode_t    st_mode;        // 文件的类型和存取权限
   nlink_t   st_nlink;       /* number of hard links */
   uid_t     st_uid;         // 用户ID
   gid_t     st_gid;         // 组ID
   dev_t     st_rdev;        /* device ID (if special file) */
   off_t     st_size;        // 文件字节数
   blksize_t st_blksize;     /* blocksize for filesystem I/O */
   blkcnt_t  st_blocks;      /* number of 512B blocks allocated */

   /* Since Linux 2.6, the kernel supports nanosecond
      precision for the following timestamp fields.
      For the details before Linux 2.6, see NOTES. */

   struct timespec st_atim;  /* time of last access */
   struct timespec st_mtim;  // 最后一次修改时间
   struct timespec st_ctim;  /* time of last status change */

#define st_atime st_atim.tv_sec      /* Backward compatibility */
#define st_mtime st_mtim.tv_sec
#define st_ctime st_ctim.tv_sec
};

st_mode: 文件的类型和存取权限

S_IFMT     0170000   bit mask for the file type bit field

S_IFSOCK   0140000   socket
S_IFLNK    0120000   symbolic link
S_IFREG    0100000   regular file
S_IFBLK    0060000   block device
S_IFDIR    0040000   directory
S_IFCHR    0020000   character device
S_IFIFO    0010000   FIFO

S_ISUID     04000   set-user-ID bit
S_ISGID     02000   set-group-ID bit (see below)
S_ISVTX     01000   sticky bit (see below)

S_IRWXU     00700   owner has read, write, and execute permission
S_IRUSR     00400   owner has read permission
S_IWUSR     00200   owner has write permission
S_IXUSR     00100   owner has execute permission

S_IRWXG     00070   group has read, write, and execute permission
S_IRGRP     00040   group has read permission
S_IWGRP     00020   group has write permission
S_IXGRP     00010   group has execute permission

S_IRWXO     00007   others  (not  in group) have read, write, and execute permission
S_IROTH     00004   others have read permission
S_IWOTH     00002   others have write permission
S_IXOTH     00001   others have execute permission

获取文件大小测试

#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>

int main(int argc, char const *argv[])
{
	struct stat st;
	int ret = stat("haha.txt", &st);
	if (ret == -1) {
		perror("stat error");
		exit(-1);
	}

	printf("file size = %d\n", (int)st.st_size);

	return 0;
}

权限测试

#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>

int main(int argc, char const *argv[])
{
	struct stat st;
	int ret = stat("haha.txt", &st);
	if (ret == -1) {
		perror("stat error");
		exit(-1);
	}

	printf("file size = %d\n", (int)st.st_size);

	// 文件类型 --> 判断是否是普通文件
	if ((st.st_mode & S_IFMT) == S_IFREG) {
		printf("这不是一个普通文件\n");
	}

	// 所有者对文件的操作
	if (st.st_mode & S_IRUSR)
		printf("读权限\n");
	if (st.st_mode & S_IWUSR)
		printf("写权限\n");
	if (st.st_mode & S_IXUSR)
		printf("执行权限\n");

	return 0;
}

access

测试当前用户指定文件是否具有某种属性
当前用户, 使用哪个用户调用这个函数, 这个用户就是当前用户

int access(const char *pathname, int mode);

参数:
  pathname: 文件名
  mode: 4种权限 R_OK: 读; W_OK: 写; X_OK: 执行; F_OK: 文件是否存在
返回值:
  0 有某种权限, 或者文件存在
  -1 没有, 或文件不存在

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

int main(int argc, char const *argv[])
{
	if (argc < 2) {
		printf("a.out filename\n");
	}

	int ret = access(argv[1], W_OK);
	if (ret ==  -1) {
		perror("access");
		exit(1);
	}
	printf("You can write this file. \n");

	return 0;
}

chmod

int chmod(const char *pathname, mode_t mode);

参数:
  filename: 文件名
  mode: 文件权限, 八进制数

修改文件所有者和所属组

#include <unistd.h>

int chown(const char *pathname, uid_t owner, gid_t group);

参数:
  pathname:
  owner: 整型值, 用户ID, 在/etc/passwd中
  group: 组ID, 在/etc/group中

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/stat.h>

int main(int argc, char const *argv[])
{
	if (argc < 3) {
		printf("a.out filename mode\n");
	}
	int mode = strtol(argv[2], NULL, 8);
	int	ret = chmod(argv[1], mode);
	if (ret == -1) {
		perror("chmod");
		exit(1);
	}

	ret = chown(argv[1], 1001, 1002);
	if (ret == -1) {
		perror("chown");
		exit(1);
	} 

	return 0;
}

truncate

#include <unistd.h>
#include <sys/types.h>

int truncate(const char *path, off_t length);

参数:
  path: 文件名
  length: 文件最终的大小, 和lseek拓展文件大小相比, 不需要最后写一个字符. 比原来小, 删除后边的buf; 比原来大, 拓展后面的部分添加\0, 显示@字符, 文件空洞

rename

#include <stdio.h>

int rename(const char *oldpath, const char *newpath);
posted @ 2019-04-19 21:48  张飘扬  阅读(303)  评论(0编辑  收藏  举报