linux下的文件读写
1, open
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
int open(const char *pathname, int flags);
int open(const char *pathname, int flags, mode_t mode);
- pathname:文件路径和名
- flags
- 必选项
- O_RDONLY:只读
- O_WRONLY:只写
- O_RDWR:读写
- 可选项
- O_APPEND
- O_CREAT
- O_EXCL
- mode:如果是创建文件,则必须指定文件的权限,最好算出来的权限:mode & ~umask
- 必选项
- 返回值:返回最小的可用文件描述符,失败返回-1,并设置errno
例子:模拟touch命令
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
int main(int argc, char* argv[]){
int fd = open(argv[1], O_RDONLY|O_CREAT|O_EXCL, 0666);
close(fd);
return 0;
}
0666 & ~0002 = 0664,所以创建出来的文件的权限是:-rw-rw-r--
2,read
#include <unistd.h>
ssize_t read(int fd, void *buf, size_t count);
- fd:文件描述符
- buf:读到哪里
- conut:读多少个字节
- 返回值
- 失败返回-1,并设置errno
- 如果文件描述符是非阻塞的时候,read不到的时候,返回值也是-1,这个-1不代表read失败,所以要判断errno的值,这时errno的值为【11】,用perror打印出的错误信息是【Resource temporarily unavailable】
- 成功返回实际读到的字节数
- 0代表读到文件的末尾了
3,write
#include <unistd.h>
ssize_t write(int fd, const void *buf, size_t count);
- fd:文件描述符
- buf:从哪里写
- conut:写多少个字节
- 返回值
- 失败返回-1,并设置errno
- 成功返回实际写出去的字节数
- 0代表什么也没写进去
例子:模拟cat命令
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
int main(int argc, char* argv[]){
int fd = open(argv[1], O_RDONLY);
char buf[64] = {0};
int ret = 0;
while((ret = read(fd, buf, sizeof buf)) > 0){
write(STDOUT_FILENO, buf, ret);
}
close(fd);
return 0;
}
4,lseek
#include <sys/types.h>
#include <unistd.h>
off_t lseek(int fd, off_t offset, int whence);
- fd:文件描述符
- offset:偏移的数量
- whence:从哪里开始偏移
- SEEK_SET:文件描述符的开始位置
- SEEK_CUR:文件描述符的当前位置
- SEEK_END:文件描述符的末尾位置
- 返回值
- 成功:返回当前位置到开始位置的长度
- 失败:返回-1,并设置errno
例子1:把字符串“helloworld”写入一个文件,然后读取这个文件,把“helloworld”从文件中读取出来,并打印到终端。
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
int main(int argc, char* argv[]){
int fd = open(argv[1], O_RDWR|O_CREAT, 0666);
write(fd, "helloworld
", 11);
//这里必须使用lseek,来调整文件指针的位置,设置文件指针设置到文件的开始位置。
lseek(fd, 0, SEEK_SET);
char buf[20] = {0};
int ret = read(fd, buf, sizeof buf);
write(STDOUT_FILENO, buf, ret);
close(fd);
return 0;
}
read和write的内幕:虽然read和write的参数里没有,文件指针所在位置的参数,但是,执行read或者write后,文件指针所在位置会被自动调整到:【当前位置+读入或者写入的字节数】的位置。
例子2:计算文件的大小
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>
int main(int argc, char* argv[]){
int fd = open(argv[1], O_RDWR);
//open后,文件指针的位置在文件开头
//因为:lseek返回当前位置到开始位置的长度
//所以用lseek移动到了文件末尾,这时lseek的返回值就是文件的大小
int ret = lseek(fd, 0, SEEK_END);
printf("file size:%d
", ret);
close(fd);
}
例子3:创建文件大小为1024的文件
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>
int main(int argc, char* argv[]){
int fd = open(argv[1], O_WRONLY|O_CREAT, 0666);
//打开后文件指针在文件的开始位置,然后从开始位置移动1023个字节,然后再调用write,
//注意不调用后面的write的话,创建的文件的大小是为0的。
lseek(fd, 1023, SEEK_SET);
write(fd, "a", 1);
close(fd);
}