Linux(C/C++)下的文件操作open、fopen与freopen

Linux(C/C++)下的文件操作open、fopen与freopen

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下一个打开文件并显示文件内容的程序:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>

char * FILE_NAME = "/home/hzg/uart/download.bin";
unsigned char file_buffer[20];

int main()
{
    FILE * file_fd;
    int read_len, i;

    file_fd = fopen(FILE_NAME,"rb");
    if(file_fd == NULL)
    {
       perror("errno");
    }
    else
    {
       printf("File Open successed!\n");
    }

    while(1)
    {
       read_len = fread(file_buffer, 1, 16, file_fd);

       if(read_len == -1)
       {
           printf("File read error!\n");
           perror("errno");
           exit(0);
       }
       else if(read_len == 0)
       {
           printf("File read Over!\n");
           break;
       }
       else
       {
           printf("Read %d Byte From download.bin: ",read_len);
           for(i = 0; i < read_len; i++)
           {
                printf(" %02x",file_buffer[i]);
           }
           printf("\n");
       }

       usleep(20000);
    }

    fclose(file_fd);
    return 0;
} 

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下须要重定向输出非常easy使用 ./程序名 >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"中

时间: 2024-10-20 04:11:27

Linux(C/C++)下的文件操作open、fopen与freopen的相关文章

熟练掌握doc命令下的文件操作

这里以介绍操作php脚本为例 熟练掌握doc命令下的文件操作

linux下对文件操作报错----------Unable to *** ***: Read-only file system

在linux中对文件操作时报错:Unable to chmod ***: Read-only file system 用如下指令能解决该问题: 输入su root 进入超级用户 输入 mount -o remount rw / 然后可输入 mount 查看

linux下的文件操作——批量重命名

概述:在日常工作中,我们经常需要对一批文件进行重命名操作,例如将所有的jpg文件改成bnp,将名字中的1改成one,等等.文本主要为你讲解如何实现这些操作 1.删除所有的 .bak 后缀: rename 's/\.bak$//' *.bak 注意,这个命令的格式组织如下:s/   \.bark$   / / 是s/para1/para2/ 这个有点想sed的语法,将para1匹配的字符串换成para2 2.把 .jpe 文件后缀修改为 .jpg: rename 's/\.jpe$/\.jpg/'

Linux下的文件操作——基于文件指针的文件操作(缓冲)

目录操作 创建和删除目录: 原型为: #include <sys/stat.h> #include <sys/types.h> #include <unistd.h> int mkdir(const char *pathname, mode_t mode); //创建目录,mode是目录权限 int rmdir(const char *pathname); //删除目录 获取目录信息: 原型为: #include <sys/types.h> #include

C# WPF Application 下的文件操作

好气哦,电脑好烂,每天花大把的时间在等电脑反应上. 没有钱买新电脑,连组台式机的钱都没有.好气哦. 啊啊啊啊文件操作是什么鬼???C++下我都懵了,C#下好多东西要学!!!我不会!我不会!我不会!!!啊啊啊啊啊啊!!! 怎么办啊?用windows API写我要怎么样移植到Linux下? WINDOWS API的文件操作 一.常用函数 CreateFile 创建.打开文件 ReadFile 读取文件内容 WriteFile 写入文件内容 SetFilePointer 移动文件指针 SetEndOf

Linux基础命令,目录文件操作,vi编辑器详解

一.linux基础命令 linux命令的执行必须依赖于shell命令解释器.shell实际上是在linux系统中运行的一种特殊程序,它位于操作系统内核与用户之间,负责接收用户输入的命令并进行解释,将需要执行的操作传递给系统内核执行,shell在用户和内核之间充当了一个"翻译官"的角色.当用户登录到linux系统时,会自动加载一个shell程序,以便给用户提供可以输入命令的操作系统. 1.首先介绍一下快捷键 Tab键:用来补齐命令字或文件.目录名,例如输入"ifcon"

win下驱动文件操作相关函数封装

创建文件 //创建文件 HANDLE KernelCreateFile( IN PUNICODE_STRING pstrFile, // 文件路径符号链接 IN BOOLEAN bIsDir) // 是否为文件夹 { HANDLE hFile = NULL; NTSTATUS Status = STATUS_UNSUCCESSFUL; IO_STATUS_BLOCK StatusBlock = { 0 }; ULONG ulShareAccess = FILE_SHARE_READ | FILE

Linux命令之目录和文件操作

1 pwd:显示当前工作目录 [[email protected] ~]# pwd /root 2 cd:切换当前工作目录 [[email protected] /]# cd                   #切换到当前用户的家目录 [[email protected] ~]# cd ..                #切换到当前目录的上一级目录 [[email protected] /]# cd -                 #返回至前一个目录 3 ls:显示目录和文件信息 选项:

内核模式下的文件操作

1.文件的创建 对文件的创建或者打开都是通过内核函数ZwCreateFile实现的.和Windows API类似,这个内核函数返回一个文件句柄,文件的所有操作都是依靠这个句柄进行操作的.在文件操作完毕后,要关闭这个文件句柄. NTSTATUS     ZwCreateFile(     OUT PHANDLE  FileHandle,     IN ACCESS_MASK  DesiredAccess,     IN POBJECT_ATTRIBUTES  ObjectAttributes,