Unix/Linux环境C编程新手教程(40) 初识文件操作

??

1.函数介绍


close(关闭文件)


相关函数


open,fcntl。shutdown,unlink,fclose


表头文件


#include<unistd.h>


定义函数


int close(int fd);


函数说明


当使用完文件后若已不再须要则可使用close()关闭该文件,二close()会让数据写回磁盘,并释放该文件所占用的资源。

參数fd为先前由open()或creat()所返回的文件描写叙述词。


返回值


若文件顺利关闭则返回0,发生错误时返回-1。


错误代码


EBADF 參数fd 非有效的文件描写叙述词或该文件已关闭。


附加说明


尽管在进程结束时,系统会自己主动关闭已打开的文件,但仍建议自行关闭文件,并确实检查返回值。


范例


參考open()


 


creat(建立文件)


相关函数


read。write,fcntl。close,link,stat,umask,unlink,fopen


表头文件


#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>


定义函数


int creat(const char * pathname, mode_tmode);


函数说明


參数pathname指向欲建立的文件路径字符串。

Creat()相当于使用下列的调用方式调用open()
open(const char * pathname ,(O_CREAT|O_WRONLY|O_TRUNC));


错误代码


关于參数mode请參考open()函数。


返回值


creat()会返回新的文件描写叙述词,若有发生错误则会返回-1,并把错误代码设给errno。

EEXIST 參数pathname所指的文件已存在。
EACCESS 參数pathname 所指定的文件不符合所要求測试的权限
EROFS 欲打开写入权限的文件存在于仅仅读文件系统内
EFAULT 參数pathname 指针超出可存取的内存空间
EINVAL 參数mode 不对。

ENAMETOOLONG 參数pathname太长。
ENOTDIR 參数pathname为一文件夹
ENOMEM 核心内存不足
ELOOP 參数pathname有过多符号连接问题。

EMFILE 已达到进程可同一时候打开的文件数上限
ENFILE 已达到系统可同一时候打开的文件数上限


附加说明


creat()无法建立特别的装置文件,假设须要请使用mknod()。


范例


请參考open()。


 


dup(拷贝文件描写叙述词)


相关函数


open。close。fcntl。dup2


表头文件


#include<unistd.h>


定义函数


int dup (int oldfd);


函数说明


dup()用来复制參数oldfd所指的文件描写叙述词,并将它返回。此新的文件描写叙述词和參数oldfd指的是同一个文件,共享全部的锁定、读写位置和各项权限或旗标。比如,当利用lseek()对某个文件描写叙述词作用时。还有一个文件描写叙述词的读写位置也会随着改变。

只是。文件描写叙述词之间并不共享close-on-exec旗标。


返回值


当复制成功时。则返回最小及尚未使用的文件描写叙述词。若有错误则返回-1。errno会存放错误代码。

错误代码EBADF參数fd非有效的文件描写叙述词,或该文件已关闭。


 


dup2(拷贝文件描写叙述词)


相关函数


open,close,fcntl,dup


表头文件


#include<unistd.h>


定义函数


int dup2(int odlfd,int newfd);


函数说明


dup2()用来复制參数oldfd所指的文件描写叙述词,并将它拷贝至參数newfd后一块返回。

若參数newfd为一已打开的文件描写叙述词,则newfd所指的文件会先被关闭。dup2()所复制的文件描写叙述词,与原来的文件描写叙述词共享各种文件状态,详情可參考dup()。


返回值


当复制成功时,则返回最小及尚未使用的文件描写叙述词。

若有错误则返回-1,errno会存放错误代码。


附加说明


dup2()相当于调用fcntl(oldfd,F_DUPFD。newfd);请參考fcntl()。


错误代码


EBADF 參数fd 非有效的文件描写叙述词,或该文件已关闭


 


fcntl(文件描写叙述词操作)


相关函数


open,flock


表头文件


#include<unistd.h>
#include<fcntl.h>


定义函数


int fcntl(int fd , int cmd);
int fcntl(int fd,int cmd,long arg);
int fcntl(int fd,int cmd,struct flock * lock);


