文件 I/O
一、主要函数: open(),creat(),read(),write(),close(),fcntl(),lseek()
二、open,creat,read,write,close 等函数的操作与文件描述符fd 有关。
1 、对于open 函数而言,仅当创建新文件时才使用第三个参数,由open 返回的文件描述符一定是最小的未用描述符数值,常用的常量有O_CREAT,O_TRUNC,O_NONBLOCK, 常用open 函数代替 creat
2 、lseek 成功执行,返回新的文件偏移量( 相对于文件头0 所偏移的量); 比较lseek 的返回值时,不要测试它是否小于0 ,而要测试它是否等于 -1.
3 、read ,经常用返回0 来判断是否已达结尾。关于read :若在到达文件尾端之前还有30 个字节,而要求读100 个字节,则read 返回30 ,下一次再调用read 时,它将返回0( 文件尾端) 。
4 、 lseek
write(fd, "hello", 5);
lseek(fd, offset, SEEK_END);
write(fd, "world", 5);
三、fcntl 可以改变已打开文件的性质
F_SETFL,F_GETFL,O_ASYNC,O_NONBLOCK
ret = fcntl(fd, F_GETFL);
fcntl(fd, F_SETFL, ret | O_NONBLOCK);
实例:
#include <fcntl.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
int main(void)
{
int fd;
int n;
char buf[20];
int ret;
fd=open("file1.txt",O_RDWR|O_TRUNC|O_CREAT,0777);// 创建文件时别忘了加mode 参数
if(fd==-1)
{
perror("open");
exit(1);
}
// ret=fcntl(0,F_GETFL );// 取得文件信息
// fcntl(0,F_SETFL,ret|O_NONBLOCK);//fcntl 可以改变已打开文件的性质
while((n=read(0,buf,20))>0)//read 阻塞,程序不会退出
if(write(fd,buf,n)!=n)// 读多少个就写多少个
perror("write");
exit(0);
}
四、例程
1 、
/*open.c*/
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
int main(int argc, char **argv)
{
if (argc != 2) {
fprintf(stderr, "Usags.../n");
return -1;
}
close(0);
int fd = open(argv[1], O_RDWR);
if (fd == -1) {
perror("read");
exit(1);
} else {
printf("fd=%d/n", fd);
}
close(fd);
return 0;
}
2 、
/*read.c*/
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
int main(void)
{
char buf[10];
int ret;
while(1)
{
// bzero(buf,0);
ret=read(0,buf,9);
if(ret==-1)
{
perror("read");
exit(1);
}
buf[ret]='/0';// 这一句不能省
printf("%s/n",buf);// 如果省去了上一句,那么打印到终端时会出现意想不到的符号
}
exit(0);
}
3 、
/*creat.c*/
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
int main(int argc, char **argv)
{
if (argc != 2) {
fprintf(stderr, "Usags.../n");
return -1;
}
int fd = open(argv[1], O_WRONLY | O_CREAT | O_TRUNC | O_EXCL,
0766);
if (fd == -1) {
perror("create");
exit(1);
} else {
printf("fd=%d/n", fd);
}
close(fd);
return 0;
}
/* 用open 代替creat*/
4 、
/*read_write.c*/
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
int main(void)
{
int fd, ret;
char buf[100];
fd = open("/etc/passwd", O_RDONLY);
if (fd == -1) {
perror("open");
exit(1);
}
while (1) {
ret = read(fd, buf, 100);
if (ret == 0)
break;
write(1, buf, ret);// 读多少就写多少
}
close(fd);
exit(0);
}
5 、
/*lseek.c*/
#include <stdio.h>
#include <fcntl.h>
#include <stdlib.h>
int main(void)
{
int fd=open("/etc/passwd-",O_RDONLY);
if(fd==-1)
{
perror("open");
exit(1);
}
int ret;
ret=lseek(fd,5,SEEK_SET);
printf("ret1=%d/n",ret);
ret=lseek(fd,10,SEEK_CUR);//lseek 返回相对于文头0 所偏移的量
printf("ret2=%d/n",ret);
exit(0);
}
6 、
/*hole.c*/
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
int main(int argc, char **argv)
{
if (argc != 2) {
exit(1);
}
int fd;
off_t offset = 0x1 << 20;
fd = open(argv[1], O_RDWR | O_CREAT | O_TRUNC, 0666);
if (fd == -1) {
perror("open");
exit(1);
}
write(fd, "hello", 5);
lseek(fd, offset, SEEK_END);
write(fd, "world", 5);
close(fd);
exit(0);
}
7 、
/*fcntl.c*/
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
int main(void)
{
char buf[32];
int ret;
ret = fcntl(0, F_GETFL);//
// fcntl(0, F_SETFL, ret | O_NONBLOCK);
while (1) {
printf("I am waitting/n");
ret = read(0, buf, 31);
printf("read success!/n");
buf[ret] = '/0';
printf("read: %s", buf);
}
exit(0);
}
8、
/*write会覆盖:本例程,xxx覆盖hai*/
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
int main(void)
{
int fd=open("testwritecover",O_RDWR | O_CREAT ,0644);
write(fd,"luoyuhai8702",12);
lseek(fd,-7,SEEK_CUR);
write(fd,"xxx",3);
close(fd);
return 0;
}