欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

C语言中关于open和fopen的区别

程序员文章站 2022-05-28 11:55:23
int open(const char *path, int access,int mode) path 要打开的文件路径和名称 access 访问模式,宏定义和含义如下: o_rdonly 1 只...

int open(const char *path, int access,int mode)

path 要打开的文件路径和名称

access 访问模式,宏定义和含义如下:

o_rdonly 1 只读打开

o_wronly 2 只写打开

o_rdwr 4 读写打开

还可选择以下模式与以上3种基本模式相与:

o_creat 0x0100 创建一个文件并打开

o_trunc 0x0200 打开一个已存在的文件并将文件长度设置为0,其他属性保持

o_excl 0x0400 未使用

o_append 0x0800 追加打开文件

o_text 0x4000 打开文本文件翻译cr-lf控制字符

o_binary 0x8000 打开二进制字符,不作cr-lf翻译

mode 该参数仅在access=o_creat方式下使用,其取值如下:

s_ifmt 0xf000 文件类型掩码

s_ifdir 0x4000 目录

s_ififo 0x1000 fifo 专用

s_ifchr 0x2000 字符专用

s_ifblk 0x3000 块专用

s_ifreg 0x8000 只为0x0000

s_iread 0x0100 可读

s_iwrite 0x0080 可写

s_iexec 0x0040 可执行

file *fopen(char *filename, char *mode)

filename 文件名称

mode 打开模式:

r 只读方式打开一个文本文件

rb 只读方式打开一个二进制文件

w 只写方式打开一个文本文件

wb 只写方式打开一个二进制文件

a 追加方式打开一个文本文件

ab 追加方式打开一个二进制文件

r+ 可读可写方式打开一个文本文件

rb+ 可读可写方式打开一个二进制文件

w+ 可读可写方式创建一个文本文件

wb+ 可读可写方式生成一个二进制文件

a+ 可读可写追加方式打开一个文本文件

ab+ 可读可写方式追加一个二进制文件

open和fopen的区别:

前者属于低级io,后者是高级io。

前者返回一个文件描述符,后者返回一个文件指针。

前者无缓冲,后者有缓冲。

前者与 read, write 等配合使用, 后者与 fread, fwrite等配合使用。

后者是在前者的基础上扩充而来的,在大多数情况下,用后者。

fopen的一个实现

#if defined(_posix_source)
#include 
#endif
#include 
#include 
#include "loc_incl.h"

#define pmode    0666
#define o_rdonly 0
#define o_wronly 1
#define o_rdwr   2
#define o_creat  0x010
#define o_trunc  0x020
#define o_append 0x040

int _open(const char *path, int flags);
int _creat(const char *path, mode_t mode);
int _close(int d);

file * fopen(const char *name, const char *mode)
{
    register int i;
    int rwmode = 0, rwflags = 0;
    file *stream;
    int fd, flags = 0;

    for (i = 0; __iotab[i] != 0 ; i++)
            if ( i >= fopen_max-1 )
                    return (file *)null;

    switch(*mode++) {
    case 'r':
            flags |= _ioread | _ioreading;        
            rwmode = o_rdonly;
            break;
    case 'w':
            flags |= _iowrite | _iowriting;
            rwmode = o_wronly;
            rwflags = o_creat | o_trunc;
            break;
    case 'a':
            flags |= _iowrite | _iowriting | _ioappend;
            rwmode = o_wronly;
            rwflags |= o_append | o_creat;
            break;         
    default:
            return (file *)null;
    }

    while (*mode) {
            switch(*mode++) {
            case 'b':
                    continue;
            case '+':
                    rwmode = o_rdwr;
                    flags |= _ioread | _iowrite;
                    continue;

            default:
                    break;
            }
            break;
    }

    if ((rwflags & o_trunc)
        || (((fd = _open(name, rwmode)) < 0)
                && (rwflags & o_creat))) {
            if (((fd = _creat(name, pmode)) > 0) && flags  | _ioread) {
                    (void) _close(fd);
                    fd = _open(name, rwmode);
            }

    }

    if (fd < 0) return (file *)null;

    if (( stream = (file *) malloc(sizeof(file))) == null ) {
            _close(fd);
            return (file *)null;
    }

    if ((flags & (_ioread | _iowrite))  == (_ioread | _iowrite))
            flags &= ~(_ioreading | _iowriting);
    stream->_count = 0;
    stream->_fd = fd;
    stream->_flags = flags;
    stream->_buf = null;
    __iotab[i] = stream;
    return stream;
}