linux程式設計學習筆記(八) 檔案 定位 lseek pread pwrite
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);
- }
- /*讀取檔案中的姓名
- 檔案以結構體的形式寫入
- struct stu
- {
- int no;
- char name[16];
- float score;
- };
- */
- #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());
- //mem檔案 虛擬記憶體空間對映到mem上了
- int fd = open(filename,O_RDWR);
- if(fd < 0)
- {
- perror("open error");
- return 1;
- }
- //讀取&a這個位置的地址
- int t;
- pread(fd,&t,4,(off_t)&a);
- printf("t:%d\n",t); //91119
- t = 88888;
- pwrite(fd,&t,4,(off_t)&a);//往所在a的地方寫資料
- printf("a=%d\n",a); //沒有改變 因為系統沒有給寫的許可權
- }
相關文章
- pread,pwrite,read,write區別
- Linux學習/TCP程式設計學習筆記LinuxTCP程式設計筆記
- Linux Shell 程式設計學習筆記Linux程式設計筆記
- linux系統程式設計之檔案與IO(三):利用lseek()建立空洞檔案Linux程式設計
- Qt 程式設計 —— 專案工程檔案(.pro)介紹 【學習筆記】QT程式設計筆記
- Linux程式設計學習筆記 | Linux IO學習[2] – 標準IOLinux程式設計筆記
- Linux 筆記分享八:檔案許可權的設定Linux筆記
- Linux 檔案許可權 學習筆記Linux筆記
- Linux檔案型別(學習筆記六)Linux型別筆記
- 網路程式設計學習筆記程式設計筆記
- 系統程式設計學習筆記程式設計筆記
- JAVA程式設計學習記錄(File類檔案操作)Java程式設計
- LINUX學習(八)Linux檔案連結命令Linux
- Linux 學習筆記--程式Linux筆記
- 學習筆記19:影像定位筆記
- Golang 學習筆記——tun/tap 程式設計Golang筆記程式設計
- 結構化程式設計--學習筆記程式設計筆記
- Javascript高階程式設計 學習筆記JavaScript程式設計筆記
- ROS串列埠程式設計學習筆記ROS串列埠程式設計筆記
- spark學習筆記--進階程式設計Spark筆記程式設計
- 《Windows 程式設計》學習筆記(五) (轉)Windows程式設計筆記
- 《Windows 程式設計》學習筆記(四) (轉)Windows程式設計筆記
- 《Windows 程式設計》學習筆記(三) (轉)Windows程式設計筆記
- Java學習筆記之檔案Java筆記
- 四. 文字程式設計--Windows程式設計課程學習筆記程式設計Windows筆記
- JavaScript學習筆記(八)—— 補JavaScript筆記
- Spss 學習筆記(八)SPSS筆記
- Linux 學習筆記--檔案打包與解壓縮Linux筆記
- 4、Linux入門學習筆記 檔案操作命令Linux筆記
- Linux學習筆記 檔案讀寫小細節Linux筆記
- Linux學習筆記——例說makefile 多個檔案Linux筆記
- linux磁碟和檔案系統的學習筆記Linux筆記
- 設計模式學習筆記設計模式筆記
- 學習筆記-設計模式筆記設計模式
- 好程式設計師web前端培訓學習筆記Vue學習筆記一程式設計師Web前端筆記Vue
- Linux 通過lseek()來實現檔案大小的設定Linux
- Linux 學習筆記--程式管理Linux筆記
- 好程式設計師學習筆記:函式程式設計師筆記函式