青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

隨筆-145  評論-173  文章-70  trackbacks-0
原帖見: http://fanqiang.chinaunix.net/a4/b2/20010508/113315.html

前言: 
    我們在這一節將要討論linux下文件操作的各個函數. 
1.文件的創建和讀寫 
2.文件的各個屬性 
3.目錄文件的操作 
4.管道文件 

--------------------------------------------------------------------------------
1。文件的創建和讀寫 
    我假設你已經知道了標準級的文件操作的各個函數(fopen,fread,fwrite等等).當然如果你不清楚的話也不要著急.我們討論的系統級的文件操作實際上是為標準級文件操作服務的. 
當我們需要打開一個文件進行讀寫操作的時候,我們可以使用系統調用函數open.使用完成以后我們調用另外一個close函數進行關閉操作. 
#include 
#include 
#include 
#include 

int open(const char *pathname,int flags);
int open(const char *pathname,int flags,mode_t mode);

int close(int fd);

open函數有兩個形式.其中pathname是我們要打開的文件名(包含路徑名稱,缺省是認為在當前路徑下面).flags可以去下面的一個值或者是幾個值的組合. 
O_RDONLY:以只讀的方式打開文件. 
O_WRONLY:以只寫的方式打開文件. 
O_RDWR:以讀寫的方式打開文件. 
O_APPEND:以追加的方式打開文件. 
O_CREAT:創建一個文件. 
O_EXEC:如果使用了O_CREAT而且文件已經存在,就會發生一個錯誤. 
O_NOBLOCK:以非阻塞的方式打開一個文件. 
O_TRUNC:如果文件已經存在,則刪除文件的內容. 
前面三個標志只能使用任意的一個.如果使用了O_CREATE標志,那么我們要使用open的第二種形式.還要指定mode標志,用來表示文件的訪問權限.mode可以是以下情況的組合. 
-----------------------------------------------------------------
S_IRUSR 用戶可以讀 S_IWUSR 用戶可以寫
S_IXUSR 用戶可以執行 S_IRWXU 用戶可以讀寫執行
-----------------------------------------------------------------
S_IRGRP 組可以讀 S_IWGRP 組可以寫
S_IXGRP 組可以執行 S_IRWXG 組可以讀寫執行
-----------------------------------------------------------------
S_IROTH         其他人可以讀    S_IWOTH         其他人可以寫
S_IXOTH         其他人可以執行  S_IRWXO         其他人可以讀寫執行
-----------------------------------------------------------------
S_ISUID 設置用戶執行ID  S_ISGID 設置組的執行ID
-----------------------------------------------------------------
我們也可以用數字來代表各個位的標志.Linux總共用5個數字來表示文件的各種權限.
00000.第一位表示設置用戶ID.第二位表示設置組ID,第三位表示用戶自己的權限位,第四位表示組的權限,最后一位表示其他人的權限.
每個數字可以取1(執行權限),2(寫權限),4(讀權限),0(什么也沒有)或者是這幾個值的和.
比如我們要創建一個用戶讀寫執行,組沒有權限,其他人讀執行的文件.設置用戶ID位那么我們可以使用的模式是--1(設置用戶ID)0(組沒有設置)7(1+2+4)0(沒有權限,使用缺省)5(1+4)即10705:
open("temp",O_CREAT,10705);
如果我們打開文件成功,open會返回一個文件描述符.我們以后對文件的所有操作就可以對這個文件描述符進行操作了.
當我們操作完成以后,我們要關閉文件了,只要調用close就可以了,其中fd是我們要關閉的文件描述符.
文件打開了以后,我們就要對文件進行讀寫了.我們可以調用函數read和write進行文件的讀寫.
#include 

ssize_t  read(int fd, void *buffer,size_t count);
ssize_t write(int fd, const void *buffer,size_t count);

fd是我們要進行讀寫操作的文件描述符,buffer是我們要寫入文件內容或讀出文件內容的內存地址.count是我們要讀寫的字節數.
對于普通的文件read從指定的文件(fd)中讀取count字節到buffer緩沖區中(記住我們必須提供一個足夠大的緩沖區),同時返回count.
如果read讀到了文件的結尾或者被一個信號所中斷,返回值會小于count.如果是由信號中斷引起返回,而且沒有返回數據,read會返回-1,且設置errno為EINTR.當程序讀到了文件結尾的時候,read會返回0.
write從buffer中寫count字節到文件fd中,成功時返回實際所寫的字節數.
下面我們學習一個實例,這個實例用來拷貝文件.

