【Linux】应用编程之C语言文件操作

简介: 【Linux】应用编程之C语言文件操作

前言

  对于文件IO来说,一切都是围绕文件描述符来进行的,在Linux系统中所有打开的文件都是一个对应的文件描述符。
  文件描述符的本质是一个非负整数,当我们打开一个文件时,系统会给我们分配一个文件描述符。
  当我们对一个文件做读写操作的时候,我们使用open函数的时候返回的就是这个文件的文件描述符,我们后续对文件的操作例如read和write都需要使用这个参数。

完成目标:

  在windows上编程和Linux上的文件操作有所不同(如果需要学习windows上的文件操作编程可以跳转到这里:C/C++文件读取操作),本文主要是熟悉Linux上的文件操作的接口使用和相关文档的翻译。


一、工程的创建

1、目录结构

2、Makefile

object = *.o
CC = gcc
main:$(object)
        $(CC) $(object) -o main
        rm *.o
        file main
%.o:%.c
        $(CC) -c $<
clean:
        rm *.o
        rm main

这里复制需要注意一下需要将复制过去的空格替换成TAB

二、文件的操作

1.创建、打开、关闭文件:open、close、creat

如需要查看函数的完整说明使用以下命令查看详细的说明;

man open 
man close  

下面是打开文件的函数接口以及使用该接口需要包含的头文件

// 使用系列操作需要包含得头文件
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <fcntl.h>
// 文件操作的接口函数:我们常用的是open
 int open(const char *pathname, int flags); // 如果没有创建文件得权限使用该打开方式
 int open(const char *pathname, int flags, mode_t mode);// 如果打开文件发现没有得情况需要创建选项这里就需要填写mode权限

const char* pathname传入的是文件名的字符串地址

flags表示文件的打开方式,如下表

参数 含义
O_CREAT 必要时创建文件
O_TRUNC 删除全部现有数据
O_APPEND 维持现有数据,保存到其后面
O_RDONLY 只读打开
O_WRONLY 只写打开
O_RDWR 读写打开

第二个函数还提供一个mode_t的参数该参数是表示创建文件的权限设置,这里类似chmod指令,在commod下使用ls -al 或则 ll指令可以查看文件权限

-rw-rw-r-- 1 stylle stylle  291 May 24 10:36 file.c
-rwxrwxr-x 1 stylle stylle 8384 May 24 10:16 main
-rw-rw-r-- 1 stylle stylle  129 May 24 10:03 Makefile

r表示可读 -4

w表示可写 - 2

x表示可执行 -1

所以我们常用到得chmod 777 就表示将该文件赋予可读可写可执行得权限;我们在操作完文件过后一定要释放文件,所以我们open过后一定要跟close函数,就如同malloc和free一样;

#include <unistd.h>
int close(int fd); // 直接传入我们刚刚open函数返回的文件描述符

完整的使用用例

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
int main(int argc, char **argv)
{
        int fd;
        fd = open("file_tmp.c", O_CREAT | O_RDWR,0666);
        if(fd < 0)
        {
                perror("open file error\r\n");
        }
        else{
                printf("fd = %d\r\n",fd);
                close(fd);
        }
        return 0;
}

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
int creat(const char *pathname, mode_t mode);

pathname为创建文件的名称

mode表示创建文件的权限

返回的参数为创建的文件描述符,如果小于0表示文件创建失败,下面是程序演示

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdlib.h>
int main(int argc, char **argv)
{
  int fd;
  if(argc < 2)
  {
    perror("plese input creat filename\r\n");
    exit(0);
  }
  int ret = creat(argv[1], 0666);
  if(ret < 0)
  {
    perror("creat file error\r\n");
    exit(0);
  }
  printf("creat file %s success\r\n",argv[1]);
  return 0;
}

2.读取、写入文件:read、write

然后我们开始向文件中写入内容然后从中读取出来,这里我们需要使用到write和read,然后我们查看函数需要传入的参数

#include <unistd.h>
ssize_t write(int fd, const void *buf, size_t count);
ssize_t read(int fd, void *buf, size_t count);

write

fd表示文件描述符,这里填写我们open函数返回的fd就可以了

buf表示要写入文件的字符串

count表示要写入字符的个数

read

fd表示文件描述符,这里填写我们open函数返回的fd就可以了

buf表示接收读取到的字符串

count表示要读取的字符个数

然后我们来实验一下

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
int main(int argc, char **argv)
{
  int fd;
  char read_str[15];
  int ret = 0;
  fd = open("tmp.txt", O_CREAT | O_RDWR,0666);
  if(fd < 0)
  {
    perror("open file error\r\n");
    exit(0);
  }
  ret = write(fd, "hello world", strlen("hello world")+1);// +1是strlen未包含‘\0’的长度
  if(ret < 0)
  {
    perror("write error\r\n");
  }
  close(fd);
  fd = open("tmp.txt", O_RDONLY);
  if(fd < 0)
  {
    perror("open read only file error\r\n");
    exit(0);
  }
  ret = read(fd, read_str, ret);
  close(fd);
  if(ret < 0)
  {
    perror("read error\r\n");
  }
  else
  {
    printf("read_num = %d read:%s\r\n",ret,read_str); 
  }
  return 0;
}

3.文件定位: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,下面来个小实验

