ch03: 文件管理

 
第三講 文件管理
文件模式
       常規文件
管道(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_FL
EXT3_IMMUTABLE_FL
EXT3_NODUMP_FL
EXT3_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;
}
 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章