Linux编程-文件IO

Kozakemi Lv4

软连接与硬连接

软连接

ln -s file file.s #ln [选项]... [-T] 目标 链接名

类似于windows的快捷方式,file.s中存储的是访问路径,但是是相对的,如果将file.s的位置移动后,无法使用,如果想要使用绝对路径,则使用绝对路径创建

ln -s /home/kozakemi/test/linux_shell/file file.soft

这样操作后任意位置均可访问,因此,为了创建软连接是,尽量使用绝对路径创建软连接

实际上其原理为软连接文件存储的是路径

创建的软连接,文件名与日期均不同

文件类型为l

硬连接

创建的软连接权限为全开放,但是文件是否可被操作,是由源文件决定

ln file file.h  

这两个文件任意修改一个,均会更改源文件,文件名不同,而日期一致

原理是两个文件为Inode一致,因此修改一个文件时,会同时修改是有的Inode一致的文件,及硬连接的文件,linux为每个文件赋予唯一的Inode

当删除时就不是这个问题,做法是将硬连接计数减1

文件类型由源文件决定

系统调用

系统调用函数属于操作系统的一部分,是为了提供给用户进行操作的接口(API函数),使得用户态运行的进程与硬件设备(如CPU、磁盘、打印机、显示器)等进行交互。

image-20231016232409335

man

太男人了

这是一个非常好用的工具,在linux查询c库与系统调用十分便捷