函数说明


fcntl()用来操作文件描写叙述词的一些特性。參数fd代表欲设置的文件描写叙述词。參数cmd代表欲操作的指令。
有下面几种情况:
F_DUPFD用来查找大于或等于參数arg的最小且仍未使用的文件描写叙述词,而且复制參数fd的文件描写叙述词。运行成功则返回新复制的文件描写叙述词。请參考dup2()。F_GETFD取得close-on-exec旗标。若此旗标的FD_CLOEXEC位为0。代表在调用exec()相关函数时文件将不会关闭。
F_SETFD 设置close-on-exec 旗标。该旗标以參数arg 的FD_CLOEXEC位决定。

F_GETFL 取得文件描写叙述词状态旗标,此旗标为open()的參数flags。

F_SETFL 设置文件描写叙述词状态旗标,參数arg为新旗标,但仅仅同意O_APPEND、O_NONBLOCK和O_ASYNC位的改变,其它位的改变将不受影响。

F_GETLK 取得文件锁定的状态。
F_SETLK 设置文件锁定的状态。

此时flcok 结构的l_type 值必须是F_RDLCK、F_WRLCK或F_UNLCK。假设无法建立锁定,则返回-1。错误代码为EACCES 或EAGAIN。
F_SETLKW F_SETLK 作用同样。可是无法建立锁定时,此调用会一直等到锁定动作成功为止。

若在等待锁定的过程中被信号中断时,会马上返回-1,错误代码为EINTR。參数lock指针为flock 结构指针,定义例如以下
struct flcok
{
short int l_type; /* 锁定的状态*/
short int l_whence;/*决定l_start位置*/
off_t l_start; /*锁定区域的开头位置*/
off_t l_len; /*锁定区域的大小*/
pid_t l_pid; /*锁定动作的进程*/
};
l_type 有三种状态:
F_RDLCK 建立一个供读取用的锁定
F_WRLCK 建立一个供写入用的锁定
F_UNLCK 删除之前建立的锁定
l_whence 也有三种方式:
SEEK_SET 以文件开头为锁定的起始位置。
SEEK_CUR 以眼下文件读写位置为锁定的起始位置
SEEK_END 以文件结尾为锁定的起始位置。


返回值


成功则返回0,若有错误则返回-1,错误原因存于errno.


 


flock(锁定文件或解除锁定)


相关函数


open,fcntl


表头文件


#include<sys/file.h>


定义函数


int flock(int fd,int operation);


函数说明


flock()会依參数operation所指定的方式对參数fd所指的文件做各种锁定或解除锁定的动作。此函数仅仅能锁定整个文件,无法锁定文件的某一区域。


參数


operation有下列四种情况:
LOCK_SH 建立共享锁定。多个进程可同一时候对同一个文件作共享锁定。

LOCK_EX 建立相互排斥锁定。一个文件同一时候仅仅有一个相互排斥锁定。
LOCK_UN 解除文件锁定状态。

LOCK_NB 无法建立锁定时,此操作可不被阻断,马上返回进程。通常与LOCK_SH或LOCK_EX 做OR(|)组合。
单一文件无法同一时候建立共享锁定和相互排斥锁定,而当使用dup()或fork()时文件描写叙述词不会继承此种锁定。


返回值


返回0表示成功,若有错误则返回-1,错误代码存于errno。


 


fsync(将缓冲区数据写回磁盘)


相关函数


sync


表头文件


#include<unistd.h>


定义函数


int fsync(int fd);


函数说明


fsync()负责将參数fd所指的文件数据,由系统缓冲区写回磁盘,以确保数据同步。


返回值


成功则返回0,失败返回-1,errno为错误代码。


 


lseek(移动文件的读写位置)


相关函数


dup。open。fseek


表头文件


#include<sys/types.h>
#include<unistd.h>


定义函数


off_t lseek(int fildes,off_t offset ,int whence);


函数说明


每个已打开的文件都有一个读写位置。当打开文件时通常其读写位置是指向文件开头,若是以附加的方式打开文件(如O_APPEND),则读写位置会指向文件尾。

