Linux下对文件io系统的调用

前言

一直以来都是在Linux下用Python进行文件调用,但还没真正使用c操作过,假期跟着师兄学Linux和嵌入式,深感c的重要性,所以开始补补钙。

文件IO系统调用

1.1 open()系统调用

int open(const char *path, int oflag, ... /*mode_t mode*/);

open()系统调用用来打开一个文件,并返回一个文件描述符(file description), 并且该文件描述符是当前进程最小、未使用的
文件描述符数值。
 参数: path: 要打开的文件、设备的路径
 oflag: 由多个选项进行“或”运算构造oflag参数 。
 必选: O_RDONLY (只读)O_WRONLY(只写)、 O_RDWR(读写) 
 可选: O_APPEND 每次写时都追加到文件的尾端。 
 O_CREAT 文件不存在则创建它,使用该选项需要第三个参数mode 
 O_TRUNC 如果文件存在,而且为只写或读写成功打开,则将其长度截取为0; 
 O_NONBLOCK 如果path是一个FIFO、块设备、字符特殊文件则此选项为文件的本次打开和后续的I/O操作
设置非阻塞模式方式。 
 O_EXEC、O_SEARCH、O_CLOEXEC、O_NOCTTY.... 
 mode: oflag带O_CREAT选项时可以用来创建文件,这时必须带该参数用来指定创建文件的权限模式,如066。 否则不
需要。使用示例代码:

int fd; 
 fd = open(“text.txt”, O_RDWR|O_CREAT|O_TRUNC, 0666); 
 fd = open(“text.txt”, O_WRONLY|O_APPEND);

1.2 create()系统调用

int creat(const char *path, mode_t mode);
//此函数用来创建一个新文件并返回其fd。它等价于 open(path,O_WRONLY|O_CREAT|O_TRUNC, mode);

int fd; 
fd=creat("text.txt", 0644);

1.3 close()系统调用

int close(int fd);

该函数用来关闭一个打开的文件描述符,关闭一个文件时还会释放该进程加在该文件上的所有记录锁。当一个进程终止时,
内核将会自动关闭它所有打开的文件。

1.4 write()系统调用

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

write()函数用来往打开的文件描述符fd指向的文件中写入buf指向的数据,其中nbytes指定要写入的数据大小。如果返回值
<0则说明写入出错,譬如尝试往一个只读的文件中写入则会抛错,错误的原因系统会保存到errno变量中去。如果>0则为实
际写入的数据大小。

1.5 read()系统调用

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

read()函数用来从打开的文件描述符对应的文件中读取数据放到buf指向的内存空间中去,最多不要超过nbytes个字节,这里
的nbytes一般是buf剩余的空间大小。如read成功,则返回实际读到的字节数(由nbytes或读到文件尾决定,其中EOF宏用
来判断是否到了文件尾),如果返回值小于0则表示出错,如尝试读一个没有权限读的文件时就会抛错。 

1.6 lseek()系统调用

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

我们在从文件里读出内容,或往文件写如内容的时候都有一个起始地址,这个起始地址就是当前文件偏移量,当我们对文件
进行读写的时候都会使文件偏移量往后偏移。这点就类似于我们打开记事本开始编辑文本时的光标,我们读或写入时从光标
所在位置开始读写,每读写一个字节都会使光标往后偏移。通过lseek()这个函数我们可以调整文件偏移量的地址。
其中 whence 可以是以下三个值:

在这里插入图片描述

而offset就是相对于whence 的偏移量,譬如:
lseek(fd, 0, SEEK_SET); 将文件偏移量设置到了文件开始的第一个字节上;
lseek(fd, 0, SEEK_END); 将文件偏移量设置到文件最后一个字节上;
lseek(fd, -1, SEEK_END); 将文件偏移量设置到文件最后的倒数第一个字节上;

1.7 文件IO系统调用源码展示与讲解

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


#define buffsize 1024               //定义存储数据的长度大小为buffsize
#define message_str "Hello World\n" //写入创建文件的内容

