【Linux】应用篇四--文件IO

一、介绍

文件IO,又称系统IO系统调用
操作系统提供的API接口函数

posix(可移植操作系统接口)定义的一组函数
  • 不提供缓冲机制,每次读写操作都引起系统调用
  • 核心概念是文件描述符
  • 访问各种类型文件
  • Linux下, 标准IO基于文件IO实现
    在这里插入图片描述

二、文件描述符

英文:缩写fd(file descriptor)
0-1023数字,表示文件

  • 每个打开的文件都对应一个文件描述符
  • 文件描述符是一个非负整数。Linux为程序中每个打开的文件分配一个文件描述符。
  • 文件描述符从0开始分配,依次递增
  • 文件IO操作通过文件描述符来完成。
  • 0, 1, 2 表示标准输入标准输出错误

三、文件打开与关闭

1、文件打开

 #include <fcntl.h>
 int open(const char *pathname, int flags);
 int open(const char *pathname, int flags, mode_t mode);

open函数用来创建或打开一个文件:
成功时返回文件描述符出错时返回EOF(-1)

  • 打开文件时使用两个参数
  • 创建文件第三个参数指定新文件的权限,(只有在建立新文件时有效)此外真正建文件时的权限会受到umask 值影响,实际权限mode-umaks(umask 用来设定文件或目录的初始权限)
  • 可以打开设备文件,但是不能创建设备文件

参数图:
在这里插入图片描述
与标准IO函数的对应:

  • rO_RDONLY
  • r+O_RDWR
  • wO_WRONLY | O_CREAT | O_TRUNC, 0664
  • w+O_RDWR | O_CREAT | O_TRUNC, 0664
  • aO_WRONLY | O_CREAT | O_APPEND, 0664
  • a+O_RDWR | O_CREAT | O_APPEND, 0664

示例:

int  fd;

if ((fd  = open(1.txt”, O_RDWR|O_CREAT|O_EXCL, 0666)) < 0)
{
    if (errno == EEXIST) 
    { 
       perror(“exist error”);
    } else 
       perror(“other error”);
}

2、文件关闭

#include  <unistd.h>
 int  close(int fd);

用法与fclose相同,函数用来关闭一个打开的文件:
成功时返回0出错时返回EOF(-1)

  • 程序结束时自动关闭所有打开的文件
  • 文件关闭后,文件描述符不再代表文件

四、文件读取、写入与定位

1、文件写

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

write函数用来向文件写入数据:
成功时返回实际写入的字节数出错时返回EOF(-1)

  • buf发送数据缓冲区
  • count不应超过buf大小

示例:将键盘输入的内容写入文件,直到输入quit

int  fd;
    char  buf[20];

    if ((fd  = open(argv[1], O_WRONLY|O_CREAT|O_TRUNC, 0666)) < 0) 
    {
           perror(“open”);  
           return -1;
    }
    while (fgets(buf, 20, stdin) != NULL) 
    {
        if (strcmp(buf, “quit\n”) == 0) 
        	break;
        write(fd, buf, strlen(buf));
    }
    ……

2、文件读

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

read函数用来从文件中读取数据:
成功时返回实际读取的字节数出错时返回EOF(-1)

  • 读到文件末尾时返回0
  • buf接收数据缓冲区
  • count不应超过buf大小

示例:从指定的文件(文本文件)中读取内容并统计大小

int  main(int argc, char *argv[]) 
{
    int  fd, n, total = 0;
    char  buf[64];
    if (argc < 2) 
    {
        printf(“Usage : %s <file>\n”, argv[0]);  
        return -1;
    }
    if ((fd  = open(argv[1], O_RDONLY)) < 0) 
    {
    	perror(“open”);  
        return -1;
    }
    while ((n = read(fd, buf, 64)) > 0) 
    {
        total += n;
    }
    ……

3、文件定位

#include  <unistd.h>
 off_t  lseek(int fd, off_t offset, intt whence);

lseek函数用来定位文件:
成功时返回当前的文件读写位置出错时返回EOF(-1)

参数offset参数whencefseek完全一样


五、使用文件IO函数写日志程序

程序在上一节已经实现过,这里主要看与标准IO编写的区别就行了。
文章链接:【Linux】应用篇三–流的刷新定位与格式化输入输出

/*
 * @Author: xiuchengzhen
 * @Date: 2022-03-17 10:40:17
 * @LastEditTime: 2022-03-17 11:39:41
 */
#include<stdio.h>
#include<unistd.h>
#include<time.h>
#include<string.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>


int main(int argc, const char *argv[])
{
	long int clock;
	struct tm *clocktim;
	int order = 1;
	char str[32] = {0}, buf[32] = {0};
	int p = open("1.txt", O_RDWR|O_CREAT|O_APPEND, 0664);
	if(p == -1)
	{
		perror("fopen:");
		return -1;
	}

	while(read(p, str, 32) != 0)   //读到最后一行时,没有数据返回0
	{
		if(str[strlen(str)] == '\0')
			order++;
	}
	while(1)
	{
		clock = time(NULL);
		clocktim = localtime(&clock);

		sprintf(buf,"%d.%04d-%02d-%02d %02d:%02d:%02d\n", order, clocktim->tm_year+1900, clocktim->tm_mon+1, 
				clocktim->tm_mday,clocktim->tm_hour, clocktim->tm_min, clocktim->tm_sec);  //先将数据存入buf
		printf("%s", buf);
		if(write(p, buf, strlen(buf)) == -1)  //将buf的时间数据写入文件内
		{
			perror("write:");
			return -1;
		}
		
		memset(buf, 0 ,sizeof(buf));
		order++;

		sleep(1);
	}

	close(p);
	
	return 0;
}

到这里就结束啦!
在这里插入图片描述

  • 6
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 10
    评论
评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

修成真

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

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

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

打赏作者

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

抵扣说明:

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

余额充值