第三講 檔案管理檔案模式 常規檔案管道(IPC):Linux系統的處理序間通訊的一種機制,FIFO的檔案,有兩種管道:無名管道和具名管道目錄檔案:以檔案的方式進行操作裝置檔案:大多數物理裝置都用檔案來表示,有兩種裝置檔案:塊裝置和字元裝置符號串連:包含到定義檔案的特殊路徑,類似於windows下的捷徑通訊端:處理序間通訊的機制基本的檔案操作 inode(資訊節點) 核心資訊節點(in-core inode):不同類型的檔案的核心資訊節點都是相同的 磁碟資訊節點(on-disk inode):不同檔案系統類型具有不同的磁碟資訊節點 當一個進程開啟磁碟中的檔案,磁碟資訊節點就轉換成核心資訊節點,如果核心資訊節點被修改,則該節點的資訊將被傳回磁碟資訊節點1. 檔案模式檔案模式定義低12位:表示存取權限,用於管理對檔案的訪問和檔案許可權的修飾符寫成6個8進位數例: 041777 100755檔案存取權限 3個存取控制位 chmod 例-rwx------ 1 root root 218 5月 22 20:49 forkd.c [root@localhost ch02]# chmod 777 forkd.c -rwxrwxrwx 1 root root 218 5月 22 20:49 forkd.c 檔案許可權修飾符與類型 是一個位元遮罩,表示setuid、setgid、stiky 檔案類型 sys/stat.h 進程的umask #include<sys/stat.h> int umask(int newmask); 例 [root@localhost tmp]# touch ex1[root@localhost tmp]# ls –l-rw-rw-r-- 1 root root 0 5月 22 21:56 ex1 [root@localhost tmp]#umask 077[root@localhost tmp]# touch ex2-rw-rw-r-- 1 root root 0 5月 22 21:56 ex1-rw------- 1 root root 0 5月 22 21:58 ex2 2.基本的檔案操作 檔案描述符 stdin、stdout、stderr #include <unistd.h> STDIN_FILENO, STDOUT_FILENO,STDERR_FILENO 操作檔案的參數 關閉檔案 int close(int fd); 開啟檔案: #include <fcntl.h> int open(char *pathname, int flags, mode_t mode); int create(char *pathname, mode_t mode); flags: O_RDONLY, O_RDWR, O_WRONLY, O_CREATE, O_EXCL ,O_NOCTTY, O_TRUNC, O_APPEND, O_NONBLOCK, O_SYNC open(pathname, O_CREAT|O_WRONLY|O_TRUNC, mode) 檔案的讀寫與位置指標的移動 #include <unistd.h> size_t read(int fd, void *buf, size_t length); size_t write(int fd, const void *buf, size_t length); 例// 寫檔案#include <errno.h>#include <fcntl.h>#include <stdio.h>#include <stdlib.h>#include <unistd.h>int main(void){ int fd; if ((fd=open("rwexm",O_TRUNC|O_CREAT|O_WRONLY,0644))<0) { perror("open"); _exit(1); } if (write(fd,"hello world/n",13) != 13) { perror("write"); _exit(1); } close(fd); return 0;} // 讀檔案#include <errno.h>#include <fcntl.h>#include <stdio.h>#include <stdlib.h>#include <unistd.h> int main(void){ int size = 13; char buffer[size]; int fd; if ((fd = open("rwexm",O_RDONLY,0644)) < 0) { perror("open"); _exit(1); } if (read(fd,buffer,sizeof(buffer)) < 0){ perror("read"); _exit(1); } printf(buffer); close(fd); return 0;} int lseek(int fd, off_t offset, int whence); SEEK_SET, SEEK_CUR, SEEK_END 局部讀寫 例 類比實現cat系統命令 #include <stdio.h>#include <stdlib.h>#include <unistd.h>#include <errno.h>#include <fcntl.h> int main(int argc, char **argv){ int fd, len; char buf[1024]; if ( argc < 2) { printf("at least 1 para/n"); return 0; } if ((fd = open(argv[1],O_RDONLY,0666)) < 0) { perror("open"); _exit(1); } while ((len = read(fd,buf,sizeof(buf))) > 0) { if (write(1,buf,len) != len) { perror("write"); close(fd); _exit(1); } } if (len < 0) { perror("read"); close(fd); _exit(1); } close(fd); return 0;} // 縮短檔案 int truncate(const char *pathname, size_t length); int ftruncate(int fd, size_t length); // 同步:執行該函數後立刻將資料寫回到硬體 int fsync(int fd) int fdatasync(int fd)查詢和修改inode資訊 查詢inode資訊 #include <sys/stat.h> int stat(const char *pathname, struct stat *statbuf); int lstat(const char *pathname, struct stat *statbuf); int fstat(int fd, struct stat *statbuf); struct stat成員 dev_t st_dev unsigned long st_block ino_t st_ino time_t st_atime mode_t st_mode time_t st_mtime nlink_t st_nlink time_t st_ctime uid_t st_uid unsigned long st_blksize gid_t st_gid dev_t st_rdev off_t st_size 例#include <errno.h>#include <stdio.h>#include <string.h>#include <sys/stat.h>#include <sys/sysmacros.h>#include <time.h>#include <unistd.h> #define TIME_STRING_BUF 50 char *timeString(time_t t, char*buf){ struct tm *local; local = localtime(&t); strftime(buf, TIME_STRING_BUF,"%c",local); return buf; } int statFile(const char *file){ struct stat statbuf; char timeBuf[TIME_STRING_BUF]; if (lstat(file,&statbuf)) { fprintf(stderr,"could not lstat %s:%s/n",file,strerror(errno)); return 1; } printf("filename: %s/n",file); printf("on device: major %d/minor %d inod number: %ld/n",major(statbuf.st_dev),minor(statbuf.st_dev),statbuf.st_ino); printf("size :%x-10ld type:%07o permissions %05o/n",statbuf.st_size,statbuf.st_mode&S_IFMT,statbuf.st_mode&~(S_IFMT)); printf("owner:%d group:%d number of links:%d/n",statbuf.st_uid,statbuf.st_gid,statbuf.st_nlink); printf("chnge time:%s/n",timeString(statbuf.st_ctime,timeBuf)); printf("modified time:%s/n",timeString(statbuf.st_mtime,timeBuf)); printf("access time:%s/n",timeString(statbuf.st_atime,timeBuf)); return 0;} int main(int argc, const char **argv){ int i; int rc = 0; for (i = 1; i < argc; i++) { rc |= statFile(argv[i]); if ((argc -i) > 1) { printf("/n"); } } return rc;}#include <unistd.h>int access(const char *pathname, int mode);正確返回0,出錯返回EACCESS #include <sys/stat.h>int chmod(const char *pathname, mode_t mode);int fchmod(int fd, mode _t mode);返回EPERM #include <unistd.h>int chown(const char *pathname, uid_t owner, gid_t group);int fchown(int fd, uid_t owner, gid_t group); #include <utime.h>int utime(const char *pathname, strcut utimbuf *buf);#include<sys/time.h>int utimes(const char *pathname, struct timeval *tvp);struct utimbuf{ time_t actime; time_t modtime;}struct timeval{ long tv_sec; long tv_usec;} ext3擴充屬性EXT3_APPEND_FLEXT3_IMMUTABLE_FLEXT3_NODUMP_FLEXT3_SYNC_FL#include <sys/ioctl.h>#include <linux/ext3_fs.h>int ioctl(int fd, int request, void *arg);EXT3_IOC_GETFLAGS, EXT3_IOC_SETFLAGS例: 操作目錄項#include <fcntl.h>#include <unistd.h>int mknod(const char *pathname, mode_t mode, dev_t dev);S_IFIFO, S_IFBLK, S_IFCHR<sys/sysmacros.h> makedev(major, minor), major(), minor()/*建立永久連結*/#include <unistd.h>int link(const char *origpath, const char *newpath); /*建立符號串連*/#include <unistd.h>int sysmlink(const char *origpath, const char *newpath);int readlink(const char *pathname, char *buf, size_t bufsize);chown(), lstat(), readlink(), rename(), unlink() /*刪除檔案*/#include <unistd.h>int unlink(char *pathname);int rename(const char *oldpath, const char *newpath);操作檔案描述符和建立無名管道#include <fcntl.h>Int fcntl(int fd, int command, long arg);fcntl(fd, F_SETFL, fcntl(fd, F_GETFL, 0) | O_RDONLY);fcntl(fd, F_SETFL, fcntl(fd, F_GETFL, 0) | O_APPEND);fcntl(fd, F_SETFL, fcntl(fd, F_GETFL, 0) & ~O_APPEND); /*複製檔案描述符*/int dup(int oldfd);int dup2(int oldfd, int newfd);int pipe(int fds[2]); 例#include <errno.h>#include <stdio.h>#include <stdlib.h>#include <string.h>#include <sys/stat.h>#include <sys/sysmacros.h>#include <unistd.h>#include <fcntl.h> void usage(void){ fprintf(stderr, "usage:mkmmodexa <path> [b|c|n|p] <major> <minor> /n"); _exit(1);} int main(int argc, char **argv){ int major = 0, minor = 0; const char *path; int mode = 0666; char *end; int args; if (argc < 3 ) { usage(); } path = argv[1]; if (!strcmp(argv[2],"b")) { mode |= S_IFBLK; args = 5; } else if (!strcmp(argv[2],"c") || !strcmp(argv[2],"m")) { mode |= S_IFCHR; args = 5; } else if (!strcmp(argv[2],"p")) { mode |= S_IFIFO; args = 3; } else { sprintf(stderr, "unknown node type %s/n",argv[2]); return 1; } if (args == 5) { major = strtol(argv[3],&end,0); if (*end) { fprintf(stderr,"bad major number %s/n",argv[3]); return 1; } minor = strtol(argv[4],&end,0); if (*end) { fprintf(stderr, "bad major number %s/n",argv[4]); return 1; } } if (mknod(path, mode, makedev(major, minor))) { fprintf(stderr, "mkmod failed:%s/n",strerror(errno)); return 1; } return 0;}