Linux API之文件操作
1.Linux中使用errno表示系统错误,errno就是error number,是由OS来维护的一个全局变量,任何OS内部函数都可以通过设置errno来告诉上层调用者究竟刚才发生了一个什么错误。errno本身实质是一个int类型的数字,当上层通过系统调用时可以通过errno判断是否成功。
常见的errno错误对应关系:
#define EPERM 1 /* Operation not permitted /
#define ENOENT 2 / No such file or directory /
#define ESRCH 3 / No such process /
#define EINTR 4 / Interrupted system call /
#define EIO 5 / I/O error /
#define ENXIO 6 / No such device or address /
#define E2BIG 7 / Argument list too long */
linux提供了2个API,如下:
1.#include <stdio.h>
void perror(const char *s);//perror - print a system error messag
2.#include <string.h>
char *strerror(int errnum);//strerror return string describing error number
- 函数原型: int fseek( FILE *stream, long offset, int origin );
第一个参数stream为文件指针
第二个参数offset为偏移量,整数表示正向偏移,负数表示负向偏移
第三个参数origin设定从文件的哪里开始偏移,可能取值为:SEEK_CUR、 SEEK_END 或 SEEK_SET
SEEK_SET: 文件开头
SEEK_CUR: 当前位置
SEEK_END: 文件结尾
其中SEEK_SET,SEEK_CUR和SEEK_END和依次为0,1和2.
简言之:
fseek(fp,100L,0);把fp指针移动到离文件开头100字节处;
fseek(fp,100L,1);把fp指针移动到离文件当前位置100字节处;
fseek(fp,100L,2);把fp指针退回到离文件结尾100字节处。
下面通过一个简单例子使用上面的2个API
#include <stdio.h>
#include <string.h>
#include <errno.h>
long filesize(FILE* fp)
{
long curpos,length;
curpos = ftell(fp); //获取文件指针指向的当前位置
fseek(fp,0L,SEEK_END); //把文件指针定位到文件末尾
length=ftell(fp);
fseek(fp,curpos,SEEK_SET); //再把文件指针定位到原来的位置
return length;
}
int main(int argc,char* argv[])
{
FILE *fp;
fp=fopen("MYFILE.TXT", "w+");
if(fp==NULL)
{
printf("fopen failed,strerror(errno):[%s]\n",strerror(errno));
return -1;
}
fprintf(fp, "This is a test");
printf("Filesize of MYFILE.TXT is %ld bytes\n", filesize(fp));
fclose(fp);
return 0;
}
亲测有效,愿对你有所帮助!
- 从文件中读取指定字段的字,在项目用到的频率很高
#define FILE_PATH "/tmp/mn/dev.conf"
int get_value_from_local(char *key,char *value){
FILE *fp = fopen(FILE_PATH,"r");
if(fp == NULL){
printf("fopen %s error\n",FILE_PATH);
return -1;
}
char buffer1[128] = {0};
char buffer2[128] = {0};
char linebuffer[256] = {0};
while(fgets(linebuffer, LINE_BUFF, fp))
{
if(linebuffer[strlen(linebuffer)-1] == '\n')
linebuffer[strlen(linebuffer)-1] = '\0';
memset(buffer1,0,sizeof(buffer1));
memset(buffer2,0,sizeof(buffer2));
sscanf(linebuffer, "%[^:]:%[^:]", buffer1,buffer2);
if(strcmp(buffer1,key) == 0){
strcpy(value,buffer2);
}
}
fclose(fp);
return 0;
}
通过get_value_from_local("devmac",g_devmac);调用可以获取devmac字段的值
get_value_from_local该函数接口目前只支持这种devmac:90102091000B类似键值对的格式,如果修改函数功能可通过修改sscanf中占位符的匹配格式。
这里着重说下sscanf中占位符匹配格式:
这里先说下函数原型:
int scanf(const char *format, ...); //标准输入
int fscanf(FILE *stream, const char *format, ...);//指定输入流
int sscanf(const char *str, const char *format, ...);//指定缓存区
格式如下:
"%s" 整个输入作为一个串,并设置末尾的'\0'
"%ns",n为整数,读入的串最长不超过n,然后在末尾补'\0'
%nf 读入的浮点数最多有n位整数,位数多于n,会截断。
"%n[a-z]" 读入最多n个字符,如果遇到非a-z的字符,停止
"%[^=]" 读入任意多的字符,直到遇到"="停止
"%n[^=]" 读入"="号前的至多n 个字符
%[^:]表示读取任意非:的字符串
^表示"非",即读入其后面的字符就结束读入。这样想读入一行字符串直接用scanf("%[^\n]%*c",str);就可以了,
%*c的作用是读入\n,否则后面读入的将一直是\n。