Linux系统调用——文件访问
函数用法 | #include <sys/types.h> #include <fcntl.h> int creat(const char *filename, mode_t mode) |
---|---|
函数功能 | 创建文件 filename:创建的文件名 mode:创建模式 常用模式: S_IRUSR 可读 S_IWUSR 可写 S_IXUSR 可执行 S_IXRWU 可读、可写、可执行 |
函数返回值 | 创建成功返回文件描述符 失败返回 -1 并设置errno |
函数用法 | #include <sys/types.h> #include <fcntl.h> int open(const char *filename, int flags) int open(const cahr *filename, int flags, mode_t mode) |
---|---|
函数功能 | 打开文件 filename:要打开或创建的文件名 flags:用来说明此函数的多个选择项 mode:创建模式,仅在创建文件时使用 常用模式: S_IRUSR 可读 S_IWUSR 可写 S_IXUSR 可执行 S_IXRWU 可读、可写、可执行 常用flag选择项: (可同时制定多个,但必须用按位或) O_CREAT 若文件不存在则创建, 需要第三个参数mode配合设定新建文件的权限 O_RDWR 读写打开 O_RDONLY 只读打开 O_WRONLY 只写打开 O_EXCL 如果文件重复则报错 |
函数返回值 | 创建成功返回文件描述符 失败返回 -1 并设置errno |
函数用法 | #include <unistd.h> int close(int fd); |
---|---|
函数功能 | 关闭文件 fd:文件描述符 |
函数返回值 | 成功返回 0 失败返回 -1 并设置errno |
函数用法 | #include <unistd.h> ssize_t write(int fd, const void *buf, size_t count); |
---|---|
函数功能 | 向打开的文件写入数据 fd:文件描述符 buf:要输入的数据的起始地址 count:每次写入的字节数 |
函数返回值 | 成功返回实际写入的字节数 失败返回 -1 并设置errno 如果返回值为0,表明实际写入的字节数为0,可以用来检测错误。 |
函数用法 | #include <unistd.h> ssize_t read(int fd, void *buf, size_t count); |
---|---|
函数功能 | 从打开的文件读取数据 fd:文件描述符 buf:所读取的数据存放的地方 count:每次读取的字节数 |
函数返回值 | 成功返回实际读取的字节数 失败返回 -1 并设置errno 如果返回值为0,表明实际读取的字节数为0,可以用来检测错误。 |
函数用法 | #include <sys/types.h> #include <unistd.h> off_t lseek(int fildes, off_t offset, int whence); |
---|---|
函数功能 | 调整文件光标的位置 filds:文件描述符 offset:表示相对移动长度,以字节为单位 20 向前移动20个字节 -20 向后移动20个字节 whence:设定光标的位置 SEEK_SET 文件开头 SEEK_END 文件末尾 SEEK_CUR 当前位置 |
函数返回值 | 成功返回光标相对文件开头的位置 失败返回 -1 并设置errno |
样例
1.使用open、write、fseek、read、close,实现打开、写入、调整光标、读取、关闭文件操作。
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
int fd;
int ret;
char buf[32] = "HelloWorld!";
fd = open("file.txt", O_CREAT | O_RDWR | O_EXCL, S_IRWXU);//以读写打开并创建file.txt,
// 设定权限为当前用户可读可写可执行
if ( -1 == fd)
{
perror("open");
exit(1);
}
ret = write(fd, buf, strlen(buf));//把buf中的数据写入到文件中
一次写入sizeof(buf)个字节
if ( -1 == ret)
{
perror("write");
exit(1);
}
else
{
printf("实际写入 %d Bytes\n", ret);
}
lseek(fd, 0, SEEK_SET);//把光标调整到文件开头
memset(buf, 0, sizeof(buf));//清空数组buf
ret = read(fd, buf, sizeof(buf));//从文件中读取数据到buf,一次读取sizeof(buf)个字节
if ( -1 == ret)
{
perror("read");
exit(1);
}
else
{
printf("实际读取 %d Bytes\n", ret);
}
printf("%s\n", buf);//打印刚才读取的数据
ret = close(fd);
if (ret == -1)
{
perror("close");
exit(1);
}
else if(ret == 0)
{
printf("文件已关闭\n");
}
return 0;
}
/**测试结果**/
实际写入 11 Bytes
实际读取 11 Bytes
HelloWorld!
文件已关闭
2.使用lseek来计算文件长度
使用上一题的 file.txt
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
int main()
{
int fd;
int ret;
fd = open("file.txt", O_RDONLY);//以只读打开file.txt,
if ( -1 == fd)
{
perror("open");
exit(1);
}
ret = lseek(fd, 0, SEEK_END);//把光标调整到文件末尾位移为0
if (ret == -1)
{
perror("lseek");
exit(1);
}
else
{
printf("文件长度为:%d\n", ret);
}
close(fd);
return 0;
}
/**测试结果**/
文件长度为:11
3.实现Linux的cp命令
#include<stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
int main(int argc, char *argv[])
{
int fd1, fd2;
int ret;
char buf[32] = {0};
if (argc != 3 )
{
printf("Input error!\n");
exit(1);
}
fd1 = open(argv[1], O_RDONLY);
if( -1 == fd1)
{
perror("open_1");
exit(1);
}
fd2 = open(argv[2], O_RDWR | O_CREAT | O_EXCL, S_IRWXU);
if( -1 == fd2)
{
perror("open_2");
exit(1);
}
memset(buf, 0, sizeof(buf));
while ( (ret = read(fd1, buf, sizeof(buf) - 1)) > 0)
{
ret = write(fd2, buf, ret);
if( -1 == ret)
{
perror("write");
exit(1);
}
memset(buf, 0, sizeof(buf));
}
close(fd1);
close(fd2);
return 0;
}
/**测试结果**/