博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Linux C 文件操作
阅读量:4162 次
发布时间:2019-05-26

本文共 2838 字,大约阅读时间需要 9 分钟。

文件操作应该是Linux系统最常用的操作了,Linux把系统中的所有的设备都映射成了文件,所以操作设备,也就是在操作文件。

Linux上的文件操作个人理解可以分为两个部分,一个是C标准库的部分(stdio.c),还有一个就是Linux系统标准接口。

1.先来介绍标准库的部分吧,常用的函数就是打开文件fopen,写入文件fputc, fputs, fwrite,关闭文件fclose.

函数原型如下:

FILE * fopen( char *path, char * mode ) ; //mode分为r,w,a,分别对应读,写,和添加打开方式int fclose( FILE *stream );int fputc( int c, FILE *stream );int fputs( char *s, FILE *stream );size_t fwrite( void *ptr, size_t size, size_t nmemb, FILE *stream )//这个主要用来存储结构数组,ptr为结构数组头指针,size为结构大小,nmemb为数组大小
 2. 接下来是系统接口:

int open( char *path, int flag ) ;//返回文件标识来给read,write用int close( int fd );size_t read( int fd, void *buff, size_t count );size_t write( int fd, void *buff, size_t count );

文件接口其实并不复杂,除了这些,还涉及到磁盘缓存的概念,因为为了效率原因,并不是每次操作都需要真实的去写硬盘,c标准库提供了fflush和Linux接口提供了sync操作来强制系统进行磁盘操作。

 

对于标准库而言,因为是针对所有的系统的比如Linux,Windows等等,所以底层实现需要系统支持的,比如现在这个文件操作,实际最终也是调用系统接口的。

所以这两个部分可以理解成C标准库中的文件操作是用第二个系统标准接口实现的,其实我们也可以自己实现的。

用图来表示可以如下:

 

接下来对比一下两个库的效率。

以写入50000行日志为例:

#include 
#include
#include
#include
#include
int main_cstadard( int argc, char *argv[] ){ if ( argc != 3 ) { printf( "usage:\ngenlog 100 log.txt\n" ); return 1; } long len = atoi( argv[1] ); FILE * fd = fopen( argv[2], "w+" ); if ( fd != NULL ) { int i = 0; char buff[30]; struct tm *gmTime; time_t timeTPre = time( NULL ); for ( ; i < len; i++ ) { time_t timeT = time(NULL); gmTime = gmtime( &timeT ); sprintf( buff, "%4d-%02d-%02d %02d:%02d:%02d %d\n", gmTime->tm_year + 1900, gmTime->tm_mon + 1, gmTime->tm_mday, gmTime->tm_hour, gmTime->tm_min, gmTime->tm_sec, i ); fputs( buff, fd ); }; fclose( fd ); printf( "Log %s is finished. \nCost time %d sec\n", argv[2], time(NULL) - timeTPre ); }}int main_linuxapi( int argc, char *argv[] ){ if ( argc != 3 ) { printf( "usage:\ngenlog 100 log.txt\n" ); return 1; } long len = atoi( argv[1] ); int fd = open( argv[2], O_RDWR | O_TRUNC | O_CREAT ); if ( fd != -1 ) { int i = 0; char buff[30]; struct tm *gmTime; time_t timeTPre = time( NULL ); for ( ; i < len; i++ ) { time_t timeT = time(NULL); gmTime = gmtime( &timeT ); sprintf( buff, "%4d-%02d-%02d %02d:%02d:%02d %d\n", gmTime->tm_year + 1900, gmTime->tm_mon + 1, gmTime->tm_mday, gmTime->tm_hour, gmTime->tm_min, gmTime->tm_sec, i ); write( fd, buff, strlen( buff ) ); }; close( fd ); printf( "Log %s is finished. \nCost time %d sec\n", argv[2], time(NULL) - timeTPre ); }}

输出结果,标准库花了1秒,直接调用API花了16秒,这个应该就是C标准库缓冲区比较大,做了些优化,带来的好处。

[chenndao@localhost log]$ gcc -o genlogc genlog.c

[chenndao@localhost log]$ ./genlogc 50001 50001.txt
Log 50001.txt is finished. 
Cost time 1 sec

[chenndao@localhost log]$ ./genlog 50001 50000.txt

Log 50000.txt is finished. 
Cost time 15 sec

转载地址:http://pdixi.baihongyu.com/

你可能感兴趣的文章
Static 作用详述
查看>>
透析ICMP协议(三): 牛刀初试之一 应用篇ping(ICMP.dll)
查看>>
透析ICMP协议(四): 牛刀初试之二 应用篇ping(RAW Socket)
查看>>
再次写给我们这些浮躁的程序员
查看>>
Linux下重要日志文件及查看方式(1)
查看>>
Linux下重要日志文件及查看方式(2)
查看>>
Ubuntu系统root用户密码找回方法
查看>>
Linux驱动程序中比较重要的宏
查看>>
芯片驱动问题定位思路总结之一单板重启的问题
查看>>
S3C2440看门狗定时器
查看>>
LDD3源码分析之llseek分析
查看>>
linux read 用法
查看>>
LDD3源码分析之llseek分析(二)
查看>>
printk及控制台的日志级别
查看>>
Linux驱动加载实例
查看>>
详解数据库设计中的三大范式理论
查看>>
JDBCUtils工具类
查看>>
Linux基本命令(1)
查看>>
Linux基本命令(二)
查看>>
Hive2.0函数大全(中文版)
查看>>