Linux(CC++)下的⽂件操作open、fopen与freopen
open是下的底层系统调⽤函数,fopen与freopen c/c++下的标准I/O库函数,带输⼊/输出缓冲。
linxu下的fopen是open的封装函数,fopen最终还是要调⽤底层的系统调⽤open。
所以在linux下如果需要对设备进⾏明确的控制,那最好使⽤底层系统调⽤(open),
open对应的⽂件操作有:close, read, write,ioctl 等。
fopen 对应的⽂件操作有:fclose, fread, fwrite, freopen, fseek, ftell, rewind等。
freopen⽤于重定向输⼊输出流的函数,该函数可以在不改变代码原貌的情况下改变输⼊输出环境,但使⽤时应当保证流是可靠的。详细见第3部分。
-------------------------------------------------------------------------------------------------------------------
open和fopen的区别:
1,fread是带缓冲的,read不带缓冲.
2,fopen是标准c⾥定义的,open是POSIX中定义的.
3,fread可以读⼀个结构.read在linux/unix中读⼆进制与普通⽂件没有区别.
4,fopen不能指定要创建⽂件的权限.open可以指定权限.
5,fopen返回⽂件指针,open返回⽂件描述符(整数).
6,linux/unix中任何设备都是⽂件,都可以⽤open,read.
-------------------------------------------------------------------------------------------------------------------
1、open系统调⽤(linux)
需要包含头⽂件:#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
函数原型:int open( const char * pathname, int oflags);
int open( const char * pathname,int oflags, mode_t mode);
mode仅当创建新⽂件时才使⽤,⽤于指定⽂件的访问权限。
pathname 是待打开/创建⽂件的路径名;
oflags⽤于指定⽂件的打开/创建模式,这个参数可由以下常量(定义于 fcntl.h)通过逻辑或构成。
O_RDONLY      只读模式
O_WRONLY      只写模式
O_RDWR          读写模式
以上三者是互斥的,即不可以同时使⽤。
打开/创建⽂件时,⾄少得使⽤上述三个常量中的⼀个。以下常量是选⽤的:
O_APPEND        每次写操作都写⼊⽂件的末尾
O_CREAT            如果指定⽂件不存在,则创建这个⽂件
O_EXCL              如果要创建的⽂件已存在,则返回 -1,并且修改 errno 的值
O_TRUNC          如果⽂件存在,并且以只写/读写⽅式打开,则清空⽂件全部内容
O_NOCTTY        如果路径名指向终端设备,不要把这个设备⽤作控制终端。
O_NONBLOCK  如果路径名指向 FIFO/块⽂件/字符⽂件,则把⽂件的打开和后继 I/O设置为⾮阻塞模式(nonblocking mode)。
//以下⽤于同步输⼊输出
O_DSYNC          等待物理 I/O 结束后再 write。在不影响读取新写⼊的数据的前提下,不等待⽂件属性更新。
O_RSYNC          read 等待所有写⼊同⼀区域的写操作完成后再进⾏
O_SYNC            等待物理 I/O 结束后再 write,包括更新⽂件属性的 I/O
当你使⽤带有O_CREAT标志的open调⽤来创建⽂件时,你必须使⽤有3个参数格式的open调⽤。第三个参数mode是⼏个标志按位或后得到的,
这些标志在头⽂件sys/stat.h中定义,如下所⽰:
S_IRUSR:    读权限,⽂件属主
S_IWUSR:  写权限,⽂件属主
S_IXUSR:    执⾏权限,⽂件属主
S_IRGRP:    读权限,⽂件所属组
S_IWGRP:  写权限,⽂件所属组
S_IXGRP:    执⾏权限,⽂件所属组
S_IROTH:  读权限,其它⽤户
S_IWOTH:  写权限,其它⽤户
S_IXOTH:  执⾏权限,其它⽤户
返回值:成功则返回⽂件描述符,否则返回 -1。返回⽂件描述符(整型变量0~255)。由open 返回的⽂件描述符⼀定是该进程尚未使⽤的最⼩描述符。只要有⼀个权限被禁⽌则返回-1。
错误代码:(均已E开头,将其去掉就是有关于错误的⽅⾯的单词或单词的缩写)
EEXIST 参数pathname 所指的⽂件已存在,却使⽤了O_CREAT和O_EXCL旗标。
EACCESS 参数pathname所指的⽂件不符合所要求的权限。
EROFS 欲测试写⼊权限的⽂件存在于只读⽂件系统内。
EFAULT 参数pathname指针超出可存取内存空间。
EINVAL 参数mode 不正确。
ENAMETOOLONG 参数pathname太长。
ENOTDIR 参数pathname不是⽬录。
ENOMEM 核⼼内存不⾜。
ELOOP 参数pathname有过多符号连接问题。
EIO I/O 存取错误。
-------------------------------------------------------------------------------------------------------------------
ssize_t write(int fd, const void *buf, size_t count);
参数:
fd:要进⾏写操作的⽂件描述词。
buf:需要输出的缓冲区
count:最⼤输出字节计数
返回值:成功返回写⼊的字节数,出错返回-1并设置errno
-----------------------------------------------.--------------------------------------------------------------------
ssize_t read(int fd, void *buf, size_t count);
参数:
buf:需要读取的缓冲区
linux重定向
count:最⼤读取字节计数
返回值:成功返回读取的字节数,出错返回-1并设置errno,如果在调read之前已到达⽂件末尾,则这次read返回0 。
-------------------------------------------------------------------------------------------------------------------
2、fopen库函数
头⽂件:<stdio.h>
函数原型:FILE * fopen(const char * path, const char * mode);
path字符串包含欲打开的⽂件路径及⽂件名,参数mode字符串则代表着流形态。
mode有下列⼏种形态字符串:
"r"或"rb"        以只读⽅式打开⽂件,该⽂件必须存在。
"w"或"wb"    以写⽅式打开⽂件,并把⽂件长度截短为零。
"a"或"ab"      以写⽅式打开⽂件,新内容追加在⽂件尾。
"r+"或"rb+"或"r+b"      以更新⽅式打开(读和写)
"w+"或"wb+"或"w+b"  以更新⽅式打开,并把⽂件长度截短为零。
"a+"或"ab+"或"a+b"    以更新⽅式打开,新内容追加在⽂件尾。
字母b表⽰⽂件时⼀个⼆进制⽂件⽽不是⽂本⽂件。(linux下不区分⼆进制⽂件和⽂本⽂件)
返回值:⽂件顺利打开后,指向该流的⽂件指针就会被返回。如果⽂件打开失败则返回NULL,并把错误代码存在errno 中。
-------------------------------------------------------------------------------------------------------------------
fread是⼀个函数。从⼀个⽂件流中读数据,最多读取count个元素,每个元素size字节,如果调⽤成功返回实际读取到的元素个数,如果不成功或读到⽂件末尾返回 0。
函数原型:size_t fread ( void *buffer, size_t size, size_t count, FILE *stream) ;
参数:
buffer:⽤于接收数据的内存地址
size:要读写的字节数,单位是字节
count:要进⾏读写多少个size字节的数据项,每个元素是size字节.
stream:输⼊流
返回值:实际读取的元素个数.如果返回值与count不相同,则可能⽂件结尾或发⽣错误,从ferror和feof获取错误信息或检测是否到达⽂件结尾. -------------------------------------------------------------------------------------------------------------------
fwrite:向⽂件写⼊⼀个数据块
函数原型:size_t fwrite(const void* buffer, size_t size, size_t count, FILE* stream);
参数:
buffer:是⼀个指针,对fwrite来说,是要获取数据的地址;
size:要写⼊内容的单字节数;
count:要进⾏写⼊size字节的数据项的个数;
stream:⽬标⽂件指针;
返回值:返回实际写⼊的数据块数⽬
-------------------------------------------------------------------------------------------------------------------
fflush:把⽂件流⾥的所有为写出数据⽴刻写出。
函数原型:int fflush(FILE *stream);
-------------------------------------------------------------------------------------------------------------------
fseek:是lseek系统调⽤对应的⽂件流函数。它在⽂件流⾥为下⼀次读写操作指定位置。
函数原型:int fseek(FILE *stream, long offset, int fromwhere);
参数stream为⽂件指针
参数offset为偏移量,正数表⽰正向偏移,负数表⽰负向偏移
参数fromwhere设定从⽂件的哪⾥开始偏移,可能取值为:SEEK_CUR、 SEEK_END 或 SEEK_SET
SEEK_SET:⽂件开头
SEEK_CUR:当前位置
SEEK_END:⽂件结尾
其中SEEK_SET,SEEK_CUR和SEEK_END依次为0,1和2.
返回值:如果执⾏成功,stream将指向以fromwhere为基准,偏移offset(指针偏移量)个字节的位置,函数返回0。如果执⾏失败(⽐如offset超过⽂件⾃⾝⼤⼩),则不改变stream指向的位置,函数返回⼀个⾮0值。
-------------------------------------------------------------------------------------------------------------------
以下为linux下⼀个打开⽂件并显⽰⽂件内容的程序:
[objc]
1. #include <stdio.h>
2. #include <stdlib.h>
3. #include <unistd.h>
4. #include <fcntl.h>
5. #include <string.h>
6. #include <sys/types.h>
7. #include <sys/stat.h>
8.
9.
10. charchar * FILE_NAME = "/home/hzg/uart/download.bin";
11. unsigned char file_buffer[20];
12.
13.
14. int main()
15. {
16.    FILEFILE * file_fd;
17.    int read_len, i;
18.
19.    file_fd = fopen(FILE_NAME,"rb");
20.    if(file_fd == NULL)
21.    {
22.        perror("errno");
23.    }
24.    else
25.    {
26.        printf("File Open successed!\n");
27.    }
28.
29.    while(1)
30.    {
31.        read_len = fread(file_buffer, 1, 16, file_fd);
32.
33.        if(read_len == -1)
34.        {
35.            printf("File read error!\n");
36.            perror("errno");
37.            exit(0);
38.        }
39.        else if(read_len == 0)
40.        {
41.            printf("File read Over!\n");
42.            break;
43.        }
44.        else
45.        {
46.            printf("Read %d Byte From download.bin: ",read_len);
47.            for(i = 0; i < read_len; i++)
48.            {
49.                printf(" %02x",file_buffer[i]);
50.            }
51.            printf("\n");
52.        }
53.
54.        usleep(20000);
55.    }
56.
57.    fclose(file_fd);
58.    return 0;
59. }
3、freopen
函数原型:FILE * freopen ( const char * filename, const char * mode, FILE * stream );
参数:
filename: 要打开的⽂件名
mode: ⽂件打开的模式,和fopen中的模式(r/w)相同
stream: ⽂件指针,通常使⽤标准流⽂件(stdin/stdout/stderr)
返回值:如果成功则返回该指向该stream的指针,否则为NULL。
作⽤:⽤于重定向输⼊输出流的函数,将stream中的标准输⼊、输出、错误或者⽂件流重定向为filename⽂件中的内容。linux下需要重定向输出很容易使⽤ ./程序名 >test (>>test 追加),windows下的输⼊输出重定向可以使⽤freopen。
使⽤⽅法: 因为⽂件指针使⽤的是标准流⽂件,因此我们可以不定义⽂件指针。
我们使⽤freopen()函数以只读⽅式r(read)打开输⼊⽂件test.in ,freopen("test.in", "r", stdin);
这样程序的输⼊就会从标准输⼊流stdin转换到从⽂件"test.in"中输⼊
然后使⽤freopen()函数以写⼊⽅式w(write)打开输出⽂件test.out,freopen("test.out", "w", stdout);
程序的输出就会从原来的标准输出变成写⼊⽂件"test.out"中

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。