一、 文件相关命令
本文主要涉及三个与文件相关的命令——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 charpathname, 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.2 堆(Heap)
-
动态内存分配: 堆用于存储
动态分配的数据
,即在运行时通过函数(如malloc
、calloc
、realloc
)手动申请的内存。 -
手动释放: 堆上的内存需要
手动释放
,否则可能导致内存泄漏。通常使用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;