Linux环境编程 day03 文件同步、修改权限、大小、软硬链接、目录

dup和dup2

int dup(int oldfd);
功能:复制文件描述符
oldfd:已经打开了的文件描述符
返回值:系统随机返回一个新的文件描述述newfd,但与oldfd代表同一个内核对象。
当对oldfd和newfd进行读写时,访问的是同一个文件。

int dup2(int oldfd, int newfd);
功能:按指定的newfd复制文件描述符
如果newfd已经被占用,则把它关闭重新复制。
在记录软件的日志经常使用(非常好用),能解决复杂的问题。
返回值:成功返回0,失败返回-1。

fcntl

int fcntl(int fd, int cmd, ... /* arg */ );
功能:
    1、复制文件描述符
    2、获取或追加文件状态标志
    3、添加或获取文件锁
fd: 被操作的文件描述符
cmd:
    F_DUPFD 复制文件描述符,返回一个没有使用过的最小的一个文件描述符。
    F_GETFD 获取文件状态标志
    F_SETFD 追加文件状态标志
        O_RDONLY,O_WRONLY, O_RDWR,O_CREAT, O_EXCL, O_NOCTTY, O_TRUNC无法设置。
        仅支持O_APPEND, O_ASYNC, O_DIRECT,O_NOATIME, and O_NONBLOCK。
    F_SETLK 设置锁的状态为 F_RDLCK、F_WRLCK、F_UNLCK,            成功返回0,失败返回-1。
    F_SETLKW 设置锁的状态为 F_RDLCK、F_WRLCK、F_UNLCK,成功返回0,如果无法加锁,则一直等待,除非被信号打断。
    F_GETLK 设置测试锁,如果可以设置则设置,如果不能设置则返回返回锁的状态。
    文件锁是让多个程序同时和平访问一个的的方法。
struct flock {
    short l_type;    锁的类型F_RDLCK,F_WRLCK, F_UNLCK
    short l_whence;  加锁内存的基础位置SEEK_SET, SEEK_CUR, SEEK_END
    off_t l_start;   偏移植
    off_t l_len;     锁的长度
    pid_t l_pid;     加锁的进程
};
读锁  读锁  Ok
读锁  写锁  NO
写锁  写锁  NO
Linux系统默认的是劝谏锁(协议),防君子不能防小人。
添加锁的三种方式:
    F_SETLK 直接加,成功或失败
    F_SETLKW 不成功则一直等待直到成功
    F_GETLK 加测试锁 

文件同步

1、大多数磁盘的IO都通过缓冲进行了,写入文件其实是写入缓冲区,直到缓冲区(此缓冲区不是标准C的缓冲区)满才排除写入磁盘。

2、缓冲区机制降低了写操作的次数,提高了写作效率,但可能 导致磁盘文件与缓冲区数据不同步。

3、sync/fsync/fdatasync用于强制把缓冲区的数据同步到磁盘中。
void sync(void);
sync是把所有缓冲区的数据排队写入磁盘,不等待完成就直接返回了。

int fsync(int fd);
fsync只针对一个文件,直致缓冲区中的数据全部写入磁盘才返回。

int fdatasync(int fd);
fdatasync只同步文件的数据,不同步属性。

获取文件属性

int stat(const char *path, struct stat *buf);
功能:根据文件的路径来获取文件的属性

int fstat(int fd, struct stat *buf);
功能:根据文件描述符来获取文件的属性

int lstat(const char *path, struct stat *buf);
功能:获取链文件的属性

struct stat {
    dev_t     st_dev;   文件的设备ID
    ino_t     st_ino;   文件的节点号
    mode_t    st_mode;  文件的类型和权限
    nlink_t   st_nlink; 硬链接数量
    uid_t     st_uid;   属主ID(文件的拥有者的用户ID)
    gid_t     st_gid;   属组ID(文件的拥有者的用户组ID)
    dev_t     st_rdev;  特殊设备ID
    off_t     st_size;  文件的总字节数
    blksize_t st_blksize; I/O块数
    blkcnt_t  st_blocks;  以512字节为一块,占多少块
    time_t    st_atime;   最后访问时间
    time_t    st_mtime;   最后的修改时间
    time_t    st_ctime;   最后状态修改时间
};

st_mode
       S_IFSOCK   套接字文件
       S_IFLNK    软链接文件
       S_IFREG    普通文件
       S_IFBLK    块设备文件
       S_IFDIR    目录
       S_IFCHR    字符设备文件
       S_IFIFO    管道文件
       S_ISUID    属主沾滞位标志(一般合并在执行权限上)
       S_ISGID    属组沾滞位标志
       S_ISVTX    其它沾滞位标志  
       S_IRWXU    属主的读写执行权限
       S_IRUSR    属主的读权限
       S_IWUSR    属主的写权限
       S_IXUSR    属主的执行权限
       S_IRWXG    属组的读写执行权限
       S_IRGRP    属组的读权限
       S_IWGRP    属组的写权限
       S_IXGRP    属组的执行权限
       S_IRWXO    其它的读写执行权限
       S_IROTH    其它的读权限
       S_IWOTH    其它的写权限
       S_IXOTH    其它的执行权限