#include 
#include 
#include 
#include 
#include 
#include 
#include 

#define BUFFER_SIZE 1024

int main(int argc,char **argv)
{
 
 int from_fd,to_fd;
 int bytes_read,bytes_write;
 char buffer[BUFFER_SIZE];
 char *ptr;

 if(argc!=3)
  {
fprintf(stderr,"Usage:%s fromfile tofile\n\a",argv[0]);
exit(1);
  }

/* 打開源文件 */

 if((from_fd=open(argv[1],O_RDONLY))==-1)
  {
fprintf(stderr,"Open %s Error:%s\n",argv[1],strerror(errno));
exit(1);
 }

/* 創建目的文件 */

 if((to_fd=open(argv[2],O_WRONLY|O_CREAT,S_IRUSR|S_IWUSR))==-1)
  {
        fprintf(stderr,"Open %s Error:%s\n",argv[2],strerror(errno));
        exit(1);
 }
 
/* 以下代碼是一個經典的拷貝文件的代碼 */

 while(bytes_read=read(from_fd,buffer,BUFFER_SIZE))
 {
/* 一個致命的錯誤發生了 */
   if((bytes_read==-1)&&(errno!=EINTR)) break;
   else if(bytes_read>0)
       {
  ptr=buffer;
  while(bytes_write=write(to_fd,ptr,bytes_read))
   {
/* 一個致命錯誤發生了 */
     if((bytes_write==-1)&&(errno!=EINTR))break;
/* 寫完了所有讀的字節 */
     else if(bytes_write==bytes_read) break;
/* 只寫了一部分,繼續寫 */
     else if(bytes_write>0)
           {
      ptr+=bytes_write;
   bytes_read-=bytes_write;
          }
          }
/* 寫的時候發生的致命錯誤 */
         if(bytes_write==-1)break;

       }
  }
 close(from_fd);
 close(to_fd);
 exit(0);
}

2。文件的各個屬性
    文件具有各種各樣的屬性,除了我們上面所知道的文件權限以外,文件還有創建時間,大小等等屬性.
有時侯我們要判斷文件是否可以進行某種操作(讀,寫等等).這個時候我們可以使用access函數.
#include 

int access(const char *pathname,int mode);

pathname:是文件名稱,mode是我們要判斷的屬性.可以取以下值或者是他們的組合.
R_OK文件可以讀,W_OK文件可以寫,X_OK文件可以執行,F_OK文件存在.當我們測試成功時,函數返回0,否則如果有一個條件不符時,返回-1.
如果我們要獲得文件的其他屬性,我們可以使用函數stat或者fstat.
#include 
#include 

int stat(const char *file_name,struct stat *buf);
int fstat(int filedes,struct stat *buf);

struct stat {
dev_t st_dev; /* 設備   */
ino_t st_ino; /* 節點   */
mode_t st_mode; /* 模式   */
nlink_t st_nlink; /* 硬連接 */
uid_t st_uid; /* 用戶ID */
gid_t st_gid; /* 組ID   */
dev_t st_rdev; /* 設備類型 */
off_t st_off; /* 文件字節數 */
unsigned long  st_blksize; /* 塊大小 */
unsigned long st_blocks; /* 塊數   */
time_t st_atime; /* 最后一次訪問時間 */
time_t st_mtime; /* 最后一次修改時間 */
time_t st_ctime; /* 最后一次改變時間(指屬性) */
};

stat用來判斷沒有打開的文件,而fstat用來判斷打開的文件.我們使用最多的屬性是st_mode.通過著屬性我們可以判斷給定的文件是一個普通文件還是一個目錄,連接等等.可以使用下面幾個宏來判斷.
S_ISLNK(st_mode):是否是一個連接.S_ISREG是否是一個常規文件.S_ISDIR是否是一個目錄S_ISCHR是否是一個字符設備.S_ISBLK是否是一個塊設備S_ISFIFO是否 是一個FIFO文件.S_ISSOCK是否是一個SOCKET文件. 我們會在下面說明如何使用這幾個宏的.
3。目錄文件的操作
    在我們編寫程序的時候,有時候會要得到我們當前的工作路徑。C庫函數提供了getcwd來解決這個問題。
