文件操作函数
Open()函数:
int open(const char *pathname, int flags);
int open(const char *pathname, int flags, mode_t mode);
fd = open(filename,O_RDWR); /*打开文件为可读写方式*/
flags:
#define O_RDONLY 00000000 只读
#define O_WRONLY 00000001 只写
#define O_RDWR 00000002 读写
#define O_CREAT 00000100 文件不存在就创建
#define O_EXCL 00000200 查看文件是否存在
#define O_TRUNC 00001000 将文件长度截断为0
#define O_APPEND 00002000 每次对文件操作都追加到尾端
mode:
用户权限
#define S_IRWXU 00700
#define S_IRUSR 00400
#define S_IWUSR 00200
#define S_IXUSR 00100
组用户权限
#define S_IRWXG 00070
#define S_IRGRP 00040
#define S_IWGRP 00020
#define S_IXGRP 00010
其他用户权限
#define S_IRWXO 00007
#define S_IROTH 00004
#define S_IWOTH 00002
#define S_IXOTH 00001
close()函数:
close()函数关闭一个打开的文件,之前打开文件所占用的资源。
#include <unistd.h>
int close(int fd);
read()函数:
用read()函数从打开文件中读数据,用户可以对读入的数据进行操作。
使用这个函数需要将头文件unistd.h加入。
read()函数的原型定义格式如下。
ssize_t read(int fd, void *buf, size_t count);
fd = open(filename,O_RDONLY); /*打开文件,如果文件不存在,则报错*/
write()函数:
write()函数向打开的文件中写入数据,将用户的数据保存到文件中。
write()的函数原型如下。
#include <unistd.h>
ssize_t write(int fd, const void *buf, size_t count);
函数操作成功会返回写入的字节数,当出错的时候返回–1。出错的原因有多种,像磁盘已满,或者文件大小超出系统的设置,
例如ext2下的文件大小限制为2Gbytes等。
size = write(fd, buf,strlen(buf)); /*将数据写入到文件test.txt中*/
lseek()函数:
在调用read()和write()函数时,每次操作成功后,文件当前的操作位置进行了移动。其中隐含了一个概念,即文件的偏移量。
文件的偏移量指的是当前文件操作位置相对于文件开始位置的偏移。
lseek()函数可以设置文件偏移量的位置,lseek()的函数原型如下:
#include <sys/types.h>
#include <unistd.h>
off_t lseek(int fildes, off_t offset, int whence);
offset = lseek(1, 0, SEEK_CUR); /*将标准输入文件描述符的文件偏移量设为当前值*/
13 if(-1 == offset){ /*设置失败,标准输入不能进行seek操作*/
...
}
whence:
#define SEEK_SET 0 /* seek relative to beginning of file */
#define SEEK_CUR 1 /* seek relative to current file position */
#define SEEK_END 2 /* seek relative to end of file */
#define SEEK_MAX
文件状态函数stat()函数:
有的时候对文件操作的目的不是读写文件,而是要获得文件的状态。例如,获得目标文件的大小、权限、时间等信息。
在程序设计的时候经常要用到文件的一些特性值,例如,文件的所有者、文件的修改时间、文件的大小等。
stat()函数、fstat()函数和lstat()函数可以获得文件的状态,其函数原型如下:
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
int stat(const char *path, struct stat *buf);
int fstat(int filedes, struct stat *buf);
int lstat(const char *path, struct stat *buf);
if( -1 == stat("test.txt", &st)){ /*获得文件的状态,将状态值放入st中*/
struct stat {
unsigned short st_dev;
unsigned short __pad1;
unsigned long st_ino;
unsigned short st_mode;
unsigned short st_nlink;
unsigned short st_uid;
unsigned short st_gid;
unsigned short st_rdev;
unsigned short __pad2;
unsigned long st_size;
unsigned long st_blksize;
unsigned long st_blocks;
unsigned long st_atime;
unsigned long st_atime_nsec;
unsigned long st_mtime;
unsigned long st_mtime_nsec;
unsigned long st_ctime;
unsigned long st_ctime_nsec;
unsigned long __unused4;
unsigned long __unused5;
};
函数实例:
/*使用stat获得文件的状态*/
#include <sys/types.h>
#include <sys/stat.h>
#include <stdio.h>
#include <unistd.h>
int main(void)
{
struct stat st;
if( -1 == stat("test.txt", &st)){ /*获得文件的状态,将状态值放入st中*/
printf("获得文件状态失败\n");
return -1;
}
printf("包含此文件的设备ID:%d\n",(int)st.st_dev); /*文件的ID号*/
printf("此文件的节点:%d\n",(int)st.st_ino); /*文件的节点*/
printf("此文件的保护模式:%d\n",(int)st.st_mode); /*文件的模式*/
printf("此文件的硬链接数:%d\n",(int)st.st_nlink); /*文件的硬链接数*/
printf("此文件的所有者ID:%d\n",(int)st.st_uid); /*文件的所有者ID*/
printf("此文件的所有者的组ID:%d\n",(int)st.st_gid); /*文件的组ID*/
printf("设备ID(如果此文件为特殊设备):%d\n",(int)st.st_rdev); /*文件的设备ID*/
printf("此文件的大小:%d\n",(int)st.st_size); /*文件的大小*/
printf("此文件的所在文件系统块大小:%d\n",(int)st.st_blksize); /*文件的系统块大小*/
printf("此文件的占用块数量:%d\n",(int)st.st_blocks); /*文件的块大小*/
printf("此文件的最后访问时间:%d\n",(int)st.st_atime); /*文件的最后访问时间*/
printf("此文件的最后修改时间:%d\n",(int)st.st_mtime); /*文件的最后修改时间*/
printf("此文件的最后状态改变时间:%d\n",(int)st.st_ctime);/*文件的最后状态改变时间*/
return 0;
}
mmap()函数:
mmap()函数将文件映射到内存中的某一段,内存比磁盘快些。映射到的内存并不占用空间,仅仅占用一段地址空间。
mmap()函数的原型如下。
#include <sys/mman.h>
void *mmap(void *start, size_t length, int prot, int flags,
int fd, off_t offset);
port:
#define PROT_READ 0x1 /* page can be read */
#define PROT_WRITE 0x2 /* page can be written */
#define PROT_EXEC 0x4 /* page can be executed */
#define PROT_SEM 0x8 /* page may be used for atomic ops */
#define PROT_NONE 0x0 /* page can not be accessed */
#define PROT_GROWSDOWN 0x01000000 /* mprotect flag: extend change to start of growsdown vma */
#define PROT_GROWSUP 0x02000000 /* mprotect flag: extend change to end of growsup vma */
flags:
#define MAP_SHARED 0x01 /* Share changes */
#define MAP_PRIVATE 0x02 /* Changes are private */
#define MAP_TYPE 0x0f /* Mask for type of mapping */
#define MAP_FIXED 0x10 /* Interpret addr exactly */
#define MAP_ANONYMOUS 0x20 /* don't use a file */
#define MAP_GROWSDOWN 0x0100 /* stack-like segment */
#define MAP_DENYWRITE 0x0800 /* ETXTBSY */
#define MAP_EXECUTABLE 0x1000 /* mark it as an executable */
#define MAP_LOCKED 0x2000 /* pages are locked */
#define MAP_NORESERVE 0x4000 /* don't check for reservations */
#define MAP_POPULATE 0x8000 /* populate (prefault) pagetables */
#define MAP_NONBLOCK 0x10000 /* do not block on IO */
#define MAP_UNINITIALIZE 0x4000000 /* For anonymous mmap, memory could
be uninitialized. */
munmap()函数:
与mmap()函数对应的函数是munmap()函数,它的作用是取消mmap()函数的映射关系。
其函数原型如下:
#include <sys/mman.h>
int munmap(void *start, size_t length);
ptr = (char*)mmap(NULL, FILELENGTH, PROT_READ |PROT_WRITE, MAP_SHARED, fd, 0);
munmap(ptr, FILELENGTH); /*取消文件映射关系*/
实例:
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/mman.h>/*mmap*/
#include <string.h>/*memset warning*/
#include <stdio.h>
#define FILELENGTH 80
int main(void)
{
int fd = -1;
char buf[]="quick brown fox jumps over the lazy dog"; /*将要写入文件的字符串*/
char *ptr = NULL;
/*打开文件mmap.txt,并将文件长度缩小为0,
如果文件不存在则创建它,权限为可读写执行*/
fd = open("mmap.txt", O_RDWR/*可读写*/|O_CREAT/*不存在,创建*/|O_TRUNC/*缩小为0*/, S_IRWXU);
if( -1 == fd){ /*打开文件失败,退出*/
return -1;
}
/*下面的代码将文件的长度扩大为80*/
/*向后偏移文件的偏移量到79*/
lseek(fd, FILELENGTH-1, SEEK_SET);
write(fd, "a", 1); /*随意写入一个字符,此时文件的 长度为80*/
/*将文件mmap.txt中的数据段从开头到1M的数据映射到内存中,对文件的操作立刻显示在文
件上,可读写*/
ptr = (char*)mmap(NULL, FILELENGTH, PROT_READ|PROT_WRITE,MAP_SHARED, fd, 0);
if( (char*)-1 == ptr){ /*如果映射失败,则退出*/
printf("mmap failure\n");
close(fd);
return -1;
}
memcpy(ptr+16, buf, strlen(buf)); /*将buf中的字符串复制到映射区 域中,起始地址为ptr偏移16*/
munmap(ptr, FILELENGTH); /*取消文件映射关系*/
close(fd); /*关闭文件*/
return 0;
}
fcntl()函数:
fcntl()函数向打开的文件fd发送命令,更改其属性。
函数原型如下:
#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);
flags = fcntl(0, F_GETFL, 0); /*获得标准输入的状态的状态*/
flags = fcntl(fd, F_SETFL, &flags); /*将状态写入*/
F_GETOWN获得接收信号SIGIO和SIGURG信号的进程ID或进程组ID。
uid = fcntl(fd, F_GETOWN); /*获得接收信号的进程ID*/
F_SETOWN用于设置接收信号SIGIO和SIGURG信号的进程ID或进程组ID。
uid = fcntl(fd, F_SETOWN,10000); /*设置接收信号的进程ID*/
cmd:
#define F_DUPFD 0 /* dup */复制文件描述符
#define F_GETFD 1 /* get close_on_exec */获得文件描述符
#define F_SETFD 2 /* set/clear close_on_exec */设置文件描述符
#define F_GETFL 3 /* get file->f_flags */获得文件状态值
#define F_SETFL 4 /* set file->f_flags */设置文件状态值
#define F_GETLK 5 获得记录锁
#define F_SETLK 6 设置记录锁
#define F_SETLKW 7
#define F_SETOWN 8 /* for sockets. */
#define F_GETOWN 9 /* for sockets. */
#define F_SETSIG 10 /* for sockets. */
#define F_GETSIG 11 /* for sockets. */
#define FD_CLOEXEC 1 /* actually anything with low bit set goes */
#define F_RDLCK 0
#define F_WRLCK 1
#define F_UNLCK 2
实例:
#include<unistd.h>
#include<fcntl.h>
#include<stdio.h>
int main()
{
int flags = -1;
int accmode = -1;
flags = fcntl(0,F_GETFL,0); /*获得标准输入下的状态*/
if(flags<0)
{
printf("use fcntl fail\n");
return -1;
}
accmode = flags&O_ACCMODE; /*获得访问模式*/
if(accmode==O_RDONLY) /*只读*/
{
printf("STDIN READ ONLY\n");
}
else if(accmode==O_WRONLY) /*只写*/
{
printf("STDIN WRITE ONLY\n");
}
else if(accmode==O_RDWR) /*可读写*/
{
printf("STDIN WRITE READ\n");
}
else /*其他模式*/
{
printf("STDIN UNKNOWN MODE\n");
}
if(flags&O_APPEND) /*附加模式*/
printf("STDIN APPEND\n");
if(flags&O_NONBLOCK) /*非阻塞模式*/
printf("STDIN NONBLOCK\n");
return 0;
}
ioctl()函数
ioctl是input output control的简写,表示输入输出控制,ioctl()函数通过对文件描述符的发送命令来控制设备。
ioctl()函数的原型如下。
#include <sys/ioctl.h>
int ioctl(int d, int request, ...);
if (!ioctl(fd,CDROMEJECT,NULL)){/*驱动程序操作成功*/