man man 
1   可执行程序或 shell 命令
2 系统调用(内核提供的函数)
3 库调用(程序库中的函数)
4 特殊文件(通常位于 /dev)
5 文件格式和规范,如 /etc/passwd
6 游戏
7 杂项(包括宏包和规范), 如 man(7),groff(7), man-pages(7)
8 系统管理命令(通常只针对 root 用户)
9 内核例程 [非标准

文件IO

open()

概述

open, creat - 打开和/或创建一个文件

#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_t mode)
int creat(const char *pathname, mode_t mode);

参数

参数 pathname 为文件路径

flages是通过 O_RDONLY, O_WRONLYO_RDWR (指明 文件 是以 只读 , 只写 或 读写 方式 打开的)与下面的 零个 或 多个 可选模式 按位 -or 操作 得到的

       O_CREAT
若文件 不存在 将 创建 一个 新 文件. 新 文件 的 属主 (用户ID) 被 设置 为 此 程序 的 有效 用户
的 ID. 同样 文件 所属 分组 也 被 设置 为 此 程序 的 有效 分组 的 ID 或者 上层 目录 的 分组
ID (这 依赖 文件系统 类型 ,装载选项 和 上层目录 的 模式, 参考,在 mount(8) 中 描述 的 ext2 文
件系统 的 装载选项 bsdgroups 和 sysvgroups )
O_APPEND
文件 以 追加 模式 打开 . 在 写 以前 , 文件 读写 指针 被 置 在 文件 的 末尾 . as if with
lseek. O_APPEND may lead to corrupted files on NFS file systems if more than one process
appends data to a file at once. This is because NFS does not support appending to a file, so
the client kernel has to simulate it, which can't be done without a race condition.

#其余详见`man 2 open`

mode创建文件时指定权限

S_IRWXU
00700 允许 文件 的 属主 读 , 写 和 执行 文件

S_IRUSR (S_IREAD)
00400 允许 文件 的 属主 读 文件

S_IWUSR (S_IWRITE)
00200 允许 文件 的 属主 写 文件
#其余详见`man 2 open`

返回值

返回值为int类型,一般从3开始递增,

  • 文件描述符 0:标准输入(stdin)
  • 文件描述符 1:标准输出(stdout)
  • 文件描述符 2:标准错误输出(stderr)

以上三个描述符被系统占用,因此一般从3开始,例如下面的示例代码

示例代码

#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
int main() {
int fd;

// Open "tmp.txt" file in write-only mode
fd = open("tmp.txt", O_WRONLY);
if (fd == -1) {
perror("Error opening tmp.txt");
printf("Error opening tmp.txt: %s\n",strerror(errno));
}
printf("%d\n", fd);

// Open "tmp.txt" file in append mode for writing
fd = open("tmp.txt", O_WRONLY | O_APPEND);
if (fd == -1) {
perror("Error opening tmp.txt");
printf("Error opening tmp.txt: %s\n",strerror(errno));
}
printf("%d\n", fd);

// Open "Fol.txt" file in read-only mode, create if it doesn't exist with permissions 0777
fd = open("Fol.txt", O_RDONLY | O_CREAT, 0777);//8进制0开头
if (fd == -1) {
perror("Error opening Fol.txt");
printf("Error opening Fol.txt: %s\n",strerror(errno));
}
printf("%d\n", fd);

return 0;
}

目录文件结构

[kozakemi@kozakemi-arch linux_ccode]$ ls -l                                       
总计 8
-rw-r--r-- 1 kozakemi kozakemi 6 10月16日 23:29 1.txt
-rw-r--r-- 1 kozakemi kozakemi 563 10月16日 23:50 file_w.c
-rwxr-xr-x 1 kozakemi kozakemi 0 10月16日 23:46 Fol.txt
-rw-r--r-- 1 kozakemi kozakemi 0 10月16日 23:47 tmp.txt

执行结果

[kozakemi@kozakemi-arch linux_ccode]$ gcc '/home/kozakemi/test/linux_ccode/file_w.c' && ./a.out 
3
4
5

write()

概述

在一个文件描述符上执行写操作

#include <unistd.h>

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

参数

fd文件描述符,open的返回值

buf写入的字符串

count写入的大小

返回值

ssize_t为写入的字节数

示例代码

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

#include <unistd.h>
#include <errno.h>
#include <string.h>
int main() {
int fd;
ssize_t strno;
fd=open("Fol.txt",O_WRONLY|O_APPEND);
char infile_str[]="asdasdasd\n";
if(-1==fd)
{
printf("error Fol.txt: %s",strerror(errno));
perror("Fol.txt");
}else{
strno=write(fd, infile_str, strlen(infile_str));
printf("%d=%d=%d-1",strno,strlen(infile_str),sizeof(infile_str));
}
return 0;
}

read()

概述

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

#include <unistd.h>

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

参数

fd文件描述符,open的返回值

buf读出的字符串

count读出的大小

  • 需要注意的是count不要大于buf值(必定报错[1] 17806 IOT instruction (core dumped) ),更不要大于文件中内容的大小否则会出现不可预料的错误(虽然我测试时未遇到)

返回值

ssize_t为读出的字节数

示例代码

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

#include <unistd.h>
#include <errno.h>
#include <string.h>
int main() {
int fd;
ssize_t strno;
int readsize=10;
fd=open("Fol.txt",O_RDONLY);
char file_oustr[20]="";
if(-1==fd)
{
printf("error Fol.txt: %s",strerror(errno));
perror("Fol.txt");
}else{
strno=read(fd, file_oustr, readsize);
printf("%d,%s",strno,file_oustr);
}

return 0;
}

close()

概述

关闭一个文件描述符

#include <unistd.h>

int close(int fd);

参数

fd文件描述符

返回值

-1为关闭失败,0为关闭成功

示例代码

#include <unistd.h>  
。。。
fd=open("Fol.txt",O_RDONLY);
。。。
if(-1==close(fd)){
printf("error close file: %s",strerror(errno));
return -1;
}

lseek()

这是一个系统调用

概述

修改文件的描述符,偏移位置

#include <unistd.h>

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

参数

fd文件描述符

offset偏移量

whence偏移方式 

  • SEEK_SET:偏移到文件头+ 设置的偏移量
  • SEEK_CUR:偏移到当前位置+设置的偏移量
  • SEEK_END:偏移到文件尾置+设置的偏移量

返回值

off_t设置之后的文件偏移量,操作失败时返回-1,成功后返回偏移量

示例程序

查看当前的位置

#include <fcntl.h>
#include <stdio.h>

#include <unistd.h>
#include <errno.h>
int main() {
int fd,ret;
fd=open("Fol.txt",O_RDWR);
ret=lseek(fd,0,SEEK_CUR);
printf("%d\n",ret);
perror("lseek");
return 0;
}

查看文件大小

#include <fcntl.h>
#include <stdio.h>

#include <unistd.h>
#include <errno.h>
int main() {
int fd,ret;
fd=open("Fol.txt",O_RDWR);
ret=lseek(fd,0,SEEK_END);
printf("%d\n",ret);
perror("lseek");
return 0;
}

将字符串插入到指定的位置后

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

int main()
{
int fd,ret;
char a[]="JMU WELCOME";
fd=open("hello1.txt",O_RDWR|O_CREAT,0777);
ret=lseek(fd,1000,SEEK_END);
write(fd,a,strlen(a));
printf("%d\n",ret);
return 0;
}
  • 标题: Linux编程-文件IO
  • 作者: Kozakemi
  • 创建于 : 2023-10-17 15:42:58
  • 更新于 : 2024-05-17 13:47:59
  • 链接: https://kozakemi.gitlab.io/post/7eebe64b.html
  • 版权声明: 本文章采用 CC BY-NC-SA 4.0 进行许可。
评论