- 浏览: 1999417 次
- 性别:
- 来自: 北京
文章分类
- 全部博客 (651)
- ACE (35)
- BAT (9)
- C/C++ (116)
- fast-cgi (14)
- COM (27)
- python (59)
- CGI (4)
- C# (2)
- VC (84)
- DataBase (29)
- Linux (96)
- P2P (6)
- PHP (15)
- Web (6)
- Memcached (7)
- IME输入法 (11)
- 设计模式 (2)
- 搜索引擎 (1)
- 个人情感 (4)
- 笔试/面试 (3)
- 一亩三分地 (33)
- 历史 (2)
- 地理 (1)
- 人物 (3)
- 经济 (0)
- 不仅仅是笑哦 (43)
- 小故事大道理 (2)
- http://www.bjdsmyysjk120.com/ (0)
- http://www.bjdsmyy120.com/ (0)
- 它山之石可以攻玉 (15)
- 大学生你关注些什么 (28)
- 数据恢复 (1)
最新评论
-
luokaichuang:
这个规范里还是没有让我明白当浏览器上传文件时,STDIN的消息 ...
FastCGI规范 -
effort_fan:
好文章!学习了,谢谢分享!
com技术简介 -
vcell:
有错误os.walk(strPath)返回的已经是全部的文件和 ...
通过python获取目录的大小 -
feifeigd:
feifeigd 写道注意:文章中的CPP示例第二行 #inc ...
ATL入门:利用ATL编写简单的COM组件 -
feifeigd:
注意:文章中的CPP示例第二行 #include " ...
ATL入门:利用ATL编写简单的COM组件
Linux下的C编程实战(二)
――文件系统编程
宋宝华 21cnbao@21cn.com
1.Linux文件系统
Linux支持多种文件系统,如ext、ext2、minix、iso9660、msdos、fat、vfat、nfs等。在这些具体文件系统的上层,Linux提供了虚拟文件系统(VFS)来统一它们的行为,虚拟文件系统为不同的文件系统与内核的通信提供了一致的接口。下图给出了Linux中文件系统的关系:
在Linux平台下对文件编程可以使用两类函数:(1)Linux操作系统文件API;(2)C语言I/O库函数。 前者依赖于Linux系统调用,后者实际上与操作系统是独立的,因为在任何操作系统下,使用C语言I/O库函数操作文件的方法都是相同的。本章将对这两种方法进行实例讲解。
2.Linux文件API
Linux的文件操作API涉及到创建、打开、读写和关闭文件。
创建
int creat(const char *filename, mode_t mode);
参数mode指定新建文件的存取权限,它同umask一起决定文件的最终权限(mode&umask),其中umask代表了文件在创建时需要去掉的一些存取权限。umask可通过系统调用umask()来改变:
int umask(int newmask);
该调用将umask设置为newmask,然后返回旧的umask,它只影响读、写和执行权限。
打开
int open(const char *pathname, int flags);
int open(const char *pathname, int flags, mode_t mode);
open函数有两个形式,其中pathname是我们要打开的文件名(包含路径名称,缺省是认为在当前路径下面),flags可以去下面的一个值或者是几个值的组合:
标志 |
含义 |
O_RDONLY |
以只读的方式打开文件 |
O_WRONLY |
以只写的方式打开文件 |
O_RDWR |
以读写的方式打开文件 |
O_APPEND |
以追加的方式打开文件 |
O_CREAT |
创建一个文件 |
O_EXEC |
如果使用了O_CREAT而且文件已经存在,就会发生一个错误 |
O_NOBLOCK |
以非阻塞的方式打开一个文件 |
O_TRUNC |
如果文件已经存在,则删除文件的内容 |
O_RDONLY、O_WRONLY、O_RDWR三个标志只能使用任意的一个。
如果使用了O_CREATE标志,则使用的函数是int open(const char *pathname,int flags,mode_t mode); 这个时候我们还要指定mode标志,用来表示文件的访问权限。mode可以是以下情况的组合:
标志 |
含义 |
S_IRUSR |
用户可以读 |
S_IWUSR |
用户可以写 |
S_IXUSR |
用户可以执行 |
S_IRWXU |
用户可以读、写、执行 |
S_IRGRP |
组可以读 |
S_IWGRP |
组可以写 |
S_IXGRP |
组可以执行 |
S_IRWXG |
组可以读写执行 |
S_IROTH |
其他人可以读 |
S_IWOTH |
其他人可以写 |
S_IXOTH |
其他人可以执行 |
S_IRWXO |
其他人可以读、写、执行 |
S_ISUID |
设置用户执行ID |
S_ISGID |
设置组的执行ID |
除了可以通过上述宏进行“或”逻辑产生标志以外,我们也可以自己用数字来表示,Linux总共用5个数字来表示文件的各种权限:第一位表示设置用户ID;第二位表示设置组ID;第三位表示用户自己的权限位;第四位表示组的权限;最后一位表示其他人的权限。每个数字可以取1(执行权限)、2(写权限)、4(读权限)、0(无)或者是这些值的和。例如,要创建一个用户可读、可写、可执行,但是组没有权限,其他人可以读、可以执行的文件,并设置用户ID位。那么,我们应该使用的模式是1(设置用户ID)、0(不设置组ID)、7(1+2+4,读、写、执行)、0(没有权限)、5(1+4,读、执行)即10705:
open("test", O_CREAT, 10705);
上述语句等价于:
open("test", O_CREAT, S_IRWXU | S_IROTH | S_IXOTH | S_ISUID );
如果文件打开成功,open函数会返回一个文件描述符,以后对该文件的所有操作就可以通过对这个文件描述符进行操作来实现。
读写
在文件打开以后,我们才可对文件进行读写了,Linux中提供文件读写的系统调用是read、write函数:
int read(int fd, const void *buf, size_t length);
int write(int fd, const void *buf, size_t length);
其中参数buf为指向缓冲区的指针,length为缓冲区的大小(以字节为单位)。函数read()实现从文件描述符fd所指定的文件中读取length个字节到buf所指向的缓冲区中,返回值为实际读取的字节数。函数write实现将把length个字节从buf指向的缓冲区中写到文件描述符fd所指向的文件中,返回值为实际写入的字节数。
以O_CREAT为标志的open实际上实现了文件创建的功能,因此,下面的函数等同creat()函数:
int open(pathname, O_CREAT | O_WRONLY | O_TRUNC, mode);
定位
对于随机文件,我们可以随机的指定位置读写,使用如下函数进行定位:
int lseek(int fd, offset_t offset, int whence);
lseek()将文件读写指针相对whence移动offset个字节。操作成功时,返回文件指针相对于文件头的位置。参数whence可使用下述值:
SEEK_SET:相对文件开头
SEEK_CUR:相对文件读写指针的当前位置
SEEK_END:相对文件末尾
offset可取负值,例如下述调用可将文件指针相对当前位置向前移动5个字节:
lseek(fd, -5, SEEK_CUR);
由于lseek函数的返回值为文件指针相对于文件头的位置,因此下列调用的返回值就是文件的长度:
lseek(fd, 0, SEEK_END);
关闭
当我们操作完成以后,我们要关闭文件了,只要调用close就可以了,其中fd是我们要关闭的文件描述符:
int close(int fd);
例程:编写一个程序,在当前目录下创建用户可读写文件“hello.txt”,在其中写入“Hello, software weekly”,关闭该文件。再次打开该文件,读取其中的内容并输出在屏幕上。
#include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <stdio.h> #define LENGTH 100 main() { int fd, len; char str[LENGTH]; fd = open("hello.txt", O_CREAT | O_RDWR, S_IRUSR | S_IWUSR); /* 创建并打开文件 */ if (fd) { write(fd, "Hello, Software Weekly", strlen("Hello, software weekly")); /* 写入Hello, software weekly字符串 */ close(fd); } fd = open("hello.txt", O_RDWR); len = read(fd, str, LENGTH); /* 读取文件内容 */ str[len] = '\0'; printf("%s\n", str); close(fd); }
编译并运行,执行结果如下图:
<!--[if gte vml 1]><v:shape id="_x0000_i1026" type="#_x0000_t75" alt="" style="width:266.25pt;height:34.5pt" mce_style="width:266.25pt;height:34.5pt" /><![endif]-->
3.C语言库函数
C库函数的文件操作实际上是独立于具体的操作系统平台的,不管是在DOS、Windows、Linux还是在VxWorks中都是这些函数:
创建和打开
FILE *fopen(const char *path, const char *mode);
fopen()实现打开指定文件filename,其中的mode为打开模式,C语言中支持的打开模式如下表:
标志 |
含义 |
r, rb |
以只读方式打开 |
w, wb |
以只写方式打开。如果文件不存在,则创建该文件,否则文件被截断 |
a, ab |
以追加方式打开。如果文件不存在,则创建该文件 |
r+, r+b, rb+ |
以读写方式打开 |
w+, w+b, wh+ |
以读写方式打开。如果文件不存在时,创建新文件,否则文件被截断 |
a+, a+b, ab+ |
以读和追加方式打开。如果文件不存在,创建新文件 |
其中b用于区分二进制文件和文本文件,这一点在DOS、Windows系统中是有区分的,但Linux不区分二进制文件和文本文件。
读写
C库函数支持以字符、字符串等为单位,支持按照某中格式进行文件的读写,这一组函数为:
int fgetc(FILE *stream); int fputc(int c, FILE *stream); char *fgets(char *s, int n, FILE *stream); int fputs(const char *s, FILE *stream); int fprintf(FILE *stream, const char *format, ...); int fscanf (FILE *stream, const char *format, ...); size_t fread(void *ptr, size_t size, size_t n, FILE *stream); size_t fwrite (const void *ptr, size_t size, size_t n, FILE *stream);
fread()实现从流stream中读取加n个字段,每个字段为size字节,并将读取的字段放入ptr所指的字符数组中,返回实际已读取的字段数。在读取的字段数小于num时,可能是在函数调用时出现错误,也可能是读到文件的结尾。所以要通过调用feof()和ferror()来判断。
write()实现从缓冲区ptr所指的数组中把n个字段写到流stream中,每个字段长为size个字节,返回实际写入的字段数。
另外,C库函数还提供了读写过程中的定位能力,这些函数包括
int fgetpos(FILE *stream, fpos_t *pos);
int fsetpos(FILE *stream, const fpos_t *pos);
int fseek(FILE *stream, long offset, int whence);
等。
关闭
利用C库函数关闭文件依然是很简单的操作:
int fclose (FILE *stream);
例程:将第2节中的例程用C库函数来实现。
#include <stdio.h> #define LENGTH 100 main() { FILE *fd; char str[LENGTH]; fd = fopen("hello.txt", "w+"); /* 创建并打开文件 */ if (fd) { fputs("Hello, Software Weekly", fd); /* 写入Hello, software weekly字符串 */ fclose(fd); } fd = fopen("hello.txt", "r"); fgets(str, LENGTH, fd); /* 读取文件内容 */ printf("%s\n", str); fclose(fd); }
4.小结
Linux提供的虚拟文件系统为多种文件系统提供了统一的接口,Linux的文件编程有两种途径:基于Linux系统调用;基于C库函数。这两种编程所涉及到文件操作有新建、打开、读写和关闭,对随机文件还可以定位。本章对这两种编程方法都给出了具体的实例。
发表评论
-
多机器执行ssh脚本
2012-08-30 18:12 2179#!/bin/bash Usage() { ... -
Berkeley DB 使用经验总结
2012-08-27 14:41 3024作者:陈磊 NoSQL是现在互联网Web2.0时代备受 ... -
嵌入式数据库系统Berkeley DB
2012-08-27 14:37 1474前言 UNIX/LINUX平台下的数据库种类非常多 ... -
shell中双引号的误用
2011-05-12 15:02 1128for i in "$LIST" ... -
shell for循环
2011-04-06 15:36 907for i in "1 2 3";do e ... -
shell技巧 除法
2011-03-07 11:34 19128shell计算中使用除法,基本默认上都是整除。 比如: ... -
.bash_profile 文件修改之后不执行
2011-02-16 11:21 1874重新登录 不可能不好用的 除非你是从一个用户su oralc ... -
SecureCRT中文显示乱码的解决方法
2011-02-12 11:38 1294最近开始用SecureCRT登陆linux系统,由于是新手,很 ... -
让putty显示中文
2011-02-11 14:43 1375对于经常在windows下远程ssh到linux的用户而言,p ... -
Linux文件类型全解析
2011-01-04 15:13 1358Linux文件类型全解析 ... -
Linux进程状态解析之T、Z、X
2011-01-04 15:09 1752摘要: Linux系统中进程有很多种 ... -
Linux进程状态解析之R、S、D
2011-01-04 14:54 4833摘要: Linu ... -
shell获取参数
2010-12-31 15:29 4131#!/bin/bash Usage() { ... -
Shell实现cgi接口示例
2010-12-30 14:59 1950ls -l /var/www/cgi-bin/ -rwxrw ... -
shell数组
2010-12-29 16:48 1250shell数组 Bash中还可以使用数 ... -
shell 自动化处理
2010-12-29 15:52 994#!/bin/bash sudo yum instal ... -
Linux用户添加sudoer
2010-12-29 11:37 24878使用sudo可以在以非root用户登录时临时获得root权限, ... -
lsof:一个功能强大的命令
2010-12-24 16:30 1319lsof:一个功能强大的命令 lsof命令的原始功能 ... -
linux 的库操作命令 ar和nm
2010-12-22 20:31 1364当我们的程序中有经 ... -
LINUX查看硬件配置 命令
2010-12-21 18:55 1016常用命令整理如下: 查看主板的序列号: dmidec ...
相关推荐
《LinuxC编程实战》系统地介绍了在Linux平台下用C语言进行程序开发的过程,集趣味性、实战性 于一体的160多段代码实例,帮助读者快速掌握在Linux平台下进行C语言程序开发的方法和技巧,并通 过一个原创的BT软件...
第二篇 Linux系统编程 第6章 文件操作 第7章 进程控制 第8章 线程控制 第9章 信号及信号处理 第10章 进程间通信 第三篇 Linux网络和图形界面编程 第11章 网络编程 第12章 GTK+...
Linux下的C编程实战.pdf Linux下的C编程实战.pdf Linux下的C编程实战.pdf Linux下的C编程实战.pdf Linux下的C编程实战.pdf Linux下的C编程实战.pdf Linux下的C编程实战.pdf Linux下的C编程实战.pdf Linux下的C编程...
linux+C编程实战linux+C编程实战linux+C编程实战linux+C编程实战
《Linux C编程实战》系统地介绍了在Linux平台下用C语言进行程序开发的过程,集趣味性、实战性于一体的160多段代码实例,帮助读者快速掌握在Linux平台下进行C语言程序开发的方法和技巧,并通过一个原创的BT软件下载...
《Linux C语言编程实战》 里所有的源代码。
linuxC编程实战关于linux下C语言的编程,好书啊
Linux C编程实战,Linux C学习,董永清 著,人民邮电出版社
Linux.C编程实战.pdf
Linux+C编程实战源码 Linux+C编程实战源码Linux+C编程实战源码Linux+C编程实战源码Linux+C编程实战源码Linux+C编程实战源码
本资源为Linux+C编程实战书的附带光盘,含书中的全部源码
Linux C编程实战 源代码 学习Linux平台C编程的优秀的实例代码。
linux c编程实战,完整版。介绍详细,适合学linux c的新手
Linux C 编程实战 高清电子版,需要的小伙伴可以下载哦
linux+C编程实战.pdf linux+C编程实战 文件较大, 这里提供下载地址。 如果地址失效,请邮件联系我,邮件标题注明: linux+C编程实战csdn链接失效, 我将提供新链接,否则勿扰
董永清所著书籍Linux c编程实战附带光盘资料,内附书中的部分代码。