在Linux下的文件IO操作

系统调用

在Linux下的文件IO操作

为什么用户程序不能直接访问系统内核提供的服务,为了更好地保护内核空间,程序的运行空间被划分为内核空间用户空间(俗称内核状态用户模式),它们在不同的级别上逻辑上是相互隔离的。因此,在正常情况下,用户进程不允许访问内核数据,也不能使用内核函数。它们只能在用户空间中操作用户数据,并调用用户空间函数。

[En]

Why user programs can’t directly access the services provided by the system kernel in order to better protect the kernel space, the running space of the program is divided into * kernel space * and * user space * (commonly known as * kernel state * and * user mode * ), which are logically isolated from each other at different levels. Therefore, under normal circumstances, user processes are not allowed to access kernel data and cannot use kernel functions. They can only operate user data in user space and call user space functions.

在Linux下的文件IO操作
在Linux下的文件IO操作

通过 文件描述符 。文件描述符是一个非负的整数 ,是一个索引值 ,指向在内核中每个进程打开文件的记录表 。 当打开一个现存文件或创建一个新文件时,内核就向进程返回一个文件描
述符;当需要读写文件时 也需要把文件描述符作为参数传递给相应的函数 。是一个非负的整数(通常是小整数),posix标准要求每次打开一个文件, 必须使用当前进程最小的文件描述符号码,因此打开一定是3.
一个进程启动时 通常会打开 3 个文件:

标准输入 标准输入 标准出错 STDIN_FILENO STDOUT_FILENO STDERR_FILENO stdin stdout stderr

#include
#include
#include
#define MSG_STR "hello world\n"

int main(int argc, char **argv)
{
   printf("%s",MSG_STR);
   fputs(MSG_STR,stdout);
   write(STDOUT_FILENO,MSG_STR,strlen(MSG_STR));//标准输出到屏幕MSG_STR
   return 0;
}

关于fputs和weitey

fputs(const char *s, FILE *stream);
write(int fd, const void *buf, size_t count);

文件的创建/打开

open() 函数用于打开或者创建文件。其在打开或者创建文件时可以指定文件的属性及用户的权限等各种参数。

int open(const char *pathname, int flags);//打开已存在的文件
int open(const char *pathname, int flags, mode_t mode);//打开不存在的文件
//flags:read write操作文件的权限
//mode:该文件在磁盘中 相对于 用户的权限
int open(const char *path, int oflag, [mode_t mode]);

args:
    const char *path: 文件路径,可以是绝对,也可以是相对路径
    int oflag       : 文件打开的方式
                        - O_RDONLY 只读打开
                        - O_WRONLY 只写打开
                        - O_RDWR   可读可写打开
                        以上3种必选一个,以下4种可以任意选择
                        - O_APPEND 追加打开,所写数据附加到文件末
                        - O_CREAT  若此文件不存在则创建它
                        - O_EXCL   若文件存在则报错返回
                        - O_TRUNC  如果文件已存在,并且以只写或可读可写方式打开
                                   则将其长度截断为0字节
    [mode_t mode]   : 文件权限,只有在创建文件时需要使用

return:
    文件描述符,非负整数是成功,-1是失败
#include
#include
#include
#include

