IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 系统运维 -> Linux系统编程 | 01 -文件操作 -> 正文阅读

[系统运维]Linux系统编程 | 01 -文件操作

一、文件操作方法

linux中有两种方法可以操作文件:系统调用和c库函数。

1. 什么是系统调用?

由操作系统实现并提供给外部应用程序的编程接口(API),是应用程序同系统之间数据交互的桥梁。

C标准函数和系统函数调用关系,如图:

2. c库函数

待写。

二、文件IO(系统调用API)

库函数头文件统一使用头文件unistd.h

1. open创建

头文件:

#include <fcntl.h>

函数原型:

int open(const char *pathname, int flags);

参数说明:

  • pathname:文件名
  • flag:文件打开标志
flag参数说明
O_RDONLY只读方式打开
O_WRONLY只写方式打开
O_RDWR可读可写
O_CREAT文件不存在则创建(文件权限由mode参数指定)
O_APPEND追加方式写入
O_EXCL判断文件是否存在
O_TRUNC截断文件大小为0/清空文件
O_NONBLOCK

mode权限参数说明:

  1. 该参数使用八进制指定;
  2. 该参数受umask(默认0002)影响:最终权限 = mode &~ umask,其实就是把我们所指定权限中other用户的写权限给去除。

返回值说明:

  • 成功返回fd号
  • 失败返回-1,错误原因errno给出

2. close关闭

头文件:

#include <unistd.h>

函数原型:

int close(int fd);

参数说明:

  • fd:文件描述符

3. write写入

头文件:

#include <unistd.h>

函数原型:

ssize_t write(int fd, const void *buf, size_t count);

参数说明:

  • fd:文件描述符
  • buf:待写数据指针
  • count:待写数据大小

返回值:

  • 成功:返回写入的字节数
  • 失败:返回-1,error被设置

4. read读取

头文件:

#include <unistd.h>

函数原型:

ssize_t read(int fd, void *buf, size_t count);

参数说明:

  • fd:文件描述符
  • buf:缓冲区指针
  • count:要读取的数据大小

返回值:

  • 成功:返回读取的字节数
  • 失败:返回-1,error被设置

说明:

在支持查找的文件上,读取操作从文件偏移量开始,并且文件偏移量会随着读取递增。如果文件偏移量在文件末尾或者超过文件末尾,则返回0

5. lseek文件偏移

头文件:

#include <unistd.h>

函数原型:

off_t lseek(int fd, off_t offset, int whence);

参数说明:

  • fd:文件描述符
  • offset:偏移量
  • count:要读取的数据大小
    • SEEK_SET:The file offset is set to offset bytes.
    • SEEK_CUR:The file offset is set to its current location plus offset bytes.
    • SEEK_END:The file offset is set to the size of the file plus offset bytes.

返回值:

  • 成功:返回当前所在偏移量
  • 失败:返回-1,error被设置

三、测试程序

demo1——默认创建文件的权限

#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>

int main(int argc, char *argv[])
{
    int fd;

    fd = open("hello.txt", O_RDWR | O_CREAT);

    printf("fd is %d\n", fd);

    close(fd);

    return 0;
}

执行结果:

fd is 3

如果hello.txt不存在,则open会创建该文件,但我们并没有指定文件权限(mode),查看默认创建文件的权限:

---Srwx--T 1 ubuntu ubuntu    0 Sep  5 16:40 hello.txt

后续文件权限分析?

demo2——指定创建文件的权限

#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>

int main(int argc, char *argv[])
{
    int fd;

    // 0644: rw-r--r--
    fd = open("hello.txt", O_RDWR | O_CREAT, 0644);

    printf("fd is %d\n", fd);

    close(fd);

    return 0;
}

执行之后再次查看hello.txt的权限:

rw-r--r-- 1 ubuntu ubuntu    0 Sep  5 16:47 hello.txt

demo3——指定创建文件的权限受umask影响

#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>

int main(int argc, char *argv[])
{
    int fd;

    // 0777: rwxrwxrwx
    // umask: 0002
    fd = open("hello.txt", O_RDWR | O_CREAT, 0777);

    printf("fd is %d\n", fd);

    close(fd);

    return 0;
}

创建出的hello.txt权限为:

-rwxrwxr-x 1 ubuntu ubuntu    0 Sep  5 17:03 hello.txt*

demo4-打开文件出错

#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <string.h>

int main(int argc, char *argv[])
{
    int fd;

    fd = open("hello.txt", O_RDWR);

    printf("fd is %d\n", fd);
    printf("errno is %d(%s)\n", errno, strerror(errno));

    close(fd);

    return 0;
}

当hello.txt不存在时,日志为:

fd is -1
errno is 2(No such file or directory)

demo5——文件偏移量导致读取失败

#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <string.h>

int main(int argc, char *argv[])
{
    int fd;
    int nbytes;
    char write_buf[] = "helloworld!";
    char read_buf[1024] = {0};

    /* 1. open file */
    fd = open("hello.txt", O_RDWR | O_CREAT, 0664);
    if (fd < 0) {
        printf("open fail, fd is %d\n", fd);
        printf("errno is %d(%s)\n", errno, strerror(errno));
        return -1;
    }

    /* 2. write */
    nbytes = write(fd, write_buf, sizeof(write_buf));
    if (nbytes < 0) {
        printf("write fail, errno is %d(%s)\r\n", errno, strerror(errno));
        return -1;
    }
    printf("write %d bytes\r\n", nbytes);

    /* 3. read */
    nbytes = read(fd, read_buf, sizeof(read_buf));
    if (nbytes < 0) {
        printf("read fail, errno is %d(%s)\r\n", errno, strerror(errno));
        return -1;
    }
    printf("read %d bytes:[%s]\r\n", nbytes, read_buf);

    /* 4. close */
    close(fd);

    return 0;
}

write写入完成后,文件偏移量在文件末尾,直接读取导致返回0:

write 12 bytes
read 0 bytes:[]

这个时候在read之前,使用lseek函数将文件偏移量恢复到文件开始处即可:

lseek(fd, 0, SEEK_SET);
  系统运维 最新文章
配置小型公司网络WLAN基本业务(AC通过三层
如何在交付运维过程中建立风险底线意识,提
快速传输大文件,怎么通过网络传大文件给对
从游戏服务端角度分析移动同步(状态同步)
MySQL使用MyCat实现分库分表
如何用DWDM射频光纤技术实现200公里外的站点
国内顺畅下载k8s.gcr.io的镜像
自动化测试appium
ctfshow ssrf
Linux操作系统学习之实用指令(Centos7/8均
上一篇文章      下一篇文章      查看所有文章
加:2021-11-20 18:49:01  更:2021-11-20 18:49:37 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年12日历 -2024/12/25 1:44:08-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码
数据统计