1 fstat 擷取檔案狀態
int fstat(int fd, struct stat *buf);
struct stat {
dev_t st_dev; /* ID of device containing file */
ino_t st_ino; /* inode number */
mode_t st_mode; /* protection */
nlink_t st_nlink; /* number of hard links */
uid_t st_uid; /* user ID of owner */
gid_t st_gid; /* group ID of owner */
dev_t st_rdev; /* device ID (if special file) */
off_t st_size; /* total size, in bytes */
blksize_t st_blksize; /* blocksize for file system I/O */
blkcnt_t st_blocks; /* number of 512B blocks allocated */
time_t st_atime; /* time of last access */
time_t st_mtime; /* time of last modification */
time_t st_ctime; /* time of last status change */
};
2 ftruncate改變檔案大小
int ftruncate(int fd, off_t length);
如果length比原來的大,則在檔案後面添加'\0'
如果length比原來的小,則在截斷檔案
#include <sys/types.h>#include <sys/stat.h> #include <fcntl.h>#include <unistd.h>#include <stdio.h>int main(){int fd;struct stat st;fd = open("stu.dat",O_RDWR);fstat(fd,&st); //錯誤:儲存大小未知 沒加標頭檔printf("%d,%o\n",(int)st.st_size,st.st_mode); //72 100644ftruncate(fd,st.st_size+1000); // 需要寫入權限才能改變大小fstat(fd,&st);printf("%d\n",(int)st.st_size);close(fd);}
zhao@ubuntu:~/unix/4$ ./fstat
72,100644
1072
3 檔案對應
mmap /munmap
之前介紹過(http://blog.csdn.net/a8887396/article/details/8996213) ,寫的是記憶體映射,拷過來
void *mmap(
void *start, //指定映射的虛擬位址 如為0 系統指定開始位置
size_t length, //映射的空間大小 : pagesize倍數
int prot,//映射許可權 PROT_NONE PROT_READ PROT_WRITE PROT_EXEC
int flags,//映射方式
int fd,//檔案描述符
offset_t off); //檔案中的位移位置(必須是page_size的倍數)
int munmap(void *addr, size_t length);
映射方式:
記憶體映射:匿名映射
檔案對應:映射到檔案 ,只有當檔案對應時,最後兩個參數才有效
MAP_ANONYMOUS 寫了就是記憶體映射 不寫就是檔案對應
MAP_PRIVATE MAP_SHARED 2選1
umap(void *start,size_t lenth)
案例:
1使用記憶體方式寫入資料
#include <stdio.h>#include <stdlib.h>#include <sys/types.h>#include <sys/stat.h>#include <fcntl.h>#include <unistd.h>#include <string.h>#include <sys/mman.h>struct stu{char name[20];int age;float score;};int main(){//開啟檔案//增加檔案大小//映射到虛擬位址//把資料寫入虛擬位址//卸載虛擬位址//關閉檔案int fd = open("newstu.dat",O_RDWR|O_CREAT,0666);if(fd < 0){perror("open error");return 1;}struct stat st;fstat(fd,&st);int size = st.st_size ; //檔案大小int count = size/sizeof(struct stu);//記錄條數//因為要增加資料 所以要先增加檔案大小(很重要)ftruncate(fd,size+sizeof(struct stu)); //增加檔案大小//將檔案對應到記憶體的虛擬位址,得到檔案在虛擬記憶體中映射的首地址 struct stu*s= mmap(0, size+sizeof(struct stu), PROT_WRITE|PROT_READ, MAP_SHARED, fd,0);printf("請輸入學生姓名");scanf("%s",s[count].name);printf("請輸入學生年齡");scanf("%d",&s[count].age);printf("請輸入學產生績");scanf("%f",&s[count].score);munmap(s,size+sizeof(struct stu));close(fd);}
2使用記憶體方式讀取資料
#include <stdio.h>#include <stdlib.h>#include <sys/types.h>#include <sys/stat.h>#include <fcntl.h>#include <unistd.h>#include <string.h>#include <sys/mman.h>struct stu{char name[20];int age;float score;};int main(){int fd = open("newstu.dat",O_RDWR);if(fd < 0){perror("open fail");return 1;}struct stat st;fstat(fd,&st);int size = st.st_size;int count = size/sizeof(struct stu);struct stu*s = mmap(0,size,PROT_READ | PROT_WRITE,MAP_SHARED,fd,0);if(s < 0){perror("mmap error");return 1;}int i =0;for(; i<count ;i++){printf("name:%s,age:%d,score:%.2f\n",s[i].name,s[i].age,s[i].score);}munmap(s,size);close(fd);}