linux編程學習筆記(八) 檔案 定位 lseek pread pwrite

來源:互聯網
上載者:User
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;}elsereturn 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 若是位置不合法 ,比如負數,返回-15  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); //91119t = 88888;pwrite(fd,&t,4,(off_t)&a);//往所在a的地方寫資料printf("a=%d\n",a); //沒有改變 因為系統沒有給寫的許可權}

相關文章

Beyond APAC's No.1 Cloud

19.6% IaaS Market Share in Asia Pacific - Gartner IT Service report, 2018

Learn more >

Apsara Conference 2019

The Rise of Data Intelligence, September 25th - 27th, Hangzhou, China

Learn more >

Alibaba Cloud Free Trial

Learn and experience the power of Alibaba Cloud with a free trial worth $300-1200 USD

Learn more >

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。