当read()或write()时。读写位置会随之添加,lseek()便是用来控制该文件的读写位置。參数fildes 为已打开的文件描写叙述词。參数offset 为依据參数whence来移动读写位置的位移数。


參数


whence为下列当中一种:
SEEK_SET 參数offset即为新的读写位置。
SEEK_CUR 以眼下的读写位置往后添加offset个位移量。
SEEK_END 将读写位置指向文件尾后再添加offset个位移量。
当whence 值为SEEK_CUR 或SEEK_END时。參数offet同意负值的出现。
下列是教特别的使用方式:
1) 欲将读写位置移到文件开头时:lseek(int fildes,0,SEEK_SET)。
2) 欲将读写位置移到文件尾时:lseek(int fildes。0,SEEK_END);
3) 想要取得眼下文件位置时:lseek(int fildes。0,SEEK_CUR);


返回值


当调用成功时则返回眼下的读写位置,也就是距离文件开头多少个字节。

若有错误则返回-1,errno 会存放错误代码。


附加说明


Linux系统不同意lseek()对tty装置作用,此项动作会令lseek()返回ESPIPE。


范例


參考本函数说明


 


mkstemp(建立唯一的暂时文件)


相关函数


mktemp


表头文件


#include<stdlib.h>


定义函数


int mkstemp(char * template);


函数说明


mkstemp()用来建立唯一的暂时文件。

參数template 所指的文件名字符串中最后六个字符必须是XXXXXX。

Mkstemp()会以可读写模式和0600 权限来打开该文件,假设该文件不存在则会建立该文件。

打开该文件后其文件描写叙述词会返回。文件顺利打开后返回可读写的文件描写叙述词。

若果文件打开失败则返回NULL。并把错误代码存在errno 中。


错误代码


EINVAL 參数template 字符串最后六个字符非XXXXXX。

EEXIST 无法建立暂时文件。


附加说明


參数template所指的文件名字符串必须声明为数组,如:
char template[ ] =”template-XXXXXX”;
千万不能够使用下列的表达方式
char *template = “template-XXXXXX”;


范例


#include<stdlib.h>
main( )
{
int fd;
char template[ ]=”template-XXXXXX”;
fd=mkstemp(template);
printf(“template = %s\n”,template);
close(fd);
}


运行


template = template-lgZcbo


 


open(打开文件)


相关函数


read,write,fcntl,close。link,stat。umask,unlink,fopen


表头文件


#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>


定义函数


int open( const char * pathname, int flags);
int open( const char * pathname,int flags, mode_t mode);


函数说明


參数pathname 指向欲打开的文件路径字符串。下列是參数flags 所能使用的旗标:
O_RDONLY 以仅仅读方式打开文件
O_WRONLY 以仅仅写方式打开文件
O_RDWR 以可读写方式打开文件。

上述三种旗标是相互排斥的,也就是不可同一时候使用。但可与下列的旗标利用OR(|)运算符组合。
O_CREAT 若欲打开的文件不存在则自己主动建立该文件。

O_EXCL 假设O_CREAT 也被设置,此指令会去检查文件是否存在。文件若不存在则建立该文件。否则将导致打开文件错误。

此外,若O_CREAT与O_EXCL同一时候设置,而且欲打开的文件为符号连接。则会打开文件失败。
O_NOCTTY 假设欲打开的文件为终端机设备时。则不会将该终端机当成进程控制终端机。
O_TRUNC 若文件存在而且以可写的方式打开时,此旗标会令文件长度清为0。而原来存于该文件的资料也会消失。
O_APPEND 当读写文件时会从文件尾開始移动。也就是所写入的数据会以附加的方式添加到文件后面。

O_NONBLOCK 以不可阻断的方式打开文件,也就是不管有无数据读取或等待。都会马上返回进程之中。
O_NDELAY 同O_NONBLOCK。
O_SYNC 以同步的方式打开文件。
O_NOFOLLOW 假设參数pathname 所指的文件为一符号连接,则会令打开文件失败。
O_DIRECTORY 假设參数pathname 所指的文件并不是为一文件夹,则会令打开文件失败。
此为Linux2.2以后特有的旗标,以避免一些系统安全问题。