#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#include <stdlib.h>
int main(int argc, char **argv)
{
  int fd;
  int ret;
  char read_str[10];
  fd = open("a.txt", O_RDONLY);
  if(fd < 0)
  {
    perror("open error");
    exit(0);
  }
  // a.txt: "hello stylle"
  ret = read(fd, read_str, 5);// read "hello"
  if(ret < 0)
  {
    perror("read error");
  }
  else
  {
    ret = lseek(fd, 0, SEEK_CUR);// return cur file addr
    read_str[5] = '\0';
    printf("read %d:%s\n",ret, read_str);
    
    ret = lseek(fd, 0, SEEK_END);
    printf("file size:%d\n",ret);
    lseek(fd, -7, SEEK_CUR);// '\0'
    memset(read_str, 0, 10);
    ret = read(fd, read_str, 6);
    if(ret > 0)
    {
      printf("read 6 digits:%s\n",read_str);
    }
    close(fd);
  }
  return 0;
}

最后

本章需要注意的点:

1、写入文件后不能马上读取需要重新打开读取

2、上述的内容并没有十分完整,完整函数的用法和原型可以使用man 函数名称 进行查阅


相关文章
|
16天前
|
存储 监控 Linux
嵌入式Linux系统编程 — 5.3 times、clock函数获取进程时间
在嵌入式Linux系统编程中,`times`和 `clock`函数是获取进程时间的两个重要工具。`times`函数提供了更详细的进程和子进程时间信息,而 `clock`函数则提供了更简单的处理器时间获取方法。根据具体需求选择合适的函数,可以更有效地进行性能分析和资源管理。通过本文的介绍,希望能帮助您更好地理解和使用这两个函数,提高嵌入式系统编程的效率和效果。
79 13
|
1月前
|
存储 程序员 C语言
【C语言】文件操作函数详解
C语言提供了一组标准库函数来处理文件操作,这些函数定义在 `<stdio.h>` 头文件中。文件操作包括文件的打开、读写、关闭以及文件属性的查询等。以下是常用文件操作函数的详细讲解,包括函数原型、参数说明、返回值说明、示例代码和表格汇总。
51 9
|
1月前
|
存储 数据管理 C语言
C 语言中的文件操作:数据持久化的关键桥梁
C语言中的文件操作是实现数据持久化的重要手段,通过 fopen、fclose、fread、fwrite 等函数,可以实现对文件的创建、读写和关闭,构建程序与外部数据存储之间的桥梁。
|
2月前
|
存储 缓存 算法
在C语言中,数据结构是构建高效程序的基石。本文探讨了数组、链表、栈、队列、树和图等常见数据结构的特点、应用及实现方式
在C语言中,数据结构是构建高效程序的基石。本文探讨了数组、链表、栈、队列、树和图等常见数据结构的特点、应用及实现方式,强调了合理选择数据结构的重要性,并通过案例分析展示了其在实际项目中的应用,旨在帮助读者提升编程能力。
68 5
|
2月前
|
存储 程序员 编译器
C 语言数组与指针的深度剖析与应用
在C语言中,数组与指针是核心概念,二者既独立又紧密相连。数组是在连续内存中存储相同类型数据的结构,而指针则存储内存地址,二者结合可在数据处理、函数传参等方面发挥巨大作用。掌握它们的特性和关系,对于优化程序性能、灵活处理数据结构至关重要。
|
2月前
|
算法 C语言
C语言中的文件操作技巧,涵盖文件的打开与关闭、读取与写入、文件指针移动及注意事项
本文深入讲解了C语言中的文件操作技巧,涵盖文件的打开与关闭、读取与写入、文件指针移动及注意事项,通过实例演示了文件操作的基本流程,帮助读者掌握这一重要技能,提升程序开发能力。
129 3
|
2月前
|
机器学习/深度学习 算法 数据挖掘
C语言在机器学习中的应用及其重要性。C语言以其高效性、灵活性和可移植性,适合开发高性能的机器学习算法,尤其在底层算法实现、嵌入式系统和高性能计算中表现突出
本文探讨了C语言在机器学习中的应用及其重要性。C语言以其高效性、灵活性和可移植性,适合开发高性能的机器学习算法,尤其在底层算法实现、嵌入式系统和高性能计算中表现突出。文章还介绍了C语言在知名机器学习库中的作用,以及与Python等语言结合使用的案例,展望了其未来发展的挑战与机遇。
51 1
|
2月前
|
并行计算 算法 测试技术
C语言因高效灵活被广泛应用于软件开发。本文探讨了优化C语言程序性能的策略,涵盖算法优化、代码结构优化、内存管理优化、编译器优化、数据结构优化、并行计算优化及性能测试与分析七个方面
C语言因高效灵活被广泛应用于软件开发。本文探讨了优化C语言程序性能的策略,涵盖算法优化、代码结构优化、内存管理优化、编译器优化、数据结构优化、并行计算优化及性能测试与分析七个方面,旨在通过综合策略提升程序性能,满足实际需求。
65 1
|
2月前
|
网络协议 物联网 数据处理
C语言在网络通信程序实现中的应用,介绍了网络通信的基本概念、C语言的特点及其在网络通信中的优势
本文探讨了C语言在网络通信程序实现中的应用,介绍了网络通信的基本概念、C语言的特点及其在网络通信中的优势。文章详细讲解了使用C语言实现网络通信程序的基本步骤,包括TCP和UDP通信程序的实现,并讨论了关键技术、优化方法及未来发展趋势,旨在帮助读者掌握C语言在网络通信中的应用技巧。
49 2
|
2月前
|
存储 C语言 计算机视觉
在C语言中指针数组和数组指针在动态内存分配中的应用
在C语言中,指针数组和数组指针均可用于动态内存分配。指针数组是数组的每个元素都是指针,可用于指向多个动态分配的内存块;数组指针则指向一个数组,可动态分配和管理大型数据结构。两者结合使用,灵活高效地管理内存。