文件相关命令——OPEN,READ,CLOSE以及实例分析

一、 文件相关命令

本文主要涉及三个与文件相关的命令——open,read,close; 并且在其中讲解了堆与栈的空间分配等。
包含实例练习1:打开一个文件并且读出文件的前1024个字节;练习2 使用open函数打开文件后将字符串转换为数值进行计算

1.1 open 打开文件命令

使用命令:man 2 open 可以看到关于打开文件有

NAME
open, creat - 用来 打开和创建 一个 文件或设备

SYNOPSIS 总览
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
int open(const char pathname, int flags);
int open(const char
pathname, int flags, mode_tmode)
int creat(const char *pathname, mode_t mode);

pathname : 路径名,打开文件的位置
这个参数的原型是一个char *: 字符串

当前工作路径下的文件使用"./1.txt"–>相对路径

. 为当前路径
… 为当前目录的父目录

"/mnt/hgfs/share/1.txt "–> 为绝对路径

flags : 打开文件的一些标志,用位域表示, 这里用宏去搞定多个功能的问题;如果有需求多巩固功能同时打开,那么直接使用|安慰或;& 按位与 ^按位异或
下面标志任选其一(必选标志):

O_RDONLY  只读
O_WRONLY 只写
O_RDWR 读写

下面的标记根据自己的需求进行打开(可选标记):

  • O_CREAT 若文件 不存在 将 创建 一个 新文件,如果使用了这个标记,则第三个参数必须要设置。给了这个标记表示如果存在就直接打开,如果不存在就创建该文加再打开。

  • O_NONBLOCK 非阻塞打开这个文件,文件打开默认是阻塞的

  • O_APPEND 追加标记,打开文件光标默认在文件开头,使用该标记后,光标会在文件末尾

  • O_TRUNC 截短标记

mode : 权限 Linux 里面的权限分为三个部分:用户,组用户,其他用户

    S_IRWXU
            00700 允许 文件 的 属主 读 , 写 和 执行 文件
   S_IRUSR (S_IREAD)
          00400 允许 文件 的 属主 读 文件

   S_IWUSR (S_IWRITE)
          00200 允许 文件 的 属主 写 文件

   S_IXUSR (S_IEXEC)
          00100 允许 文件 的 属主 执行 文件

   S_IRWXG
          00070 允许 文件 所在 的 分组 读 , 写 和 执行 文件

   S_IRGRP
          00040 允许 文件 所在 的 分组 读 文件

是使用8进制来表示权限的
比如

    用户  组用户 其他用户
0664:110  110   100 
权限:rw    rw     r

返回值:
open 和 creat 都 返回 一个 新的 文件描述符 (若是 有 错误 发生 返回 -1 ,并在 errno 设置 错误 信息). 注意 open 可以 打开 设备 专用 文件 , 但是creat 不能创建,需要用 mknod(2) 来代替.

成功返回一个大于等一0的整数(实际上>=3)
我们的进程在启动的时候操作系统就会为这个层序打开三个文件
1. 标准的输入 -> 0
2. 标准的输出 -> 1
3. 标准的出错 -> 2
返回的这个整数是一个数组(进程文件表项)的下表。
这个整数我们使用一个名词进行描述 — 文件描述符(fd)
后续对文件的操作都是对这个fd进行的

失败则返回-1,同时errno被设置
perror 可以解析一个系统错误

使用==man perror ==可以查看

perror - print a system error message

SYNOPSIS
       #include <stdio.h>

       void perror(const char *s);
       //该接口调用的时候会打印出系统的错误信息

       int fd =open();
       if(-1==fd)
       {
        perror("这里出错了")}

举例子:

#include <sys/types.h>
#include<sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
int main()
{
    // open a file
    int fd =open("./1.txt",O_RDWR);
    if(-1 == fd)
    {
        perror("open 1.txt error");
        return -1;

    }
    else
{
    {printf("open 1.txt success!!!!\n");
    
    }
}

}

在这里插入图片描述

1.2 READ 读文件命令

执行:man 2 read

NAME
read - 在文件描述符上执行读操作

概述
#include <unistd.h>

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

描述
read() 从文件描述符 fd 中读取 count 字节的数据并放入从 buf 开始的缓冲区
中.

   如果  count   为零,read()返回0,不执行其他任何操作.如果count   大
   于SSIZE_MAX,那么结果将不可预料.

buf : 读到的内容需要放到一个内存才能进行操作,这个buf就是这块内存的首地址。因为C语言没有边界检查,因此要时刻注意是否会越界。
程序员开辟内存一般是在栈空间或堆空间