參数mode 则有下列数种组合,仅仅有在建立新文件时才会生效,此外真正建文件时的权限会受到umask值所影响。因此该文件权限应该为(mode-umaks)。
S_IRWXU00700 权限。代表该文件全部者具有可读、可写及可运行的权限。
S_IRUSR 或S_IREAD。00400权限,代表该文件全部者具有可读取的权限。
S_IWUSR 或S_IWRITE。00200 权限。代表该文件全部者具有可写入的权限。

S_IXUSR 或S_IEXEC。00100 权限。代表该文件全部者具有可运行的权限。

S_IRWXG 00070权限。代表该文件用户组具有可读、可写及可运行的权限。
S_IRGRP 00040 权限,代表该文件用户组具有可读的权限。
S_IWGRP 00020权限。代表该文件用户组具有可写入的权限。

S_IXGRP 00010 权限,代表该文件用户组具有可运行的权限。

S_IRWXO 00007权限,代表其它用户具有可读、可写及可运行的权限。
S_IROTH 00004 权限,代表其它用户具有可读的权限
S_IWOTH 00002权限。代表其它用户具有可写入的权限。
S_IXOTH 00001 权限,代表其它用户具有可运行的权限。


返回值


若全部欲核查的权限都通过了检查则返回0 值。表示成功,仅仅要有一个权限被禁止则返回-1。


错误代码


EEXIST 參数pathname 所指的文件已存在。却使用了O_CREAT和O_EXCL旗标。

EACCESS 參数pathname所指的文件不符合所要求測试的权限。
EROFS 欲測试写入权限的文件存在于仅仅读文件系统内。
EFAULT 參数pathname指针超出可存取内存空间。
EINVAL 參数mode 不对。
ENAMETOOLONG 參数pathname太长。

ENOTDIR 參数pathname不是文件夹。

ENOMEM 核心内存不足。

ELOOP 參数pathname有过多符号连接问题。

EIO I/O 存取错误。


附加说明


使用access()作用户认证方面的推断要特别小心,比如在access()后再作open()空文件可能会造成系统安全上的问题。


范例


#include<unistd.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
main()
{
int fd,size;
char s [ ]=”Linux Programmer!\n”,buffer[80];
fd=open(“/tmp/temp”,O_WRONLY|O_CREAT);
write(fd,s,sizeof(s));
close(fd);
fd=open(“/tmp/temp”,O_RDONLY);
size=read(fd,buffer,sizeof(buffer));
close(fd);
printf(“%s”,buffer);
}


运行


Linux Programmer!


 


read(由已打开的文件读取数据)


相关函数


readdir。write,fcntl,close,lseek。readlink,fread


表头文件


#include<unistd.h>


定义函数


ssize_t read(int fd,void * buf ,size_t count);


函数说明


read()会把參数fd 所指的文件传送count个字节到buf指针所指的内存中。若參数count为0。则read()不会有作用并返回0。

返回值为实际读取到的字节数,假设返回0,表示已到达文件尾或是无可读取的数据,此外文件读写位置会随读取到的字节移动。


附加说明


假设顺利read()会返回实际读到的字节数,最好能将返回值与參数count 作比較。若返回的字节数比要求读取的字节数少,则有可能读到了文件尾、从管道(pipe)或终端机读取。或者是read()被信号中断了读取动作。当有发生错误时则返回-1,错误代码存入errno中。而文件读写位置则无法预期。


错误代码


EINTR 此调用被信号所中断。

EAGAIN 当使用不可阻断I/O 时(O_NONBLOCK),若无数据可读取则返回此值。

EBADF 參数fd 非有效的文件描写叙述词,或该文件已关闭。


范例


參考open()。


 


sync(将缓冲区数据写回磁盘)


相关函数


fsync


表头文件


#include<unistd.h>


定义函数


int sync(void)


函数说明


sync()负责将系统缓冲区数据写回磁盘,以确保数据同步。


返回值


返回0。


 


write(将数据写入已打开的文件内)


