文件操作-open等

1、文件的作用

linux下,一切均文件

2、linux的文件结构

root:该目录为系统管理员的用户主目录

bin:(binary)改目录存放最经常使用的命令

boot:存放启动Linux时使用的一些核心文件

dev:(device)存放Linux的外部设备,在Linux中访问设备的方式和访问文件的方式是相同的。

etc:所有的配置文件

home:用户的主目录,在Linux中每个用户都拥有自己的目录

var:存放着不断变化的文件数据,包含各种日志文件。

lib:存放着系统最基本的动态链接共享库,作用类似于Windows的dll文件。

usr:系统用户工具和程序

​ --bin:用户命令

​ --sbin:超级用户使用的

​ --include:标准头文件

​ --lib:库文件

--src:内核源代码

tmp:用于存在一些临时文件

media:linux系统会自动识别一些设备,例如U盘、光驱等,识别后,linux会把识别的设备挂载到改目录下。

mnt:临时挂载其他文件。

3、文件操作方式
(1)文件描述符 fd

是一个大于等于0的整数

每打开一个文件,就创建一个文件描述符,通过文件描述符来操作文件

预定义的文件描述符:

  • 0:标准输入,对应于已打开的标准输入设备(键盘)
  • 1:标准输出,对应于已打开的标准输出设备(控制台)
  • 2:标准错误,对应于已打开的标准错误输出设备(控制台)

多次打开同一个文件,可得到多个不同的文件描述符

ps -ef # 查看进程信息
(2)使用底层文件操作(系统调用)

比如:read

可使用man 2 查看

(3)使用I/O库函数

比如:fread

可使用man 3 查看

4、底层文件操作(关于文件的系统调用)
1) write

(1)用法

man 2 write

(2)返回值

​ 成功:返回实际写入的字节数

​ 失败:返回-1 错误编号设置errno, 使用(strerror(errno))查看

注意:是从文件的当前指针位置写入!

​ 文件刚打开时,文件的位置指针指向文件头

例子:

#include<stdio.h>
#include<stdlib.h>

int main(){
    char buf[] = "hello world!\n";

    // 写到标准输出stdout
    write(1, buf, sizeof(buf));

    // 写到标准错误stderror
    write(2, buf, sizeof(buf));

    return 0;
}
2) read

(1) 用法

​ man 2 read

(2) 返回值

​ > 0: 实际读取的字节数

0:已读到文件尾

​ -1:出错

注意:参数3表示最多能接受的字节数,而不是指一定要输入的字节数

例子:

#include<stdio.h>
#include<stdlib.h>

int main(){
    char buffer[1024];
    int cnt = 0;

    cnt = read(0, buffer, sizeof(buffer));
    write(1, buffer, cnt);

    return 0;
}
3) open

(1) 用法

​ man 2 open

(2) 返回值

​ 成功:文件描述符

​ 失败:-1

(3) 打开方式

​ O_RDONLY 只读

​ O_WRONLY 只写

​ O_RDWR 读写

​ O_CREAT 如果文件不存在,则创建该文件,使用第三个参数进行权限设置,如果文件存在,则只打开文件

​ O_EXCL 如果同时使用O_CREAT而且该文件已经存在,则返回错误,用途:以防止多个进程同时创建。

​ O_APPEND 尾部追加方式(打开后,文件指针指向文件的末尾)

​ O_TRUNC 若文件存在,则长度被截为0,属性不变

例如 open("/dev/hello", O_RDONLY | O_CREAT | O_EXCL, 0777)

(4) 参数3(权限设置)

​ 当使用O_CREAT时,使用参数3

S_I(R/W/X)(USR/GRP/OTH)

​ 例如:S_IRUSR | S_IWUSR # 文件的所有者对该文件可读可写

(八进制表示法)0600

4) close

(1) 用法

​ man 2 close

​ 终止指定文件描述符与对应文件之间的关联

​ 并释放该文件描述符,即该文件描述符可被重新使用

(2) 返回值

​ 成功返回0

​ 失败返回1

示例:

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

#define FILE1 "./file1.txt"
#define FILE2 "./file2.txt"
#define LEN 4096

int main(){
    int file1 = 0, file2 = 0;
    char buffer[LEN];
    int len = 0;

    file1 = open(FILE1, O_RDONLY);
    if(file1 < 0){
        printf("open file1.txt failed, reason: %s! \n", strerror(errno));
    }
    file2 = open(FILE2, O_WRONLY | O_CREAT | O_EXCL, S_IRWXU);
    if(file1 < 0){
        printf("open file2.txt failed, reason: %s! \n", strerror(errno));
    }

    while((len = read(file1, buffer, sizeof(buffer))) > 0){
        write(file2, buffer, len);
    }

    close(file2);
    close(file1);
    return 0;
}
5)time命令

观察耗时

time ./a.out

分别输出:

​ 程序总的执行时间

​ 该程序本身所消耗的时间(用户态所执行的时间)

​ 系统调用所消耗的时间(内核态所执行的时间)

6) lseek

​ (1)用法

​ man 2 lseek

​ (2)返回值

​ 成功:返回新的文件位置与文件头之间偏移

​ 失败:-1

​ 示例:从文件偏移量100的位置拷贝100个字节到另外一个文件

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

#define FILE1 "./lseek_test.c"
#define FILE2 "./lseek_test2.c"
#define LEN 4096

int main(){
    int file1 = 0, file2 = 0;
    char buffer[LEN];
    int len = 0, ret = 0;

    file1 = open(FILE1, O_RDONLY);
    if(file1 < 0){
        printf("open file1.txt failed, reason: %s! \n", strerror(errno));
    }
    file2 = open(FILE2, O_WRONLY | O_CREAT | O_EXCL, S_IRWXU);
    if(file1 < 0){
        printf("open file2.txt failed, reason: %s! \n", strerror(errno));
    }
	
	# 改变文件的读写位置,基于SEEK_SET偏移100位置
    ret = lseek(file1, 100, SEEK_SET);
    printf("lseek ret: %d\n", ret);

    len = read(file1, buffer, LEN);
    printf("read[%d]:%s\n", len, buffer);

    write(file2, buffer, len);

    close(file2);
    close(file1);

    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值