这里补充一下关于堆栈的知识
栈(Stack)和堆(Heap)是计算机内存中两个常用的存储区域,它们用于存储不同类型的数据,并有不同的分配和释放方式。

1.2.1 栈(Stack)
  1. 开辟变量或空间: 在函数中声明的局部变量、函数参数等通常存储在栈上。栈上的空间是由编译器自动管理的,变量的大小在编译时就已经确定

  2. 自动释放: 栈上的内存空间是在变量超出作用域时自动释放的。当一个函数执行完成时,其局部变量所占用的栈空间会被立即释放。

  3. 代码块: 栈内存的分配和释放通常与代码块的生命周期相关。一般来说,代码块是指由花括号 {} 包围的一段代码。

1.2.2 堆(Heap)
  1. 动态内存分配: 堆用于存储动态分配的数据,即在运行时通过函数(如 malloccallocrealloc)手动申请的内存。

  2. 手动释放: 堆上的内存需要手动释放,否则可能导致内存泄漏。通常使用 free 函数释放动态分配的内存。

1.2.2.1 malloc

malloc(Memory Allocation)是 C 语言中用于动态分配内存的函数。它接受一个参数,即要分配的内存大小(以字节为单位),并返回一个指向分配内存起始地址的指针。

#include <stdlib.h>

int *ptr = (int *)malloc(10 * sizeof(int));

上面的代码使用 malloc 动态分配了一个可以存储 10 个整数的内存空间。

1.2.2.2 calloc

calloc(Contiguous Allocation)也是用于动态分配内存的函数,与 malloc 不同的是,calloc 在分配内存的同时会将内存的所有位初始化为零。

#include <stdlib.h>

int *ptr = (int *)calloc(10, sizeof(int));

上面的代码使用 calloc 动态分配了一个可以存储 10 个整数的内存空间,并且所有的整数都被初始化为零。

1.2.2.3 realloc

realloc(Reallocate)用于重新分配已经分配的内存大小。它接受一个已经分配的内存指针和新的大小作为参数,返回一个指向新分配内存的指针。

#include <stdlib.h>

int *ptr = (int *)malloc(10 * sizeof(int));
// 重新分配内存大小为20个整数
ptr = (int *)realloc(ptr, 20 * sizeof(int));

上面的代码使用 realloc 对之前分配的内存进行重新分配,使其可以存储 20个整数


count : 读到的字节数 > 0

返回值:
成功返回实际读到的字节数 <= count
失败返回-1,同时errno被设置

1.3 CLOSE 关闭文件命令

NAME 名字
close - 关闭一个文件描述符

SYNOPSIS 总览
#include <unistd.h>

   int close(int fd);

二、 练习1:打开一个文件并且读出文件的前1024个字节

读取文件1.txt文件中的前1024个字节。

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

int main()
{
    //open the file
int fd =open("./1.txt",O_RDWR);
    if(-1 == fd)
    {
        perror("open 1.txt error");
        return -1;

    }
//2.operate the file
char buf[1024]={0};
int r = read(fd,buf,1024);
if (-1==r)
{
    perror("read error");
    return -2;
}

printf("%s\n",buf);//%s must find the \o in the fnal byte

//close the file
close(fd);
return 0;
}

读取的内容如下:
在这里插入图片描述

三、 练习2 使用open函数打开文件后将字符串转换为数值进行计算

使用open函数打开1.txt文件,在一个1.txt的前面4个字节放了一个千位数,以%的形式输出它的两倍


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

int main()
{
    //open the file
int fd =open("./1.txt",O_RDWR);
    if(-1 == fd)
    {
        perror("open 1.txt error");
        return -1;

    }
//2.operate the file
char buf[1024]={0};

int r = read(fd,buf,4);
int i=atoi(buf);
if (-1==r)
{
    perror("read error");
    return -2;
}
printf("%s\n",buf);//%s must find the \o in the fnal byte
printf("%d\n",2*i);
//close the file
close(fd);
return 0;
}

在1.txt文件中写入1024 ,通过read函数读取出来的是字符串格式,所以使用atoi()函数,将其转换为整数,然后再进行输出。

r = read(fd,buf,4); --> “1024”

不使用函数可以通过减去字符串"0"得到相同字符的int的ascll
a=(buf[0]-“0”) *1000 + (buf[1]-“0”)*100+ (buf[2]-“0”) *10 +(buf[3]-“0”)*1;

在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

写的什么石山代码

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值