linux 系统函数调用:open close read write lseek

  1. open函数
    查看函数原型 man 2 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);

相关参数用法介绍;

a.	pathname 文件名
b. flags
	必选项:
		O_RDONLY 只读
		O_WRONLY 只写
		O_RDWR   读写
	可选项:
		O_APPEND 追加
		O_CREAT  创建文件
			O_EXCL 与 O_CREAT 一起使用,如果文件存在,则报错
			mode 权限位,最终(mode & ~umask)
		O_NONBLOCK 非阻塞
		
	返回值:返回最小的可用文件描述符,失败返回-1, 设置errno
	
  1. close 函数
    man 2 close
 #include <unistd.h>
 int close(int fd);

参数介绍: fd为要关闭的文件描述符
返回值:成功返回0, 失败返回-1, 设置errno

ps:C语言参数使用 | 可以有多项参数的实现原理,实际上就是位符
比如:int 类型 32个位,哪几个位代表那几个含义

  1. read函数
    man 2 read
#include <unistd.h>
ssize_t read(int fd, void *buf, size_t count);
参数介绍:
	fd 文件描述符
	buf 缓冲区
	count 缓冲区大小
返回值:
	失败返回-1,设置errno
	成功返回读到的大小
	0代表读到文件末尾
	非阻塞情况下:
		read返回-1,但是此时需要判断errno的值,看是否是因为非阻塞的原因导致返回-1

非阻塞情况下:
read返回-1,但是此时需要判断errno的值,看是否是因为非阻塞的原因导致返回-1
这里回头再学习以下 ???
代码示例,使用read函数实现 linux cat命令的功能

#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <string.h>
int main(int arg, char *argv[]) {
    if(arg != 2)  {
        printf("./a.out filename\n");
        return -1;
    }
    int fd = opeޙn(argv[1], O_RDONLY);
    if(fd == -1) {
        printf("not found filename\n");
        return -1;
    }
    char buf[256];
    int read_ret = read(fd, buf, sizeof(buf));
    while (read_ret > 0)
    {
        printf("%s", buf);
        memset(buf, '\0', sizeof(buf));
        read_ret = read(fd, buf, sizeof(buf));  
    }
    close(fd);
    return 0;
}

注意使用这一行代码memset(buf, ‘\0’, sizeof(buf));
不然最后一次输出buf,会出现多余的情况 ,暨每次使用完buf,都清洗一次。

  1. wirte
#include <unistd.h>       
ssize_t write(int fd, const void *buf, size_t count);
参数介绍:
	fd 文件描述符
	buf 缓冲区
	count 缓冲区大小
返回值:
	成功,返回写入的字节数
	失败,返回-1,设置errno
	0, 代表未写入
  1. 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

以下代码示例:
将一个字符串helloworld,写到一个文件里面,读取出来,输出在屏幕上

de <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>

int main(int argc, char *argv[]) {
    if(argc != 2) {
        printf("./a.out filename1");
        return -1;
    }
    int fd = open(argv[1], O_RDWR|O_CREAT, 0666);
    char *w_temp = "helloworld";
    int length = strlen(w_temp);
    int write_ret = write(fd, w_temp, length);
    if(write_ret>0) {
        printf("write bytes of %d\n", length);
    } else {
        printf("write error\n");
        return -1;
    }
    char r_temp[256];
    int seek_ret = lseek(fd, 0, SEEK_SET);
    if(seek_ret == -1) {
        printf("lseek error\n");
        return -1;
    }
    memset(r_temp, '\0', sizeof(r_temp));
    int read_ret = read(fd, r_temp, sizeof(r_temp));
    printf("%d\n", read_ret);
    if(read_ret !=-1){
        printf("read bytes of %d\n", strlen(r_temp));
        printf("read is\n");
        printf("%s\n", r_temp);
    } else {
        printf("read error\n");
        return -1;
    }
    write(STDOUT_FILENO, r_temp, strlen(r_temp));
    close(fd);
    return 0;
}

注意

int seek_ret = lseek(fd, 0, SEEK_SET);

将文件读写位置,重写设置为文件开始,不然以后的代码读取不到文件的内容。

lseek函数计算文件大小
代码示例:

#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

int main(int argc, char *argv[]) {
    if(argc !=2) {
        printf("./a.out filename1\n");
        return -1;
    }
    int fd = open(argv[1], O_RDONLY);
    if(!fd) {
        printf("open error\n");
        return -1;
    }
    int file_size = lseek(fd, 0, SEEK_END);
    printf("%s file size is %d\n", argv[1], file_size);
    close(fd);
    return 0;
}

lseek 拓展文件
以下代码,创建一个新文件, 并且使其大小为1024字节。

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>

int main(int argc, char *argv[]) {
    if(argc!=2) {
        printf("./a.out filename1\n");
        return -1;
    }
    int fd = open(argv[1], O_WRONLY|O_CREAT, 0666);
    int l_ret = lseek(fd, 1023, SEEK_END);
    char a[1] = {'a'};
    // 这里必须要写一次,才能生效
    int w_ret = write(fd, a, 1); // or write(fd, "a", 1);
    close(fd);
    return 0;
}

代码举例:

  1. 同一个进程中,两次打开同一个文件,进行写操作
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>

int main(int argc, char *argv[]) {
    if(argc != 2) {
        printf("./a.out filename1\n");
        return -1;
    }
    int o_ret = open(argv[1], O_RDWR|O_CREAT, 0666);
    printf("o_ret = %d\n", o_ret);
    int o_ret1 = open(argv[1], O_RDWR|O_CREAT, 0666);
    printf("o_ret1 = %d\n", o_ret1);

    write(o_ret, "hello", 5);
    lseek(o_ret1, 5, SEEK_CUR);
    // 这里注意lseek的用法,不然,下面的world,会把上面的hello覆盖掉
    write(o_ret1, "world", 5);


    int cl_ret = close(o_ret);
    int cl_ret1 = close(o_ret1);
    printf("cl_ret = %d\n", cl_ret);
    printf("cl_ret1 = %d\n", cl_ret1);
    return 0;
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值