文件操作
C库函数与系统函数
虚拟地址空间
Linux每一个运行的程序(进程), 操作系统都会为其飞培一个0~4G(32位操作系统)的地址空间(虚拟地址空间)
open/close
#include <unistd.h>
int close(int fd);
#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);
flags
必选: O_RDONLY, O_WRONLY, or O_RDWR
可选:
O_CREAT: 创建文件时检测文件是否存在: O_EXCL, 如果存在则返回-1, 必须如O_CREAT一起使用
O_APPEND: 追加文件
O_TRUNC: 文件截断
O_NONBLOCK: 设置非阻塞
mode: 权限并不是传进去的值, 而是mode & ~umask
, 创建文件未指定时会随机指定一个数(垃圾值)
zyb@server:~/dir_test_1$ cat open.c
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
int main(int argc, const char *argv[]) {
int fd = open("haha", O_RDWR | O_CREAT, 0777);
if (fd == -1) {
printf("打开失败\n");
}
close(fd);
return 0;
}
zyb@server:~/dir_test_1$ gcc open.c -o open
zyb@server:~/dir_test_1$ ./open
zyb@server:~/dir_test_1$ ll
total 24
drwxrwxr-x 2 zyb zyb 4096 4月 10 17:12 ./
drwxr-xr-x 20 zyb zyb 4096 4月 10 17:12 ../
-rwxrwxr-x 1 zyb zyb 0 4月 10 17:12 haha*
-rwxrwxr-x 1 zyb zyb 8704 4月 10 17:12 open*
-rw-rw-r-- 1 zyb zyb 269 4月 10 17:12 open.c
read
#include <unistd.h>
ssize_t read(int fd, void *buf, size_t count);
参数:
fd: open的返回值
buf: 缓冲区, 存储要读取的数据
count: 缓冲区能存储的最大字节数sizeof(buf)
返回值:
失败: -1
成功: >0
读出的字节数; =0
文件读完了
write
#include <unistd.h>
ssize_t write(int fd, const void *buf, size_t count);
参数:
fd:
buf: 要写到文件的数据
count: strlen(buf), 文件数的有效字节数
返回值:
失败: -1
成功: >0
写入到文件的字节数
zyb@server:~/dir_test_2$ cat read_write.c
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <string.h>
#include <fcntl.h>
int main(int argc, char const *argv[])
{
// 打开一个文件
int fd1 = open("haha.txt", O_RDWR);
printf("fd1 = %d\n", fd1);
// 打开另外一个文件, 写操作
int fd2 = open("hehe.txt", O_WRONLY | O_CREAT, 0664);
printf("fd2 = %d\n", fd2);
char buf[4096];
int len = read(fd1, buf, sizeof(buf));
while (len > 0) {
// 写入数据
int ret = write(fd2, buf, len); // 不是能用strlen(buf), strlen以\0为标志来判断字符串
printf("ret = %d\n", ret);
// read
len = read(fd1, buf, sizeof(buf));
}
close(fd1);
close(fd2);
return 0;
}
zyb@server:~/dir_test_2$ ls
haha.txt read_write.c
zyb@server:~/dir_test_2$ gcc read_write.c -o app
zyb@server:~/dir_test_2$ ./app
fd1 = 3
fd2 = 4
ret = 4096
ret = 4096
ret = 4096
ret = 4096
ret = 4096
ret = 4096
ret = 4096
ret = 4096
ret = 4096
ret = 4096
ret = 4096
ret = 3603
zyb@server:~/dir_test_2$ ll
total 120
drwxrwxr-x 2 zyb zyb 4096 4月 10 21:57 ./
drwxr-xr-x 21 zyb zyb 4096 4月 10 21:55 ../
-rwxrwxr-x 1 zyb zyb 8872 4月 10 21:56 app*
-rw-rw-r-- 1 zyb zyb 48659 4月 10 21:54 haha.txt
-rw-rw-r-- 1 zyb zyb 48659 4月 10 21:57 hehe.txt
-rw-rw-r-- 1 zyb zyb 647 4月 10 21:55 read_write.c
lseek
#include <sys/types.h>
#include <unistd.h>
off_t lseek(int fd, off_t offset, int whence);
SEEK_SET
SEEK_CUR
SEEK_END
文件指针移动到头部: lseek(fd, 0, SEEK_SET);
获取文件指针当前位置: int len = lseek(fd, 0, SEEK_CUR);
获取文件长度: int len = lseek(fd, 0, SEEK_END);
文件拓展需要两步骤: 执行步骤1并不改变文件的大小
1. lseek(fd, 1000, SEEK_END);
2. 要有一次写操作write(fd, "a", 1);
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <string.h>
#include <fcntl.h>
int main(int argc, char const *argv[])
{
// 打开一个文件
int fd1 = open("haha.txt", O_RDWR);
printf("fd1 = %d\n", fd1);
if (fd1 == -1) {
perror("open");
}
int len = lseek(fd1, 1000, SEEK_END);
printf("len = %d\n", len);
write(fd1, "a", 1);
close(fd1);
return 0;
}
perror
errno不同值对应不同的错误信息
perror("错误信息")