相关函数


open,read。fcntl,close,lseek,sync,fsync。fwrite


表头文件


#include<unistd.h>


定义函数


ssize_t write (int fd,const void * buf,size_t count);


函数说明


write()会把參数buf所指的内存写入count个字节到參数fd所指的文件内。当然。文件读写位置也会随之移动。


返回值


假设顺利write()会返回实际写入的字节数。

当有发生错误时则返回-1。错误代码存入errno中。


错误代码


EINTR 此调用被信号所中断。
EAGAIN 当使用不可阻断I/O 时(O_NONBLOCK),若无数据可读取则返回此值。

EADF 參数fd非有效的文件描写叙述词,或该文件已关闭。


范例


请參考open()。

2.小试牛刀

学习了这么多函数的使用方法,我们须要将这个函数全部揉在一起写一个小demo了哦。

流程设计:

首先创建一个文件   使用open或者create函数

然后往里面写入一个字符串缓冲区的内容

利用sync函数(将缓冲区数据写回磁盘)

将内容读取出来

关闭文件

Demo源代码

#include<unistd.h>

#include<sys/types.h>

#include<sys/stat.h>

#include<fcntl.h>

#include <stdio.h>

int main(void)

{

        int fd; //文件描写叙述符

        int size; //标记字节数

        char s [ ]="Just test it!\n"; //作为输入缓冲区

        char buffer[80];                 //作为输出缓冲区

        fd=open("/tmp/test.txt",O_WRONLY|O_CREAT);

        if(fd > 0)

            printf("打开文件/tmp/test.txt 成功\n");

         //ssize_t write (int fd,const void * buf,size_t count);

        size = write(fd,s,sizeof(s));

        if(size <= sizeof(s))

             printf("写入文件成功%d字节\n",size);

        //刷新缓冲区

        sync();

        printf("刷新文件缓冲区\n");

        close(fd);

        printf("关闭文件缓冲区\n");

        fd=open("/tmp/temp",O_RDONLY);

        //ssize_t read(int fd,void * buf ,size_t count);

        size=read(fd,buffer,sizeof(buffer));

        if(size <= sizeof(buffer))

            printf("文件已经度去完毕\n");

        close(fd);

        printf("文件关闭\n");

        printf("文件内容为:%s\n",buffer);

    return 0;

}

平台效果

在RHEL7上

在MAC上

时间: 2024-08-09 06:42:27

Unix/Linux环境C编程新手教程(40) 初识文件操作的相关文章

Unix/Linux环境C编程入门教程(40) 初识文件操作

?? 1.函数介绍 close(关闭文件) 相关函数 open,fcntl,shutdown,unlink,fclose 表头文件 #include<unistd.h> 定义函数 int close(int fd); 函数说明 当使用完文件后若已不再需要则可使用close()关闭该文件,二close()会让数据写回磁盘,并释放该文件所占用的资源.参数fd为先前由open()或creat()所返回的文件描述词. 返回值 若文件顺利关闭则返回0,发生错误时返回-1. 错误代码 EBADF 参数fd

Unix/Linux环境C编程新手教程(22) C/C++怎样获取程序的执行时间

1.问:知道程序执行时间我们能够做什么? 在<C++应用程序性能优化>一书中,假设大家读过相信大家一定对性能优化这一块很上心,文中总是对优化前后的时间对照很直观给我们一个感受. 那么我们怎样利用C语言提供的库函数获取一个应用程序的各阶段的执行效率,通过数据分析出该程序的瓶颈而且做出对应的优化. 本文给大家解说的clock()函数. 2.我们首先看一看C/C++标准文档对于clock()函数的解说 3.函数原型 clock_t clock (void); 函数返回值 clock()返回从&quo

Unix/Linux环境C编程新手教程(24) MySQL 5.7.4 for Red Hat Enterprise 7(RHEL7)的安装

