Linux: 文件操作
int open (const char *pathname,int flags) ;
int open (const char *pathname,int flags,mode_t mode) ;
int close (int fd);
ssize_t read(int fd, void *buf,size_t count) ;
ssize_t write(int fd,const void *buf, size_t count) ;
off_t lseek (int fd, off_t offset, int whence) ;
int stat (const char *pathname,struct stat *statbuf);
int lstat (const char *pathname,struct stat *statbuf) ;
/*
- pathname: 要创建的文件的路径
- flags: 对文件的操作权限和其他的设置
-必选项:O_RDONLY, O_WRONLY,O_RDWR这三个之间是互斥的
-可选项:O_CREAT文件不存在,创建新文件
- mode: 八进制的数,表示用户创建出的新的文件的操作权限
- fd : 文件描述符
-buf: 读写的中间容器
-count:buf的大小:sizeof(buf)
-offset: 偏移量
- whence:
SEEK_SET:
设置文件指针的偏移量
SEEK_CUR:
设置偏移量:当前位置+第二个参数offset的值
SEEK_END:
设置偏移量:文件大小+第二个参数offset的值
返回值:返回文件指针的位置。
作用:
1.移动文件指针到文件头:
lseek(fd, e,SEEK_SET);
2.获取当前文件指针的位置:
lseek(fd, 0,SEEK_CUR);
3,获取文件长度:
lseek(fd, 0, SEEK_END);
4,拓展文件的长度:10b-->110b
lseek(ld, 100, SEEK_END);
*/
将文件China.txt 复制到 cpy.txt
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
int main(){
//通过 open打开文件 只读
int srcfd = open("China.txt", O_RDONLY);
if(srcfd == -1){
perror("open");
return -1;
}
//创建新文件
int desfd = open("cpy.txt", O_WRONLY|O_CREAT, 0664);
if(desfd == -1){
perror("create");
return -2;
}
//频繁的读写操作
char buff[1024] = {
0};
int len = 0;
while((len = read(srcfd, buff, sizeof(buff))) > 0){
write(desfd, buff, len);
}
//关闭文件
close(desfd);
close(srcfd);
return 0;
}
lseek的使用
将文件大小改大。
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
int main(){
int fd = open("China.txt", O_RDWR);
if(fd == -1){
perror("open");
return -1;
}
//拓展文件长度
int ret = lseek(fd, 100, SEEK_END);
if(ret == -1){
perror("lessk");
return -2;
}
//写入数据
write(fd, " ", 1);
//关闭文件
close(fd);
return 0;
}
stat lstat的使用
/*
int stat(const char *pathname, struct stat *statbuf);
作用:获取一个文件相关的一些信息
参数:
-pathname:操作文件的路径
-statbuf: 结构体变量,传出参数,用于保存获取到的文件的信息
返回值:
- 0:成功
- -1:失败并设置errno
=======================================================================
具体信息:
root@ubuntu:/home/carey/Linux/lesson6# stat stat.c
File: stat.c
Size: 0 Blocks: 0 IO Block: 4096 regular empty file
Device: 801h/2049d Inode: 1196991 Links: 1
Access: (0666/-rw-rw-rw-) Uid: ( 0/ root) Gid: ( 0/ root)
Access: 2021-11-16 03:21:12.438363774 -0800
Modify: 2021-11-16 03:20:57.670363717 -0800
Change: 2021-11-16 03:21:07.542363755 -0800
Birth: -
=========================================================================
int lstat(const char *pathname, struct stat *statbuf);
若一个文件为软连接,那么stat查看的是被指向文件的信息
lstat则是此文件的信息
*/
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
int main(){
struct stat statbuf;
int ret = stat("China.txt", &statbuf);
if(ret == -1){
perror("stat");
return -1;
}
printf("size: %ld \n", statbuf.st_size);
return 0;
}
模拟实现 ls -l
/*
模拟实现 ls -l 指令
root@ubuntu:/home/carey/Linux/lesson6# ls -l China.txt
-rw-rw-rw- 1 root root 237 Nov 16 00:42 China.txt
*/
#include <stdio.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <fcntl.h>
#include <unistd.h>
#include <pwd.h>
#include <grp.h>
#include <time.h>
#include <string.h>
int main(int argc, char *argv[]){
//判断输入的参数是否正确
if(argc < 2){
printf("%s filename \n",argv[0]);
return -1;
}
//通过stat函数获取用户传入文件的信息
struct stat st;
int ret = stat(argv[1], &st);
if(ret == -1){
perror("stat");
return -2;
}
//获取文件类型 和 文件权限
char perms[11] = {
0};
switch(st.st_mode & S_IFMT){
case S_IFLNK: //符号文件
perms[0] = 'l';
break;
case S_IFDIR: //目录文件
perms[0] = 'd';
break;
case S_IFREG: //普通文件
perms[0] = '-';
break;
case S_IFBLK: //块设备文件
perms[0] = 'b';
break;
case S_IFCHR: //字符文件
perms[0] = 'c';
break;
case S_IFSOCK: //套接字文件
perms[0] = 's';
break;
case S_IFIFO: //管道文件
perms[0] = 'p';
break;
default:
perms[0] = '?';
break;
}
//判断文件权限
//文件所有者
perms[1] = (st.st_mode & S_IRUSR) ? 'r' : '-';
perms[2] = (st.st_mode & S_IWUSR) ? 'w' : '-';
perms[3] = (st.st_mode & S_IXUSR) ? 'x' : '-';
//文件所在组权限
perms[4] = (st.st_mode & S_IRGRP) ? 'r' : '-';
perms[5] = (st.st_mode & S_IWGRP) ? 'w' : '-';
perms[6] = (st.st_mode & S_IXGRP) ? 'x' : '-';
//文件所在组权限
perms[7] = (st.st_mode & S_IROTH) ? 'r' : '-';
perms[8] = (st.st_mode & S_IWOTH) ? 'w' : '-';
perms[9] = (st.st_mode & S_IXOTH) ? 'x' : '-';
//硬链接数
int linkNum = st.st_nlink;
//文件所有着
char *fileUser = getpwuid(st.st_uid) -> pw_name;
//文件所在组
char *fileGrp = getgrgid(st.st_gid) -> gr_name;
//文件大小
long int fileSize = st.st_size;
//修改时间
char *time = ctime(&st.st_mtime);
char mtime[512] = {
0};
strncpy(mtime, time, strlen(time)-1);
char buf[1024];
sprintf(buf, "%s %d %s %s %ld %s %s", perms, linkNum, fileUser, fileGrp, fileSize, mtime, argv[1]);
printf("%s \n", buf);
return 0;
}