int main(int argc , char *argv[])
{
  /*Linux操作系统:return 0 为正常返回,return -1 出错,很多时候会用-1、-2等数据来比较错误,用echo $?在终端会有上次运行的返回值,以此来判断程序发生错误的位置*/
  int fd = -1;                      //考虑最糟糕的情况,所以一开始赋值为-1
  int rv = -1;                      //考虑最糟糕的情况,所以一开始赋值为-1
  char buff[buffsize];              //创建buff

  fd = open("hello.txt",O_RDWR | O_CREAT | O_TRUNC , 0666); 
  if(fd < 0)
  {
    perror("创建文件失败!");
    return 0;
  }
  printf("Open file return file director:[%d]\n",fd);

  rv = write(fd,message_str,strlen(message_str));
  if(rv < 0)
  {
    printf("write %d bytes into file failure:%s\n",rv,strerror(errno));
    goto cleanup;
  }
  lseek(fd,0,SEEK_SET);
  memset(buff,0,sizeof(buff));
  rv = read(fd,buff,sizeof(buff));
  if(rv < 0)
  {
   printf("Read data from file failure: %s\n",strerror(errno));
   goto cleanup;
  }
  printf("Read %d bytes data from files: %s\n",rv,buff);
  
cleanup:
  close(fd);
  return 0 ;

}


二、文件夹操作的系统调用
2.1 mkdir()

int mkdir(const char *pathname, mode_t mode);//创建文件夹

2.2 rmdir()

int rmdir(const char *pathname);//删除文夹

2.3 opendir()

DIR *opendir(const char *pathname);//打开文件夹

2.4 readdir()

struct dirent * readdir(DIR *dp);//读文件夹

2.5 closedir()

int closedir(IDR *dp);//关闭文件夹

2.6 chdir()

int chdir(const char * pathname);//改变文件操作目录

2.7 文件夹系统调用源码展示与讲解

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

#define TEST_DIR "dir"
int main(int argc, char **argv)
{
    int rv;
    int fd1;
    int fd2;
    DIR *dirp;
    struct dirent *direntp;
    /* 创建文件夹dir, 并设置文件夹权限为755 */
    if (mkdir(TEST_DIR, 0777) < 0)
    {
        printf("create directory '%s' failure: %s\n", TEST_DIR, strerror(errno));
        return -1;
    }
    /* 更改当前工作路径到文件夹dir下去 */
    if (chdir(TEST_DIR) < 0)
    {
        printf("Change directory to '%s' failure: %s\n", TEST_DIR, strerror(errno));
        rv = -2;
        goto cleanup;
    }
    /* 在dir文件夹下 创建普通文本文件file1.txt,并设置其权限位为644 */
    if ((fd1 = creat("file1.txt", 0777)) < 0)
    {
        printf("Create file1.txt failure: %s\n", strerror(errno));
        rv = -3;
        goto cleanup;
    }
    /* 在dir文件夹下 创建普通文本文件file2.txt,并设置其权限位为644 */
    if ((fd2 = creat("file2.txt", 0777)) < 0)
    {
        printf("Create file2.txt failure: %s\n", strerror(errno));
        rv = -4;
        goto cleanup;
    }
    /* 更改当前工作路径到父目录去 */
    if (chdir("../") < 0)
    {
        printf("Change directory to '%s' failure: %s\n", TEST_DIR, strerror(errno));
        rv = -5;
        goto cleanup;
    }
    /* 打开dir文件夹 */
    if ((dirp = opendir(TEST_DIR)) == NULL)
    {
        rv = -6;
        printf("opendir %s error: %s\n", TEST_DIR, strerror(errno));
        goto cleanup;
    }
    /* 列出dir里面的所有文件和文件夹 */
    while ((direntp = readdir(dirp)) != NULL)
    {
        printf("Find file: %s\n", direntp->d_name);
    }
    /* 关闭所有打开的文件夹 */
    closedir(dirp);
cleanup:
    if (fd1 >= 0)
    {
        close(fd1);
    }
    if (fd2 >= 0)
    {
        close(fd2);
    }
}


三、文件拷贝(文件IO系统调用实现)

#include <stdio.h>
#include <dirent.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
char buff[1024];

int len;

int main(int argc,char const*argv[])
{
 char const *src_path = argv[1];
 char const *des_path = argv[2];
 int fd, fd2;
 fd = open(src_path,O_RDWR | O_CREAT);
 fd2 = open(des_path,O_RDWR | O_CREAT,0666);
 
 while(len=read(fd,buff,sizeof(buff)))
 {
  write(fd2,buff,len);
 } 
 return 0;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值