Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/file/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 使用open()而不是fopen()有什么普通的原因吗?_C_File_Posix_Libc - Fatal编程技术网

C 使用open()而不是fopen()有什么普通的原因吗?

C 使用open()而不是fopen()有什么普通的原因吗?,c,file,posix,libc,C,File,Posix,Libc,我正在用C语言做一个小项目,离它有很长一段时间了。这些碰巧包括一些文件处理。我在各种文档中注意到,有些函数返回FILE*句柄,有些函数返回(小整数)描述符。这两组函数都提供了我所需要的基本服务,所以我使用它们并不重要 但我对收藏智慧很好奇:使用fopen()和朋友,还是使用open()和朋友更好 编辑既然有人提到了缓冲与非缓冲以及访问设备,我应该补充一点,这个小项目的一部分将是在FUSE下编写用户空间文件系统驱动程序。因此,文件级访问可以在设备(如CDROM或SCSI驱动器)上进行,也可以在“文

我正在用C语言做一个小项目,离它有很长一段时间了。这些碰巧包括一些文件处理。我在各种文档中注意到,有些函数返回
FILE*
句柄,有些函数返回(小整数)描述符。这两组函数都提供了我所需要的基本服务,所以我使用它们并不重要

但我对收藏智慧很好奇:使用
fopen()
和朋友,还是使用
open()
和朋友更好


编辑既然有人提到了缓冲与非缓冲以及访问设备,我应该补充一点,这个小项目的一部分将是在FUSE下编写用户空间文件系统驱动程序。因此,文件级访问可以在设备(如CDROM或SCSI驱动器)上进行,也可以在“文件”(即图像)上进行。

通常,您应该使用标准库(fopen)。但是,有时您需要直接使用open


我想到的一个例子是解决旧版本solaris中的一个bug,该bug导致fopen在打开256个文件后失败。这是因为他们在结构文件实现中错误地使用了一个无符号字符作为fd字段,而不是int。但这是一个非常特殊的情况。

是的。当你需要一个低级手柄时

在UNIX操作系统上,通常可以交换文件句柄和套接字

此外,低级句柄比文件指针具有更好的ABI兼容性。

如果您坚持使用类似unix的系统,并且您可能希望:

  • 在文件创建时对unix权限位进行更细粒度的控制
  • 使用较低级别的函数,如读/写/mmap,而不是C缓冲流I/O函数
  • 使用基于文件描述符(fd)的IO调度(轮询、选择等)。您当然可以使用fileno()从文件*获取fd,但必须注意不要将基于文件*的流函数与基于fd的函数混合使用
  • 打开任何特殊设备(非常规文件)

最好使用fopen/fread/fwrite以实现最大的可移植性,因为这些是标准的C函数,我上面提到的函数不是。

fopen的工作级别比open更高。。。。 fopen返回指向文件流的指针,该指针类似于在C中读取的流抽象++

open为打开的文件返回一个文件描述符。。。它不为您提供流抽象,您自己负责处理位和字节。。。这与fopen相比处于较低水平

Stdio流是缓冲的,而open()文件描述符不是。这取决于你需要什么。您还可以从另一个创建一个:

int fileno(FILE*stream)返回文件*的文件描述符,FILE*fdopen(int fildes,const char*模式)从文件描述符创建文件*

混合使用缓冲和非缓冲IO时要小心,因为如果不使用fflush()刷新缓冲区,将丢失缓冲区中的内容。

反对“fopen”是可移植的,“open”不是假的

fopen是libc的一部分,open是POSIX系统调用

每一个都是便携式的,就像它们来自的地方一样

打开文件的i/o(您必须假设它可能是,并且出于实际目的,它是)由libc缓冲的,文件描述符open()不是由libc缓冲的(它们很可能是,并且通常是在文件系统中缓冲的——但并不是所有打开()的东西都是文件系统上的文件)

比如说,打开一个像/dev/sg0或/dev/tty0这样的设备节点有什么意义?你要做什么?你要在一个文件*上做一个ioctl?祝你好运