远观历史, MySQL的主要目的是为了可以在单处理器核心的商业服务器上执行.现在MySQL的一个变化用户可能不会注意到,那就是甲骨文已经開始又一次架构MySQL的代码,使它大量的模块化.如软件解析器,优化和复制功能以模块化的形式被重写.该版本号的查询性能得以大幅提升,比 MySQL 5.6 提升 1 倍,新版本号的 MySQL 在測试平台上可达到每秒 512000 仅仅读 QPS,而 MySQL 5.6 最高仅仅能到 250000 QPS.该性能的提升是通过其 Memcached 插件实现的.同

Unix/Linux环境C编程新手教程(12) openSUSECCPP以及Linux内核驱动开发环境搭建

1. openSUSE是一款优秀的linux. watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvaXRjYXN0Y3Bw/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" /> 2.选择默认虚拟机 3.选择稍后安装操作系统 4.选择linux  opensuse 5. 选择默认虚拟机名称 6.设置处理器为双核. watermark/2/text/a

Unix/Linux环境C编程入门教程(12) openSUSECCPP以及Linux内核驱动开发环境搭建

1. openSUSE是一款优秀的linux. 2.选择默认虚拟机 3.选择稍后安装操作系统 4.选择linux  opensuse 5. 选择默认虚拟机名称 6.设置处理器为双核. 7.内存设置为2G 8. 选择网络地址转换 9.设置IO控制器 10. 选择默认磁盘类型 11.创建一个新的虚拟磁盘 12.设置磁盘大小 13.选择路径保存虚拟磁盘 14. 完成虚拟机创建 15.设置虚拟机 16.选择opensuse镜像 17.开启虚拟机 18.虚拟机启动 19.安装opensuse 20.安装程

Unix/Linux环境C编程入门教程(1) Solaris 11 64bit环境搭建

Unix/Linux版本众多,我们推荐Unix/Linux初学者选用几款典型的Unix/Linux操作系统进行学习. 本文就带大家来安装Solaris 11 64位并且配置好C/C++开发环境 本文所需软件下载地址 33.  F2 开始安装 34.待安装完成 按F8重启 35.重启后的界面  直接回车  启动 36. 登陆切换到我们刚刚创建的用户 待切成功的时候我们就加载合成的镜像文件sol-11_1-repo-full.iso 然后我们切换到root用户 37.先取消掉已连接的状态 38.重新

Unix/Linux环境C编程入门教程(5) Red Hat Enterprise Linux(RHEL)环境搭建

Unix/Linux版本众多,我们推荐Unix/Linux初学者选用几款典型的Unix/Linux操作系统进行学习. Red Hat Enterprise Linux是Red Hat公司的Linux发行版,面向商业市场,包括大型机.红帽公司从Red Hat Enterprise Linux 5开始对企业版LINUX的每个版本提供10年的支持[1].而Red Hat Enterprise Linux常简作RHEL. 1. 启动Vmware,如果没有安装的话,请看前面VMware安装的视频 2.选中

Unix/Linux环境C编程入门教程(24) MySQL 5.7.4 for Red Hat Enterprise 7(RHEL7)的安装

远观历史, MySQL的主要目的是为了能够在单处理器核心的商业服务器上运行.如今MySQL的一个变化用户可能不会注意到,那就是甲骨文已经开始重新架构MySQL的代码,使它大量的模块化.如软件解析器,优化和复制功能以模块化的形式被重写.该版本的查询性能得以大幅提升,比 MySQL 5.6 提升 1 倍,新版本的 MySQL 在测试平台上可达到每秒 512000 只读 QPS,而 MySQL 5.6 最高只能到 250000 QPS.该性能的提升是通过其 Memcached 插件实现的.同时该版本在

Unix/Linux环境C编程入门教程(41) C语言库函数的文件操作详解

?? 上一篇博客我们讲解了如何使用Linux提供的文件操作函数,本文主要讲解使用C语言提供的文件操作的库函数. 1.函数介绍 fopen(打开文件) 相关函数 open,fclose 表头文件 #include<stdio.h> 定义函数 FILE * fopen(const char * path,const char * mode); 函数说明 参数path字符串包含欲打开的文件路径及文件名,参数mode字符串则代表着流形态. mode有下列几种形态字符串: r 打开只读文件,该文件必须存