open是linux下的底层系统调用函数,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:需要读取的缓冲区
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下一个打开文件并显示文件内容的程序:

  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. charchar * FILE_NAME = "/home/hzg/uart/download.bin";
  9. unsigned char file_buffer[20];
  10. int main()
  11. {
  12. FILEFILE * file_fd;
  13. int read_len, i;
  14. file_fd = fopen(FILE_NAME,"rb");
  15. if(file_fd == NULL)
  16. {
  17. perror("errno");
  18. }
  19. else
  20. {
  21. printf("File Open successed!\n");
  22. }
  23. while(1)
  24. {
  25. read_len = fread(file_buffer, 1, 16, file_fd);
  26. if(read_len == -1)
  27. {
  28. printf("File read error!\n");
  29. perror("errno");
  30. exit(0);
  31. }
  32. else if(read_len == 0)
  33. {
  34. printf("File read Over!\n");
  35. break;
  36. }
  37. else
  38. {
  39. printf("Read %d Byte From download.bin: ",read_len);
  40. for(i = 0; i < read_len; i++)
  41. {
  42. printf(" %02x",file_buffer[i]);
  43. }
  44. printf("\n");
  45. }
  46. usleep(20000);
  47. }
  48. fclose(file_fd);
  49. return 0;
  50. }

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"中

linux下 open fopen区别的更多相关文章

  1. php windows与linux下的路径区别

    php windows与linux下的路径区别windows用的是"\",linux用的是"/"这一点要特别清楚,, ps:在PHP windows也可以用/表 ...

  2. Linux下“/”和“~”的区别

    在linux中,”/“代表根目录,”~“是代表目录.Linux存储是以挂载的方式,相当于是树状的,源头就是”/“,也就是根目录. 而每个用户都有”家“目录,也就是用户的个人目录,比如root用户的”家 ...

  3. 解决Windows下文件在Linux下打开出现乱码的问题

    目录 问题 原理 解决 总结 参考资料 问题 前几天生病了,Java一直在看代码但是没跟着打,于是决定偷一波小小的懒,直接把教材的代码从Windows通过共享文件夹放到了Linux里面.但是编译的时候 ...

  4. C++和C在linux下 和在windows下有什么区别?

    一.函数库的区别 linux下的C函数库和windows下的函数库系统调用的机制不一样,Glibc包含了主要的C库.这个库提供了基本例程,用于分配内存.搜索目录.打开关闭文件.读写文件.字串处理.模式 ...

  5. Linux下ps -ef和ps aux的区别及格式详解

    Linux下显示系统进程的命令ps,最常用的有ps -ef 和ps aux.这两个到底有什么区别呢?两者没太大差别,讨论这个问题,要追溯到Unix系统中的两种风格, System V风格和BSD 风格 ...

  6. <iostream> 和 <iostream.h>的区别 及 Linux下编译iostream.h的方法

    0.序言 其实2者主要的区别就是iostream是C++标准的输入输出流头文件,而iostream.h是非标准的头文件. 标准头文件iostream中的函数属于标准命令空间,而iostream.h中的 ...

  7. Linux下fork()、vfork()、clone()和exec()的区别

    转自Linux下fork().vfork().clone()和exec()的区别 前三个和最后一个是两个类型.前三个主要是Linux用来创建新的进程(线程)而设计的,exec()系列函数则是用来用指定 ...

  8. Linux下su与su -命令的区别

    在启动服务器ntpd服务时遇到一个问题 使用 su root 切换到root用户后,不可以使用service命令: 使用 su - 后,就可以使用service命令了. 原因: su命令和su -命令 ...

  9. [转] linux 下 进程和线程的区别

    1.进程与线程 进程是程序执行时的一个实例,即它是程序已经执行到课中程度的数据结构的汇集.从内核的观点看,进程的目的就是担当分配系统资源(CPU时间.内存等)的基本单位. 线程是进程的一个执行流,是C ...

随机推荐

  1. C++系统学习之九:顺序容器

    元素在顺序容器中的顺序与其加入容器时的位置相对应.关联容器中元素的位置由元素相关联的关键字值决定.所有容器类都共享公共的接口,不同容器按不同方式对其进行扩展. 一个容器就是一些特定类型对象的集合.顺序 ...

  2. 【最大权闭合子图 最小割】bzoj1497: [NOI2006]最大获利

    最大权闭合子图的模型:今天才发现dinic板子是一直挂的…… Description 新的技术正冲击着手机通讯市场,对于各大运营商来说,这既是机遇,更是挑战.THU集团旗下的CS&T通讯公司在 ...

  3. Latex使用笔记,中文,字号等

    中文 编译器选择的xelatex 或者lualatex 我试过的两种方式(都是基于ctex的). 直接使用ctex的基本documentclass \documentclass[UTF8]{ctexa ...

  4. MyBatis逆向工程中的Mapper接口以及Example的实例函数及详解

    一.mapper接口中的方法解析 mapper接口中的函数及方法 方法 功能说明 int countByExample(UserExample example) thorws SQLException ...

  5. 微信JS-SDK 示例

    微信JS-SDK 示例 1.html部分 <!DOCTYPE html> <!-- saved from url=(0028){sh:$selfUrl} --> <htm ...

  6. Python基础-函数参数

    Python基础-函数参数 写在前面 如非特别说明,下文均基于Python3 摘要 本文详细介绍了函数的各种形参类型,包括位置参数,默认参数值,关键字参数,任意参数列表,强制关键字参数:也介绍了调用函 ...

  7. GoF23种设计模式之行为型模式之状态模式

    一.概述         定义对象之间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新. 二.适用性 1.一个对象的行为取决于它的状态,并且它必须在运行时刻 ...

  8. Altium Designer入门学习笔记4:PCB设计中各层的含义

    阻焊层:solder mask,是指板子上要上绿油的部分:因为它是负片输出,所以实际上有solder mask的部分实际效果并不上绿油,而是镀锡,呈银白色! 助焊层:paste mask,是机器贴片时 ...

  9. HDU:2255-奔小康赚大钱(KM算法模板)

    传送门:http://acm.hdu.edu.cn/showproblem.php?pid=2255 奔小康赚大钱 Time Limit: 1000/1000 MS (Java/Others) Mem ...

  10. poj 2251 三维地图最短路径问题 bfs算法

    题意:给你一个三维地图,然后让你走出去,找到最短路径. 思路:bfs 每个坐标的表示为 x,y,z并且每个点都需要加上时间 t struct node{ int x, y, z; int t;}; b ...