可能您希望使用一些标志打开,如O_DIRECT--对fopen()没有意义。

fopen及其同族将被缓冲。打开、读取和写入不会被缓冲。您的应用程序可能关心,也可能不关心

fprintf和scanf具有更丰富的API,允许您读取和写入格式化文本文件。读取和写入使用基本字节数组。转换和格式化必须手工制作

文件描述符和(文件*)之间的区别实际上是无关紧要的

Randy

读取()和写入()使用无缓冲I/O.(fd:整数文件描述符)

fread()&fwrite()使用缓冲I/O.(文件*结构指针)

由于字节对齐、大小可变等原因,使用write()写入管道的二进制数据可能无法使用fread()读取二进制数据。这是一个废话

大多数低级设备驱动程序代码使用无缓冲I/O调用

大多数应用程序级I/O使用缓冲

文件*及其相关函数的使用 在一台机器一台机器的基础上是可以的:但是便携性丧失了 关于二进制数据读写的其他体系结构。 fwrite()是缓冲I/O,如果 为64位体系结构编写并在32位;或(Windows/Linux)上运行。 大多数操作系统在自己的代码中都有兼容宏来防止这种情况

对于低级二进制I/O可移植性,read()和write()保证 在不同的体系结构上编译时,相同的二进制读取和写入。 最基本的是选择一种或另一种方式并保持一致, 整个二进制套件

<stdio.h>  // mostly FILE*  some fd input/output parameters for compatibility
             // gives you a lot of helper functions -->
List of Functions
       Function      Description
       ───────────────────────────────────────────────────────────────────
       clearerr      check and reset stream status
       fclose        close a stream
       fdopen        stream open functions //( fd argument, returns FILE*)                      feof          check and reset stream status
       ferror        check and reset stream status
       fflush        flush a stream
       fgetc         get next character or word from input stream
       fgetpos       reposition a stream
       fgets         get a line from a stream
       fileno        get file descriptor   // (FILE* argument, returns fd) 
       fopen         stream open functions
       fprintf       formatted output conversion
       fpurge        flush a stream
       fputc         output a character or word to a stream
       fputs         output a line to a stream
       fread         binary stream input/output
       freopen       stream open functions
       fscanf        input format conversion
       fseek         reposition a stream
       fsetpos       reposition a stream
       ftell         reposition a stream
       fwrite        binary stream input/output
       getc          get next character or word from input stream
       getchar       get next character or word from input stream
       gets          get a line from a stream
       getw          get next character or word from input stream
       mktemp        make temporary filename (unique)
       perror        system error messages
       printf        formatted output conversion
       putc          output a character or word to a stream
       putchar       output a character or word to a stream
       puts          output a line to a stream
       putw          output a character or word to a stream
       remove        remove directory entry
       rewind        reposition a stream
       scanf         input format conversion
       setbuf        stream buffering operations
       setbuffer     stream buffering operations
       setlinebuf    stream buffering operations
       setvbuf       stream buffering operations
       sprintf       formatted output conversion
       sscanf        input format conversion
       strerror      system error messages
       sys_errlist   system error messages
       sys_nerr      system error messages
       tempnam       temporary file routines
       tmpfile       temporary file routines
       tmpnam        temporary file routines
       ungetc        un-get character from input stream
       vfprintf      formatted output conversion
       vfscanf       input format conversion
       vprintf       formatted output conversion
       vscanf        input format conversion
       vsprintf      formatted output conversion
       vsscanf       input format conversion
//主要是文件*一些fd输入/输出参数的兼容性
//为您提供了许多帮助函数-->
功能列表
功能描述
───────────────────────────────────────────────────────────────────
clearerr检查和重置流状态
关闭一条小溪
fdopen stream open functions/(fd参数,返回文件*)
<unistd.h>   write()
             lseek()
             close()
             pipe()
<sys/types.h>
<sys/stat.h>
<fcntl.h>  open()
           creat()
           fcntl() 
all use file descriptors.