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] = '\0';

 

    printf("fread is %s\n",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] = '\0';

 

    printf("fread is %s\n",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] = '\0';

    fwrite(f_buf,2,8,fp);

    //printf("fread is %s\n",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] = '\0';

    fwrite(f_buf,2,4,fp);

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

    fclose(fp);

}

 

执行的结果:

 

posted @ 2016-02-14 08:31  cestlavie  阅读(376)  评论(0编辑  收藏  举报