zoukankan      html  css  js  c++  java
  • 9. 库函数方式文件编程

    9. 库函数方式文件编程

    库函数:基于C函数库的文件编程是独立于具体的操作系统平台的,不管是在windows、linux还是其他操作系统中,都是使用这些函数。使用库函数进行程序设计可以提高程序的可移植性。

    流:对于标准的C函数库,它们的操作都是围绕流来进行的。流是一个抽象的概念,当程序需要读取数据的时候,就会开启一个通向数据源的流,这个数据源可以是文件,内存,或是网络连接。类似的,当程序需要写入数据的时候,就会开启一个通向目的地的流。这时候你就可以想象数据好像在这其中"流"动一样。

    文件指针:

    在系统调用方式实现的文件访问中,使用文件描述符(一个整数)来指向一个文件。在库函数方式的文件访问中,使用FILE类型来表示一个打开的文件,这个类型中包含了管理文件流的信息。而指向该类型的指针FILE* 则被称之为文件指针。

    打开文件:

    打开文件的库函数是fopen,man fopen:得到下面信息:

    NAME

    fopen, fdopen, freopen - stream open functions

    SYNOPSIS

    #include <stdio.h>

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

    FILE *fdopen(int fd, const char *mode);

    FILE *freopen(const char *path, const char *mode, FILE *stream);

    Feature Test Macro Requirements for glibc (see feature_test_macros(7)):

    fdopen(): _POSIX_C_SOURCE >= 1 || _XOPEN_SOURCE || _POSIX_SOURCE

    DESCRIPTION

    The fopen() function opens the file whose name is the string pointed to by path

    and associates a stream with it.

    The argument mode points to a string beginning with one of the following sequences

    (Additional characters may follow these sequences.):

    r Open text file for reading. The stream is positioned at the beginning of

    the file.

    r+ Open for reading and writing. The stream is positioned at the beginning of

    the file.

    w Truncate file to zero length or create text file for writing. The stream

    is positioned at the beginning of the file.

    w+ Open for reading and writing. The file is created if it does not exist,

    otherwise it is truncated. The stream is positioned at the beginning of

    the file.

    a Open for appending (writing at end of file). The file is created if it

    does not exist. The stream is positioned at the end of the file.

    a+ Open for reading and appending (writing at end of file). The file is cre-

    ated if it does not exist. The initial file position for reading is at the

    beginning of the file, but output is always appended to the end of the

    file.

    The mode string can also include the letter 'b' either as a last character or as a

    character between the characters in any of the two-character strings described

    above. This is strictly for compatibility with C89 and has no effect; the 'b' is

    ignored on all POSIX conforming systems, including Linux. (Other systems may

    treat text files and binary files differently, and adding the 'b' may be a good

    idea if you do I/O to a binary file and expect that your program may be ported to

    non-Unix environments.)

    See NOTES below for details of glibc extensions for mode.

    Any created files will have mode S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH |

    S_IWOTH (0666), as modified by the process's umask value (see umask(2)).

    Reads and writes may be intermixed on read/write streams in any order. Note that

    ANSI C requires that a file positioning function intervene between output and

    input, unless an input operation encounters end-of-file. (If this condition is

    not met, then a read is allowed to return the result of writes other than the most

    recent.) Therefore it is good practice (and indeed sometimes necessary under

    Linux) to put an fseek(3) or fgetpos(3) operation between write and read opera-

    tions on such a stream. This operation may be an apparent no-op (as in fseek(...,

    0L, SEEK_CUR) called for its synchronizing side effect.

    Opening a file in append mode (a as the first character of mode) causes all subse-

    quent write operations to this stream to occur at end-of-file, as if preceded by

    an

    fseek(stream,0,SEEK_END);

    call.

    The fdopen() function associates a stream with the existing file descriptor, fd.

    The mode of the stream (one of the values "r", "r+", "w", "w+", "a", "a+") must be

    compatible with the mode of the file descriptor. The file position indicator of

    the new stream is set to that belonging to fd, and the error and end-of-file indi-

    cators are cleared. Modes "w" or "w+" do not cause truncation of the file. The

    file descriptor is not dup'ed, and will be closed when the stream created by

    fdopen() is closed. The result of applying fdopen() to a shared memory object is

    undefined.

    The freopen() function opens the file whose name is the string pointed to by path

    and associates the stream pointed to by stream with it. The original stream (if

    it exists) is closed. The mode argument is used just as in the fopen() function.

    The primary use of the freopen() function is to change the file associated with a

    standard text stream (stderr, stdin, or stdout).

    RETURN VALUE

    Upon successful completion fopen(), fdopen() and freopen() return a FILE pointer.

    Otherwise, NULL is returned and errno is set to indicate the error.

    ERRORS

    EINVAL The mode provided to fopen(), fdopen(), or freopen() was invalid.

    The fopen(), fdopen() and freopen() functions may also fail and set errno for any

    of the errors specified for the routine malloc(3).

    The fopen() function may also fail and set errno for any of the errors specified

    for the routine open(2).

    The fdopen() function may also fail and set errno for any of the errors specified

    for the routine fcntl(2).

    The freopen() function may also fail and set errno for any of the errors specified

    for the routines open(2), fclose(3) and fflush(3).

    CONFORMING TO

    The fopen() and freopen() functions conform to C89. The fdopen() function con-

    forms to POSIX.1-1990.

    NOTES

    Glibc Notes

    The GNU C library allows the following extensions for the string specified in

    mode:

    c (since glibc 2.3.3)

    Do not make the open operation, or subsequent read and write operations,

    thread cancellation points.

    e (since glibc 2.7)

    Open the file with the O_CLOEXEC flag. See open(2) for more information.

    m (since glibc 2.3)

    Attempt to access the file using mmap(2), rather than I/O system calls

    (read(2), write(2)). Currently, use of mmap(2) is only attempted for a

    file opened for reading.

    x Open the file exclusively (like the O_EXCL flag of open(2)). If the file

    already exists, fopen() fails, and sets errno to EEXIST. This flag is

    ignored for fdopen().

    SEE ALSO

    open(2), fclose(3), fileno(3), fmemopen(3), fopencookie(3)

    COLOPHON

    This page is part of release 3.22 of the Linux man-pages project. A description

    of the project, and information about reporting bugs, can be found at

    http://www.kernel.org/doc/man-pages/.

    我们从上面的信息知道,

    打开文件的函数的功能是open file,原型是:

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

    需要包含的头文件是:

    <stdio.h>

    返回值:如果成功是返回文件指针,失败则是NULL。参数:path就是要打开文件的路径,mode是文件打开模式,例如可读可写。

    fopen.c:

    #include <stdio.h>

    void main(){

        FILE *fp;

        fp = fopen("/home/wen","w+");

    }

    运行结果:

    关闭文件:

    关闭文件是fclose,man fopen的信息:

    NAME

    fclose - close a stream

    SYNOPSIS

    #include <stdio.h>

    int fclose(FILE *fp);

    DESCRIPTION

    The fclose() function will flushes the stream pointed to by fp (writing any

    buffered output data using fflush(3)) and closes the underlying file descriptor.

    RETURN VALUE

    Upon successful completion 0 is returned. Otherwise, EOF is returned and errno is

    set to indicate the error. In either case any further access (including another

    call to fclose()) to the stream results in undefined behavior.

    ERRORS

    EBADF The file descriptor underlying fp is not valid.

    The fclose() function may also fail and set errno for any of the errors specified

    for the routines close(2), write(2) or fflush(3).

    CONFORMING TO

    C89, C99.

    NOTES

    Note that fclose() only flushes the user space buffers provided by the C library.

    To ensure that the data is physically stored on disk the kernel buffers must be

    flushed too, for example, with sync(2) or fsync(2).

    SEE ALSO

    close(2), fcloseall(3), fflush(3), fopen(3), setbuf(3)

    COLOPHON

    This page is part of release 3.22 of the Linux man-pages project. A description

    of the project, and information about reporting bugs, can be found at

    http://www.kernel.org/doc/man-pages/.

    函数fclose的功能是关闭一个打开的文件,函数的原型是:

    int fclose(FILE *fp);

    需要的头文件:

    stdio.h

    如果关闭成功则返回0,失败则返回EOF。

    fclose.c:

    #include <stdio.h>

    void main(){

        FILE *fp;

        fp = fopen("/home/wen","w+");

        fclose(fp);

    }

    运行结果:

    读文件:

    在命令行man fread:

    NAME

    fread, fwrite - binary stream input/output

    SYNOPSIS

    #include <stdio.h>

    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);

    DESCRIPTION

    The function fread() reads nmemb elements of data, each size bytes long, from the

    stream pointed to by stream, storing them at the location given by ptr.

    The function fwrite() writes nmemb elements of data, each size bytes long, to the

    stream pointed to by stream, obtaining them from the location given by ptr.

    For non-locking counterparts, see unlocked_stdio(3).

    RETURN VALUE

    fread() and fwrite() return the number of items successfully read or written

    (i.e., not the number of characters). If an error occurs, or the end-of-file is

    reached, the return value is a short item count (or zero).

    fread() does not distinguish between end-of-file and error, and callers must use

    feof(3) and ferror(3) to determine which occurred.

    CONFORMING TO

    C89, POSIX.1-2001.

    SEE ALSO

    read(2), write(2), feof(3), ferror(3), unlocked_stdio(3)

    COLOPHON

    This page is part of release 3.22 of the Linux man-pages project. A description

    of the project, and information about reporting bugs, can be found at

    http://www.kernel.org/doc/man-pages/.

    fread函数是从文件中读取数据,函数的原型:

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

    需要的头文件:stdio.h

    返回值:如果读取成功则返回读取到的数据量,失败则返回0.

    Stream:指向要读取的文件。

    ptr:指向读取出来后的数据保存的位置。

    nmemb:是一次读取数据块的块数。

    size:就是每一块的大小。

    所以总的读取大小是nmemb*size。

    fread.c的代码:

    #include <stdio.h>

    void main(){

        FILE *fp;

        char f_buf[17];

        fp = fopen("/home/wen","w+");

        fread(f_buf,2,8,fp);

        f_buf[16] = '';

        printf("fread is %s ",f_buf);

        fclose(fp);

    }}运行的结果是读出的内容为空:

    这是为啥呢?其实问题出在fopen的w+参数,清空了内容。我们应该使用r+

    #include <stdio.h>

    void main(){

        FILE *fp;

        char f_buf[17];

        fp = fopen("/home/wen","r+");

        fread(f_buf,2,8,fp);

        f_buf[16] = '';

        printf("fread is %s ",f_buf);

        fclose(fp);

    }

    运行的结果:

    这个程序中最核心的就是:fread(f_buf,2,8,fp);它的意思是从fd文件指针所指定的地方读取数据,每次读2个字节,读8次,读得的结果存到f_buf里面。

    写文件:

    在命令行执行man fwrite:

    NAME

    fread, fwrite - binary stream input/output

    SYNOPSIS

    #include <stdio.h>

    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);

    DESCRIPTION

    The function fread() reads nmemb elements of data, each size

    bytes long, from the stream pointed to by stream, storing them

    at the location given by ptr.

    The function fwrite() writes nmemb elements of data, each size

    bytes long, to the stream pointed to by stream, obtaining them

    from the location given by ptr.

    For non-locking counterparts, see unlocked_stdio(3).

    RETURN VALUE

    fread() and fwrite() return the number of items successfully

    read or written (i.e., not the number of characters). If an

    error occurs, or the end-of-file is reached, the return value

    is a short item count (or zero).

    fread() does not distinguish between end-of-file and error,

    and callers must use feof(3) and ferror(3) to determine which

    occurred.

    CONFORMING TO

    C89, POSIX.1-2001.

    SEE ALSO

    read(2), write(2), feof(3), ferror(3), unlocked_stdio(3)

    COLOPHON

    This page is part of release 3.22 of the Linux man-pages

    project. A description of the project, and information about

    reporting bugs, can be found at http://www.kernel.org/doc/man-

    pages/.

    fwrite函数是向文件中写入数据,函数的原型:

    size_t fwrite(const void *ptr, size_t size, size_t nmemb,

    FILE *stream);

    需要的头文件:stdio.h

    返回值:如果读取成功则返回读取到的数据量,失败则返回0.

    Stream:指向要写入数据的文件的指针。

    ptr:指向存放要写入文件的数据

    nmemb:是一次写入数据块的块数。

    size:就是每一块的大小。

    所以总的读取大小是nmemb*size。

    fwrite.c:

    #include <stdio.h>

    void main(){

        FILE *fp;

        char *f_buf="1234567890123456";

        fp = fopen("/home/wen","r+");

        //fread(f_buf,2,8,fp);

        //f_buf[16] = '';

        fwrite(f_buf,2,8,fp);

        //printf("fread is %s ",f_buf);

        fclose(fp);

    }

    运行的结果:

    定位文件:

    函数fseek,通过man fseek查看信息:

    NAME

    fgetpos, fseek, fsetpos, ftell, rewind - reposition a stream

    SYNOPSIS

    #include <stdio.h>

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

    long ftell(FILE *stream);

    void rewind(FILE *stream);

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

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

    DESCRIPTION

    The fseek() function sets the file position indicator for the

    stream pointed to by stream. The new position, measured in

    bytes, is obtained by adding offset bytes to the position

    specified by whence. If whence is set to SEEK_SET, SEEK_CUR,

    or SEEK_END, the offset is relative to the start of the file,

    the current position indicator, or end-of-file, respectively.

    A successful call to the fseek() function clears the end-of-

    file indicator for the stream and undoes any effects of the

    ungetc(3) function on the same stream.

    The ftell() function obtains the current value of the file

    position indicator for the stream pointed to by stream.

    The rewind() function sets the file position indicator for the

    stream pointed to by stream to the beginning of the file. It

    is equivalent to:

    (void) fseek(stream, 0L, SEEK_SET)

    except that the error indicator for the stream is also cleared

    (see clearerr(3)).

    The fgetpos() and fsetpos() functions are alternate interfaces

    equivalent to ftell() and fseek() (with whence set to

    SEEK_SET), setting and storing the current value of the file

    offset into or from the object referenced by pos. On some

    non-Unix systems an fpos_t object may be a complex object and

    these routines may be the only way to portably reposition a

    text stream.

    RETURN VALUE

    The rewind() function returns no value. Upon successful com-

    pletion, fgetpos(), fseek(), fsetpos() return 0, and ftell()

    returns the current offset. Otherwise, -1 is returned and

    errno is set to indicate the error.

    ERRORS

    EBADF The stream specified is not a seekable stream.

    EINVAL The whence argument to fseek() was not SEEK_SET,

    SEEK_END, or SEEK_CUR.

    The functions fgetpos(), fseek(), fsetpos(), and ftell() may

    also fail and set errno for any of the errors specified for

    the routines fflush(3), fstat(2), lseek(2), and malloc(3).

    CONFORMING TO

    C89, C99.

    SEE ALSO

    lseek(2), fseeko(3)

    COLOPHON

    This page is part of release 3.22 of the Linux man-pages

    project. A description of the project, and information about

    reporting bugs, can be found at http://www.kernel.org/doc/man-

    pages/.

    fseek函数是实现定位文件指针的功能,函数的原型:

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

    需要的头文件:stdio.h

    返回值:返回值是移动后的文件指针距离文件头的位置的距离,失败则返回-1.

    Stream:指向要定位的文件。

    Whence: 它的取值有三种情况:SEEK_SET, SEEK_CUR,

    or SEEK_END,

    offset: 是偏移量,就是距离whence的距离。

    fwrite.c:

    #include <stdio.h>

    void main(){

        FILE *fp;

        char *f_buf="1234567890123456";

        fp = fopen("/home/wen","r+");

        fseek(fp,4,SEEK_SET);

        //fread(f_buf,2,4,fp);

        //f_buf[8] = '';

        fwrite(f_buf,2,4,fp);

        //printf("fread is %s ",f_buf);

        fclose(fp);

    }

    执行的结果:

  • 相关阅读:
    Web框架下安全漏洞的测试反思
    如何能低成本地快速获取大量目标用户,而不是与竞争对手持久战?
    Spring-Boot自定义Starter实践
    WM_QUERYENDSESSION与WM_ENDSESSION
    AutoMapper用法
    使用AutoMapper实现Dto和Model的自由转换(下)
    使用AutoMapper实现Dto和Model的自由转换(中)
    使用AutoMapper实现Dto和Model的自由转换(上)
    JSON中JObject和JArray的修改
    通信对象 System.ServiceModel.Channels.ServiceChannel 无法用于通信,因为其处于“出错”状态。
  • 原文地址:https://www.cnblogs.com/FORFISH/p/5188609.html
Copyright © 2011-2022 走看看