帮助判断文件类型的宏函数:
    S_ISREG(m)  普通文件        -
    S_ISDIR(m)  目录文件        d
    S_ISCHR(m)  字符设备文件    c
    S_ISBLK(m)  块设备文件      b
    S_ISFIFO(m) 管道文件        p
    S_ISLNK(m)  软链接文件      l
    S_ISSOCK(m) 套接字文件      s

struct passwd *getpwuid(uid_t uid);
功能:根据用户ID获取用户信息

struct group *getgrgid(gid_t gid);
功能:根据组ID获取组信息

测试文件权限

int access(const char *pathname, int mode);
功能:测试文件是否具有某个权限
pathname:文件和路径
mode:被测试的权限
    F_OK    文件是否存在
    R_OK    文件是否有读权限
    W_OK    文件是否有写权限
    X_OK    文件是否有执行权限
返回值:有则返回0,没有则返回-1

权限屏蔽码

当创建文件时设置文件的权限会被权限屏蔽码过滤一下。
mode_t umask(mode_t mask);
功能:为当前进程设置权限屏蔽码,并返回之前的权限屏蔽码,该函数永远成功。

注意:一旦设置完成,当前进行所创建的文件都不具有权限屏蔽码所包括的权限,只对当前进程有效。
注意:chmod命令不受权限屏蔽码的影响。

修改文件的权限

int chmod(const char *path, mode_t mode);
功能:根据文件的路径修改文件的权限 

int fchmod(int fd, mode_t mode);
功能:根据文件描述符修改文件的权限

chmod函数和命令都不受权限屏蔽码的影响。

修改文件的大小

int truncate(const char *path, off_t length);
功能:根据文件的路径修改文件的大小
返回值:成功返回0,失败返回-1

int ftruncate(int fd, off_t length);
功能:根据文件描述符修改文件的大小
返回值:成功返回0,失败返回-1

注意:从大往小改,丢弃末尾的数据,从小往大改补0。

创建硬链接删除硬链接

int link(const char *oldpath, const char *newpath);
功能:创建硬链接文件
返回值:成功返回0,失败返回-1

int unlink(const char *pathname);
功能:删除链接硬文件
返回值:成功返回0,失败返回-1

注意:普通文件就是硬链接数为1的文件,因此unlink也可能用于删除普通文件。

文件的删除与重命名

int remove(const char *pathname);
功能:删除文件
返回值:成功返回0,失败返回-1

int rename(const char *oldpath, const char *newpath);
功能:重命名文件
返回值:成功返回0,失败返回-1

remove与unlink的区别是什么?
    remove与unlink在删除普通文件时没有任何区别。
    但remove可以删除目录(空目录),unlink不行。

软链接文件

int symlink(const char *oldpath, const char *newpath);
功能:创建软链接文件

ssize_t readlink(const  char *path, char *buf, size_t
   bufsiz);
功能:读取软链接文件本身的内容,使用open打开软链接文件打开的是链接目标,而不是软链接文件本身。
返回值:成功读取到的字节数

注意:硬链接就是个文件名,就是目录表中的一个条目,软链接是一个独立的文件,内容是链接目标的路径信息。

目录文件

int mkdir(const char *pathname, mode_t mode);
功能:创建目录
pathname:目录的路径
mode:目录的权限,必须要有执行权限,否则无法进入。
返回值:成功返回0,失败返回-1

int rmdir(const char *pathname);
功能:删除目录,只能删除空目录
返回值:成功返回0,失败返回-1
注意:rmdir与remove的区别是,remove既可以删除普通文件也可以删除空目录,而rmdir只能删除空目录。

工作目录

就是可以不加路径直接使用文件名就可以操作当前目录下的文件,一般默认程序运行时所在的目录就是工作目录。
char *getcwd(char *buf, size_t size);
功能:获取当前工作目录
buf:存储工作目录的路径
size:buf的容量

int chdir(const char *path);
功能:修改当前工作目录,只针对当前进程有效,类似cd命令。

int fchdir(int fd);
功能:根据文件描述符修改当前的工作目录,该描述符对应的必须是目录文件。

目录流

对目录流的操作就是读取目录下的每个条目,以及调整目录流的位置指针,是专门对目录文件的操作。

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

DIR *opendir(const char *name);
功能:根据路径打开目录文件
返回值:目录流(相当于链表)

DIR *fdopendir(int fd);
功能:根据目录文件的描述符获取目录流

struct dirent *readdir(DIR *dirp);
功能:从目录流中读取一个条目

条目信息包括:
struct dirent {
    ino_t          d_ino;       i节点号
    off_t          d_off;       下一个条目的偏移量
    unsigned short d_reclen;    条目的长度   
    unsigned char  d_type;      文件的类型              
    char           d_name[256]; 文件名
}

文件类型:
    DT_BLK      块设备文件
    DT_CHR      字符设备文件
    DT_DIR      目录文件
    DT_FIFO     管道文件
    DT_LNK      链接文件
    DT_REG      普通文件
    DT_SOCK     套接字文件
    DT_UNKNOWN  未知类型


void rewinddir(DIR *dirp);
功能:把目录流的位置指针调整到开头。

long telldir(DIR *dirp);
功能:返回当前目录流的位置指针指向了第几个条目

void seekdir(DIR *dirp, long offset);
功能:设置目录流的位置指针
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值