int main(int argc ,char **argv)
{
        int fd = -1;

        if((fd = open("test.txt",O_CREAT|O_RDWR,0666))

写文件

当文件打开后,我们就可以向该文件写数据了。在Linux系统中,用 write() 向打开的文件写入数据,要使用这个函数,需要包含 #include

ssize_t write(int fildes, const void *buf, size_t nbyte);

args:
    int fildes     : 写入文件的文件描述符
    const void *buf: 写入数据在内存空间存储的地址
    size_t nbyte   : 期待写入数据的最大字节数

return:
    文件实际写入的字节数,非负整数是成功,-1是失败(磁盘已满或者超出该文件的长度等)
        if((rv = write(fd, MSG_STR,strlen(MSG_STR)))

读文件

同写文件类似,要使用读文件函数 read() ,需要包含 #include

ssize_t read(int fildes, void *buf, size_t nbyte);

args:
    int fildes  : 读取文件的文件描述符
    void *buf   : 读取数据在内存空间存储的地址
    size_t nbyte: 期待读取数据的最大字节数

return:
    文件实际读取的字节数,非负整数是成功,-1是失败
#include
#include
#include
#include
#include
#include

#define  BUFSIZE        1024
#define  MSG_STR  "i love  linux\n"

int main(int argc ,char **argv)
{
        int     fd = -1;
        int     rv = -1;
        char    buf[BUFSIZE];

        if((fd = open("test.txt",O_CREAT|O_RDWR,0666))

但是这样读出是空的,所以要使用lseek文件偏离量,通俗来说:就是改变光标的位置,从哪里读数据.

memset函数
memset是计算机中C/C++语言初始化函数。作用是将某一块内存中的内容全部设置为指定的值, 这个函数通常为新申请的内存做初始化工作。

void *memset(void *s, int ch, size_t n);
    str  -- 指向要填充的内存块。
    c    -- 要被设置的值。该值以 int 形式传递,但是函数在填充内存块时是使用该值的无符号字符形式。
    n    -- 要被设置为该值的字符数。

文件的偏移量
在每个打开的文件中都有一个文件的偏移量,文件的偏移量会根据文件的读写而改变位置。我们可以通过 lseek() 函数来调整文件的偏移量。默认情况下,新打开文件的文件偏移量在文件的开始。同 write() 和 read() 函数类似,要使用这个函数,需要包含 #include

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

args:
    int fildes  : 修改文件的文件描述符
    off_t offset: 文件偏移量移动的距离
    int whence  : 文件偏移量的基址
                    - SEEK_SET 文件开始处
                    - SEEK_CUR 文件当前位置
                    - SEEK_END 文件结束处

return:
    当前文件指针的位置,非负整数是成功,-1是失败
lseek(fd , 0 ,SEEK_SET);//将文件偏移量设置到文件开始第一个字节上
lseek(fd , -1 ,SEEK_END);//将文件偏移量设置在文件倒数第一个字节上

在数据写入成功后,把文件偏移量移到文件开始第一行字节上

 if((rv = write(fd, MSG_STR,strlen(MSG_STR)))

关闭文件
当文件不再被使用时,可以调用 close() 函数来关闭被打开的文件。 除了用 close() 显示地关闭文件外,通过结束进程也能隐式地关闭被该进程打开的所有文件。要使用该函数,需要包含 #include

int close(int fildes);

args:
   int fildes: 要关闭文件的文件描述符

return:
    文件关闭状态,0是成功,-1是失败

代码实现

#include
#include
#include
#include
#include
#include

#define  BUFSIZE        1024
#define  MSG_STR  "i love  linux\n"

int main(int argc ,char **argv)
{
        int     fd = -1;
        int     rv = -1;
        char    buf[BUFSIZE];

        if((fd = open("test.txt",O_CREAT|O_RDWR,0666))

strerror函数
C 库函数 char *strerror(int errnum) 从内部数组中搜索错误号 errnum,并返回一个指向错误消息字符串的指针。strerror 生成的错误字符串取决于开发平台和编译器。

char *strerror(int errnum)

进一步代码实现

#include
#include
#include
#include
#include
#include

#define  BUFSIZE        1024
#define  MSG_STR        "hello world\n"

int main(int argc ,char **argv)
{
        int     fd = -1;
        int     rv = -1;
        char    buf[BUFSIZE];

        fd = open("test.txt",O_RDWR|O_CREAT|O_TRUNC,0666);
        if(fd < 0)
        {
                perror("创建/打开文件失败");
                return 0;
        }
        printf("打开文件成功 [%d]\n",fd);

        if((rv = write(fd,MSG_STR,strlen(MSG_STR))) < 0)
        {
                printf("文件写入失败:%s\n",strerror(errno));
                goto cleanup;
        }
        lseek(fd, 0 ,SEEK_SET);

        memset(buf, 0 ,sizeof(buf));
        if((rv = read(fd,buf,sizeof(buf))) < 0)
        {
                printf("读文件失败:%s\n",strerror(errno));
                goto cleanup;
        }
        printf("从文件读出%d数据:%s\n",rv,buf);

cleanup:
        close(fd);
        return 0;
}

Original: https://www.cnblogs.com/Ye-Wei/p/16100500.html
Author: 叶星辰$
Title: 在Linux下的文件IO操作

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/523882/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球