#include 

char *getcwd(char *buffer,size_t size);

我們提供一個size大小的buffer,getcwd會把我們當前的路徑考到buffer中.如果buffer太小,函數會返回-1和一個錯誤號.
Linux提供了大量的目錄操作函數,我們學習幾個比較簡單和常用的函數.
#include 
#include 
#include 
#include 
#include 

int mkdir(const char *path,mode_t mode);
DIR *opendir(const char *path);
struct dirent *readdir(DIR *dir);
void rewinddir(DIR *dir);
off_t telldir(DIR *dir);
void  seekdir(DIR *dir,off_t off);
int closedir(DIR *dir);

struct dirent {
long  d_ino;
off_t  d_off;
unsigned short d_reclen;
char  d_name[NAME_MAX+1]; /* 文件名稱 */

mkdir很容易就是我們創建一個目錄,opendir打開一個目錄為以后讀做準備.readdir讀一個打開的目錄.rewinddir是用來重讀目錄的和我們學的rewind函數一樣.closedir是關閉一個目錄.telldir和seekdir類似與ftee和fseek函數.
下面我們開發一個小程序,這個程序有一個參數.如果這個參數是一個文件名,我們輸出這個文件的大小和最后修改的時間,如果是一個目錄我們輸出這個目錄下所有文件的大小和修改時間.

#include 
#include 
#include 
#include 
#include 
#include 
#include 

static int get_file_size_time(const char *filename)
{
 struct stat statbuf;
 
 if(stat(filename,&statbuf)==-1)
  {
printf("Get stat on %s Error:%s\n",
filename,strerror(errno));
return(-1);
  }
  
 if(S_ISDIR(statbuf.st_mode))return(1);
 if(S_ISREG(statbuf.st_mode))
printf("%s size:%ld bytes\tmodified at %s",
filename,statbuf.st_size,ctime(&statbuf.st_mtime)); 

 return(0);
}

int main(int argc,char **argv)
{
 DIR *dirp;
 struct dirent *direntp; 
 int stats;

 if(argc!=2)
  {
printf("Usage:%s filename\n\a",argv[0]);
exit(1);
  }

 if(((stats=get_file_size_time(argv[1]))==0)||(stats==-1))exit(1);
 
 if((dirp=opendir(argv[1]))==NULL)
 {
printf("Open Directory %s Error:%s\n",
argv[1],strerror(errno));
exit(1);
 }

 while((direntp=readdir(dirp))!=NULL)
   if(get_file_size_time(direntp-
 closedir(dirp);
 exit(1);
}

4。管道文件
    Linux提供了許多的過濾和重定向程序,比如more cat
等等.還提供了< > | <<等等重定向操作符.在這些過濾和重 定向程序當中,都用到了管道這種特殊的文件.系統調用pipe可以創建一個管道.
#include

int pipe(int fildes[2]);

pipe調用可以創建一個管道(通信緩沖區).當調用成功時,我們可以訪問文件描述符fildes[0],fildes[1].其中fildes[0]是用來讀的文件描述符,而fildes[1]是用來寫的文件描述符.
在實際使用中我們是通過創建一個子進程,然后一個進程寫,一個進程讀來使用的.
關于進程通信的詳細情況請查看進程通信

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#define  BUFFER 255

int main(int argc,char **argv)
{
  char buffer[BUFFER+1];
  int fd[2];

  if(argc!=2)
  {
fprintf(stderr,"Usage:%s string\n\a",argv[0]);
exit(1);
  }

  if(pipe(fd)!=0)
  {
fprintf(stderr,"Pipe Error:%s\n\a",strerror(errno));
exit(1);
  }
  if(fork()==0)
   {
close(fd[0]);
printf("Child[%d] Write to pipe\n\a",getpid());
snprintf(buffer,BUFFER,"%s",argv[1]);
write(fd[1],buffer,strlen(buffer));
printf("Child[%d] Quit\n\a",getpid());
exit(0);
   }
 else
  {
close(fd[1]);
printf("Parent[%d] Read from pipe\n\a",getpid());
memset(buffer,'\0',BUFFER+1);
read(fd[0],buffer,BUFFER);
printf("Parent[%d] Read:%s\n",getpid(),buffer);
   exit(1);
  }
}

為了實現重定向操作,我們需要調用另外一個函數dup2.
#include 

int dup2(int oldfd,int newfd);

dup2將用oldfd文件描述符來代替newfd文件描述符,同時關閉newfd文件描述符.也就是說,
所有向newfd操作都轉到oldfd上面.下面我們學習一個例子,這個例子將標準輸出重定向到一個文件.

#include 
#include 
#include 
#include 
#include 
#include 
#include 

#define  BUFFER_SIZE 1024

int main(int argc,char **argv)
{
 int fd;
 char buffer[BUFFER_SIZE];

 if(argc!=2)
  {
fprintf(stderr,"Usage:%s outfilename\n\a",argv[0]);
exit(1);
  }

 if((fd=open(argv[1],O_WRONLY|O_CREAT|O_TRUNC,S_IRUSR|S_IWUSR))==-1)
  {
  fprintf(stderr,"Open %s Error:%s\n\a",argv[1],strerror(errno));
exit(1);
  }

 if(dup2(fd,STDOUT_FILENO)==-1)
  {
fprintf(stderr,"Redirect Standard Out Error:%s\n\a",strerror(errno));
exit(1);
  }

 fprintf(stderr,"Now,please input string");
 fprintf(stderr,"(To quit use CTRL+D)\n");  
 while(1)
  {
    fgets(buffer,BUFFER_SIZE,stdin); 
    if(feof(stdin))break;
    write(STDOUT_FILENO,buffer,strlen(buffer));
 }
 exit(0);
}

好了,文件一章我們就暫時先討論到這里,學習好了文件的操作我們其實已經可以寫出一些比較有用的程序了.我們可以編寫一個實現例如dir,mkdir,cp,mv等等常用的文件操作命令了.
想不想自己寫幾個試一試呢?

附:常見的頭文件是:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <fcntl.h>
#include <signal.h>
#include <errno.h>
posted on 2010-03-02 10:11 deercoder 閱讀(430) 評論(0)  編輯 收藏 引用 所屬分類: Unix/Linux
青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            正在播放欧美一区| 麻豆精品传媒视频| 欧美国产在线观看| 欧美伊人久久久久久久久影院| 欧美另类久久久品| 亚洲精品国产欧美| 欧美承认网站| 亚洲欧美精品suv| 美国十次了思思久久精品导航| 国产综合视频| 欧美影视一区| 欧美一区三区三区高中清蜜桃| 国产精品视频一二| 久久久www成人免费精品| 亚洲一二三区精品| 国产精品系列在线播放| 99视频精品在线| 亚洲精品久久久久久久久久久久久| 久久综合狠狠综合久久激情| 国产精品视频不卡| 亚洲成在人线av| 久久亚洲精品中文字幕冲田杏梨| 久久精品国产99精品国产亚洲性色| 国产视频精品va久久久久久| 亚洲欧美一区二区原创| 亚洲综合欧美日韩| 精品不卡一区| 亚洲国产免费| 国产精品护士白丝一区av| 午夜精品久久久久久久久 | 久久国产成人| 黑人一区二区三区四区五区| 99re66热这里只有精品3直播| 日韩视频一区二区| 欧美日韩在线播放三区| 亚洲一区二区在线免费观看| 亚洲天堂激情| 在线观看的日韩av| 亚洲精品系列| 国产一区二区看久久| 久久精品亚洲国产奇米99| 久久人人爽人人| 一区二区电影免费观看| 午夜精品久久久久久久99水蜜桃 | 欧美中文字幕久久| 久久久久久久久久久成人| 亚洲黄一区二区三区| 亚洲视频视频在线| 亚洲电影免费观看高清| 久久综合一区二区三区| 欧美精品在线观看91| 久久精品91久久久久久再现| 亚洲欧美激情诱惑| 99re8这里有精品热视频免费| 亚洲在线中文字幕| 在线成人激情视频| 亚洲自拍啪啪| 一本不卡影院| 麻豆国产精品一区二区三区 | 国产婷婷色一区二区三区在线| 欧美高清在线精品一区| 国产亚洲精品7777| 一区二区三区视频在线 | 久久亚洲综合网| 欧美亚洲免费电影| 欧美国产日本韩| 亚洲一区免费看| 欧美成人xxx| 麻豆成人在线观看| 国产美女一区二区| 一区二区福利| 亚洲一二三四区| 欧美人与性禽动交情品| 蜜臀av性久久久久蜜臀aⅴ| 国产精品美女久久| 亚洲视频播放| 亚洲图片在线观看| 欧美日韩一区二区精品| 老司机久久99久久精品播放免费 | 亚洲综合日韩在线| 亚洲一区二区精品| 欧美日韩成人激情| 亚洲精品视频一区| 亚洲精选中文字幕| 美女诱惑黄网站一区| 久久精品成人一区二区三区蜜臀| 日韩网站在线观看| 国模大胆一区二区三区| 亚洲一品av免费观看| 正在播放亚洲| 欧美三级午夜理伦三级中视频| 日韩视频不卡中文| 老司机一区二区三区| 在线免费不卡视频| 国产精品私房写真福利视频 | 欧美淫片网站| avtt综合网| 欧美成人免费在线视频| 亚洲制服丝袜在线| 亚洲精品视频免费观看| 国产一区视频在线观看免费| 欧美女人交a| 久久精品亚洲精品| 亚洲综合日本| 9久草视频在线视频精品| 欧美/亚洲一区| 久久久www免费人成黑人精品| 亚洲午夜激情网站| 亚洲精品一区二| 精品99视频| 国产午夜精品久久久久久久| 欧美日韩在线看| 久久久久久久高潮| 欧美在线一二三四区| 亚洲欧美日韩国产综合| 一区二区三区波多野结衣在线观看| 欧美激情久久久久久| 免费观看亚洲视频大全| 久久永久免费| 老色鬼久久亚洲一区二区| 久久精品一区二区| 久久精品国产亚洲精品| 欧美一区二区三区的| 日韩午夜在线| 在线免费观看视频一区| 精品成人久久| 亚洲第一区在线| 亚洲电影视频在线| 亚洲人成7777| 夜夜嗨av色一区二区不卡| 日韩亚洲精品电影| 亚洲视频狠狠| 亚洲欧美综合网| 欧美在线短视频| 老牛国产精品一区的观看方式| 久久躁狠狠躁夜夜爽| 久久精品夜色噜噜亚洲a∨| 亚洲一区亚洲二区| 先锋资源久久| 久久一区二区三区四区五区| 免费成人在线视频网站| 欧美激情第二页| 亚洲美女在线观看| 亚洲性感美女99在线| 午夜精品福利一区二区蜜股av| 久久成人精品无人区| 久久综合九色综合欧美狠狠| 欧美国产精品人人做人人爱| 欧美午夜精品久久久久久孕妇| 国产精品国产a| 国产一区激情| 亚洲国产精品va在线看黑人动漫 | 在线亚洲免费| 欧美一区二区三区免费观看视频 | 久久精品国产精品| 免费在线成人| 亚洲人午夜精品免费| 亚洲深夜av| 亚洲精品国偷自产在线99热| 亚洲一二三区精品| 欧美成人在线免费观看| 亚洲资源av| 欧美日韩国产首页| 亚洲国产一区二区a毛片| 欧美一区二区视频在线观看| 亚洲日本电影| 久久欧美肥婆一二区| 国产美女精品视频免费观看| 一卡二卡3卡四卡高清精品视频| 久久综合影视| 欧美一级大片在线免费观看| 欧美图区在线视频| 亚洲美女一区| 亚洲电影第1页| 久久精品一区四区| 国产亚洲一区二区三区| 亚洲综合色丁香婷婷六月图片| 亚洲七七久久综合桃花剧情介绍| 久久久99精品免费观看不卡| 国产亚洲欧美日韩日本| 香蕉乱码成人久久天堂爱免费 | 久久夜色精品一区| 亚洲免费人成在线视频观看| 欧美日韩一区二区三区四区在线观看| 亚洲精品黄网在线观看| 欧美刺激性大交免费视频| 久久九九精品| 精品1区2区3区4区| 免费成人在线观看视频| 久久久精品国产一区二区三区| 国产一区自拍视频| 久久免费高清视频| 欧美一区二区三区在线免费观看| 国产伦精品一区二区三区在线观看| 亚洲免费网站| 午夜精品一区二区三区四区| 国产日韩亚洲| 美女尤物久久精品| 免费亚洲婷婷| 9l视频自拍蝌蚪9l视频成人|