1IO的共享和效率
read与write其中数据缓冲的大小建设设置为:getpagesize (一页的大小)
或者4092
2 定位与读取数据(随机读取)
read和write时自动移动读取位置
lseek改变读取位置
pread/pwrite在指定位置读写
2.1lseek函数说明
off_t lseek(int fd, //文件描述符
off_t offset,//偏移
int whence);//定位参数 开始SEEK_SET, 当前位置SEEK_CUR , 结束SEEK_END
返回值:当前读取在文件中的绝地位置
3 例子
- #include <sys/types.h>
- #include <sys/stat.h>
- #include <fcntl.h>
- #include <unistd.h>
- #include <stdlib.h>
- #include <stdio.h>
-
- struct stu
- {
- int no;
- char name[16];
- float score;
- };
-
- int openfile(const char* filename)
- {
- int fd = open(filename,O_WRONLY|O_CREAT|O_EXCL,0666);
- if(fd < 0)
- {
- perror("open error!");
- }
-
- return fd;
- }
-
- void input(struct stu *record)
- {
- printf("请输入学生ID:");
- scanf("%d",&(record->no));
- printf("请输入学生姓名:");
- scanf("%s",record->name);
- printf("请输入学生成绩:");
- scanf("%f",&(record->score));
- }
-
- void save(int fd,struct stu* record)
- {
- write(fd,record,sizeof(struct stu));
- }
-
- int iscontinue()
- {
- char c;
- printf("是否继续输入:y/n\n");
- scanf("%c",&c);
- scanf("%c",&c);
- if(c == 'y')
- {
- return 1;
- }
- else
- return 0;
- }
-
- int main()
- {
-
- int fd =openfile("stu.dat");
- if(fd < 0)
- {
- return 1;
- }
- struct stu record;
- while(1)
- {
- input(&record);
- save(fd,&record);
-
- if(! iscontinue() )
- {
- break;
- }
- }
- close(fd);
- }
-
-
-
-
-
-
-
-
-
- #include <stdio.h>
- #include <unistd.h>
- #include <fcntl.h>
- #include <sys/types.h>
- int main()
- {
- int fd = open("stu.dat",O_RDONLY);
- if(fd < 0)
- {
- perror("open");
- return 1;
- }
- int i = 0;
- char buf[4092];
- lseek(fd,i*24+4,SEEK_SET);
- while(read(fd,buf,16))
- {
- printf("%s ",buf);
- i++;
- lseek(fd,i*24+4,SEEK_SET);
- }
- printf("\n");
- close(fd);
- }
4 lseek的定位位置超出文件大小时会发生什么?
1 lseek只要位置合法(绝对位置>=0),返回值都是当前位置
位置可以超出文件范围,只要不写入文件大小不会变化
- #include <stdio.h>
- #include <unistd.h>
- #include <fcntl.h>
- #include <sys/types.h>
- int main()
- {
- int fd = open("dat",O_RDWR|O_CREAT,0666);
- if(fd < 0)
- {
- perror("open");
- return 1;
- }
- int r = lseek(fd,2000,SEEK_SET);
- printf("%d\n",r);
- close(fd);
- }
zhao@ubuntu:~/unix/4$ ./lseek2
2000
zhao@ubuntu:~/unix/4$ ls -l dat
-rw-r--r-- 1 zhao zhao 0 2013-06-01 04:59 dat
lseek超出文件范围,写入后文件大小会多出很多
- #include <stdio.h>
- #include <unistd.h>
- #include <fcntl.h>
- #include <sys/types.h>
- int main()
- {
- int fd = open("dat",O_RDWR|O_CREAT,0666);
- if(fd < 0)
- {
- perror("open");
- return 1;
- }
- int r = lseek(fd,2000,SEEK_SET);
- printf("%d\n",r);
- write(fd,"hello"5);
- close(fd);
- }
zhao@ubuntu:~/unix/4$ ls -l dat
-rw-r--r-- 1 zhao zhao 2005 2013-06-01 05:02 d
2 若是位置不合法 ,比如负数,返回-1
5 pread pwrite
函数描述
#include <unistd.h>
ssize_t pread(int fd, void *buf, size_t count, off_t offset); //注意offset是绝对位置
ssize_t pwrite(int fd, const void *buf, size_t count, off_t offset);
pread=lseek+read
pwrite=lseek+write
返回值
读写的数据大小,出错返回-1
-
- #include <stdio.h>
- #include <unistd.h>
- #include <fcntl.h>
- #include <sys/types.h>
-
-
- int main()
- {
- int fd = open("stu.dat",O_RDONLY);
- if(fd < 0)
- {
- perror("open");
- return 1;
- }
- int i = 0;
- char buf[4092];
- while(pread(fd,buf,16,i*24+4))
- {
- printf("%s ",buf);
- i++;
- }
- printf("\n");
- close(fd);
- }
pread pwrite会改变读写位置吗?
pread() reads up to count bytes from file descriptor fd at offset off‐
set (from the start of the file) into the buffer starting at buf. The
file offset is not changed.
pwrite() writes up to count bytes from the buffer starting at buf to
the file descriptor fd at offset offset. The file offset is not
changed.
记住 都不改变读写位置 , 这就是它们和lseek+read/write的区别
案例 读取/proc/$(pid)/mem 文件(虚拟内存 )
- #include <stdio.h>
- #include <unistd.h>
- #include <fcntl.h>
- #include <sys/types.h>
- #include <string.h>
-
-
- int a = 91119;
- int main()
- {
-
-
- char filename[20];
- memset(filename,0,20);
- sprintf(filename,"/proc/%d/mem",getpid());
-
-
-
- int fd = open(filename,O_RDWR);
- if(fd < 0)
- {
- perror("open error");
- return 1;
- }
-
-
- int t;
- pread(fd,&t,4,(off_t)&a);
- printf("t:%d\n",t);
-
-
- t = 88888;
- pwrite(fd,&t,4,(off_t)&a);
- printf("a=%d\n",a);
-
- }