文章详情

  • 游戏榜单
  • 软件榜单
关闭导航
热搜榜
热门下载
热门标签
php爱好者> php文档>GNU/Linux应用程序开发学习笔记(一) 文件操作

GNU/Linux应用程序开发学习笔记(一) 文件操作

时间:2011-02-05  来源:Endlessor

 
GNU/Linux的文件操作是通过标准C库实现的,可以用同一个API创建ASCII或二进制文件,其中文件操作函数有很多个,分别对应不同方面的功能,可谓是面面具到,下面就逐一学习。
1.Header file
在C中 ,
#include <stdio.h>
在C++中,
#include <cstdio>
2.Open File
一般用fopen()函数来打开文件,fclose()函数关闭文件。

FILE* fopen(const char* filename, const char* mode);

其中mode是文件访问模式:
* r 打开一个已经存在的文件进行度操作
* w 打开一个文件进行写操作
* a 对文件进行追加操作
* rw 对文件进行读写操作
上面后三个模式中,如果文件不存在,则会创建一个新文件filename,而第一个返回 (FILE*)NULL.
文件字符接口
对文件进行逐个字符操作时,可使用如下两个函数:

int fputc(int c, FILE* stream);
int fgetc(FILE* stream);

其中fputc()中是int类型,别忘了类型转换,示例:

int func()
{
    char str[] = "Hey, it's just a test!";
    FILE* fin = fopen(filename,"a");
    FILE* fout = fopen(filename,"r");
    if(fout == (FILE*)NULL || fin == (FILE*)NULL)
        exit(-1);
    int i = 0;
    // write string STR to the file every bytes
    while(str[i] != NULL)
    {
        fputc((int)str[i],fin);
        ++i;
    }
    // get bytes from file through fgetc() until the end of the file
    while( (ch=fgetc(fout)) != EOF )
    {
        printf("%c",ch);
    }
    fclose(fin);
    fclose(fout);
    return 0;
}


字符串接口
对文件进行逐字符串的操作函数和字符操作函数类似,用法也类似
fputs() , fgets();
ASCII字符文件操作
这类文件操作也是比较常见的操作,应用很广,主要以下几种:

int fprintf(FILE* stream, const char* format, ...);
int fscanf(FILE* stream, const char* format, ...);
int sprintf(char* str, const char* format, ...);
int sscanf(char* str, const char* format, ...);


二进制文件的读写
这类文件操作比较重要,特点是处理快,适用范围广,先看fread和fwrite

size_t fread(void* ptr, size_t size, size_t nmemb, FILE* stream);
size_t fwrite(const void* ptr, size_t size, size_t nmemb,FILE* stream);

其中ptr指的是所需要处理的对象组,比如字符串或者结构题数组,size代表每个对象的字节数,nmemb代表对象的数目,这里要注意:当对象组是字符串时,nmemb=str_len+1,原因是字符串最后的'\0'不能省略。

void rewind(FILE* stream);

重置文件流指针到文件首。

int fseek(FILE* stream, long offset, int whence);

这个函数是设置文件流指针,offset是偏移值,whence有几个标志:
* SEEK_SET 将指针移到距离文件首offset个字节的位置
* SEEK_CUR 将指针移到距离当前指针位置后offset个字节的位置
* SEEK_END 将指针移到距离文件尾offset个字节的位置
注意:offset为正数时表示指针向后移动,为负数时向前移动,这个地方写了程序各种测试才发现,以前以为SEEK_END是将指针向前移动offset字节....无语......
long ftell(FILE* stream);
此函数返回文件流的指针位置,是long型,通过这个可以方便的查看文件指针的位置。
还有两个和上面功能一样的函数是fgetpos,fsetpos,但是使用目的也不一样,ftell和fseek函数没有对其机制的细节进行抽象,所以推荐使用fgetpos,fsetpos,原型如下:

int fgetpos(FILE* stream, fpos_t* pos);
int fsetpos(FILE* stream, fpos_t* pos);

这两个函数通过对指针位置的抽象操作和细节描述达到比ftell,fseek更加直观的目的,他们返回的不是指针的绝对位置,而是抽象位置,所以就可以用fpos_t类型来对文件位置进行描述。
上面这些是对二进制文件操作的函数,下面是示例:

#include <iostream>
#include <cstdio>
using namespace std;

#define MAXN_STR 40
#define MAXN_OBJECT 3

char file_name[] = "input";
char str[] = "This is a test.";
FILE* fout;
FILE* fin;
typedef struct{
    int id;
    float x;
    float y;
    char str[MAXN_STR+1];
}TYPE_NODE;
TYPE_NODE object[MAXN_OBJECT]={
    {1,10.2,12.2,"The earth"},
    {2,20.9,20.8,"The arm"},
    {3,12.3,12.4,"The null"}
};
TYPE_NODE tmp_object;

int main()
{
    fin = fopen(file_name,"w");
    if(fin == (FILE*)NULL)
    {
        exit(-1);
    }
    fwrite((void*)object,sizeof(TYPE_NODE),MAXN_OBJECT,fin);
    fwrite((void*)str,sizeof(str[0]),strlen(str)+1,fin);
    fclose(fin);
    fout = fopen(file_name,"r");
    if(fout == (FILE*)NULL)
    {
        exit(-1);
    }
    char ss[MAXN_STR];
    int pos;
    for(int i = 0; i < MAXN_OBJECT; ++i)
    {
        rewind(fout);
        fseek(fout,(i*sizeof(TYPE_NODE)),SEEK_CUR);
        pos = ftell(fout);
        printf("cur pos %d\n",pos);
        fread(&tmp_object,sizeof(TYPE_NODE),1,fout);
        printf("%d %f %f %s\n",tmp_object.id,tmp_object.x,
                tmp_object.y,tmp_object.str);
    }
    fread(ss,sizeof(ss[0]),strlen(str)+1,fout);
    printf("%s\n",ss);

    fclose(fout);
    return 0;
}


基础API
这里之写出两个:

ssize_t pread(int filedes, void* buf, size_t nbyte, off_t offset);
ssize_t pwrite(int filedes, void* buf, size_t nbyte, off_t offset);


这两个函数需要设置offset来对文件进行读写,但是不会影响文件指针,比较适合随机查找的情况。

====== 总结之 文件操作API======

FILE* fopen(const char* filename,const char* mode);
FILE* fdopen(int filedes, const char* type);
int fputc(int c,FILE* stream);
int fgetc(FILE* stream);
int fprintf(FILE* stream, const char* format, ...);
int fscanf(FILE* stream, const char* format, ...);
int sprintf(char* str, const char* format, ...);
int sscanf(char* str, const char* format, ...);
size_t fread(void* ptr,size_t size,size_t nmemb,FILE* stream);
size_t fwrite(const void* ptr,size_t size,size_t nmemb,FILE* stream);
void rewind(FILE* stream);
long ftell(FILE* stream);
int fseek(FILE* stream,long offset,    int whence);
int lseek(FILE* stream,long offset, int whence);
int fgetpos(FILE* stream, fpos_t* pos);
int fsetpos(FILE* stream, fpos_t* pos);
int fclose(FILE* stream);
int open(const char* pathname, int flags);
int open(const char* pathname, int flags, mode_t mode);
相关阅读 更多 +
排行榜 更多 +
辰域智控app

辰域智控app

系统工具 下载
网医联盟app

网医联盟app

运动健身 下载
汇丰汇选App

汇丰汇选App

金融理财 下载