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


    GNU/Linux的文件操作

     
    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);
  • 相关阅读:
    假如
    Find the peace with yourself
    Sep 15th 2018
    Sep 10th 2018
    third party sales process 继续说
    成功设置open live writer
    sublime text2 基本配置及结合Python 环境
    Compmgmtlauncher.exe问题解决方法
    nginx 代理服务器
    vmware之linux不重启添加虚拟硬盘
  • 原文地址:https://www.cnblogs.com/lvpengms/p/1949212.html
Copyright © 2020-2023  润新知