歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux基礎 >> Linux教程 >> Linux 下幾個文件操作命令的代碼實現

Linux 下幾個文件操作命令的代碼實現

日期:2017/2/28 16:20:17   编辑:Linux教程

本文章中的示例代碼是在 CentOS 5.4 64 位環境下運行通過的,在其它 unix 系統上沒有測試過。

Linux 操作系統中的命令實際上是編譯好的可執行程序,比如說 ls 這個命令,這個文件位於 /bin 目錄下面,當我們用 file /bin/ls 命令查看的時候會有以下輸出:

 [root@localhost ~]# file /bin/ls 
 /bin/ls: ELF 64-bit LSB executable, 
 AMD x86-64, version 1 (SYSV), for GNU/Linux 2.6.9, 
 dynamically linked (uses shared libs), for GNU/Linux 2.6.9, stripped 

這個命令通過調用 stat 系統調用和 /usr/share/file/magic.mgc 文件來決定文件的類型。如上的 /bin/ls 是一個 ELF 格式的動態鏈接的 64 位的可執行文件。

系統調用是用戶程序和操作系統內核之間的接口,我們可以使用操作系統提供的系統調用來請求分配資源和服務。我們可以通過 man 2 章節來查找 Linux 提供的系統調用的具體使用方法。有關文件操作的常見系統調用命令有:open、creat、close、read、write、lseek、opendir、readdir、mkdir、stat 等等。

cp 命令的實現

cp 命令的模擬實現

大家也都知道 cp 這個命令主要的作用就是把一個文件從一個位置復制到另一個位置。比如現在 /root 目錄下有一個 test.txt 文件,如果我們用 cp test.txt test2.txt 命令的話,在同一個目錄下面就會生成一個同樣內容的 test2.txt 文件了。

那麼 cp 命令是怎麼實現的呢,我們看如下代碼:


清單 1. cp 命令實現代碼
				
 #include    <stdio.h> 
 #include    <unistd.h> 
 #include    <fcntl.h> 
 #include    <stdlib.h> 

 #define BUFFERSIZE    4096 
 #define COPYMODE     0644 

 void oops(char *, char *); 

 main(int argc, char * argv[]) 
 { 
    int   in_fd, out_fd, n_chars; 
    char  buf[BUFFERSIZE]; 

    if ( argc != 3 ){ 
        fprintf( stderr, "usage: %s source destination\n", *argv); 
        exit(1); 
    } 

    if ( (in_fd=open(argv[1], O_RDONLY)) == -1 ){ 
        oops("Cannot open ", argv[1]); 
    } 
    if ( (out_fd=creat( argv[2], COPYMODE)) == -1 ){ 
        oops( "Cannot creat", argv[2]); 
    } 

    while ( (n_chars = read(in_fd , buf, BUFFERSIZE)) > 0 ){ 
        if ( write( out_fd, buf, n_chars ) != n_chars ){ 
           oops("Write error to ", argv[2]); 
        } 
    } 
    if ( n_chars == -1 ){ 
        oops("Read error from ", argv[1]); 
    } 

    if ( close(in_fd) == -1 || close(out_fd) == -1 ) 
        oops("Error closing files",""); 
 } 

 void oops(char *s1, char *s2) 
 { 
    fprintf(stderr,"Error: %s ", s1); 
    perror(s2); 
    exit(1); 
 } 

該程序的主要實現思想是:打開一個輸入文件,創建一個輸出文件,建立一個 BUFFERSIZE 大小的緩沖區;然後在判斷輸入文件未完的循環中,每次讀入多少就向輸出文件中寫入多少,直到輸入文件結束。

cp 命令實現的說明

讓我來詳細的講述一下這個程序:

  • 開頭四行包含了 4 個頭文件,<stdio.h> 文件包含了 fprintf、perror 的函數原型定義;<unistd.h> 文件包含了 read、write 的函數原型定義;<fcntl.h> 文件包含了 open、creat 的函數原型定義、<stdlib.h> 文件包含了 exit 的函數原型定義。這些函數原型有些是系統調用、有些是庫函數,通常都可以在 /usr/include 目錄中找到這些頭文件。
  • 接下來的 2 行以宏定義的方式定義了 2 個常量。BUFFERSIZE 用來表示緩沖區的大小、COPYMODE 用來定義創建文件的權限。
  • 接下來的一行定義了一個函數原型 oops,該函數的具體定義在最後出現,用來輸出出錯信息到 stderr,也就是標准錯誤輸出的文件流。
  • 接下來主程序開始。首先定義了 2 個文件描述符、一個存放讀出字節數的變量 n_chars、和一個 BUFFERSIZE 大小的字符數組用來作為拷貝文件的緩沖區。
  • 接下來判斷輸入參數的個數是否為 3,也就是程序名 argv[0]、拷貝源文件 argv[1]、目標文件 argv[2]。不為 3 的話就輸出錯誤信息到 stderr,然後退出程序。
  • 接下來的 2 行,用 open 系統調用以 O_RDONLY 只讀模式打開拷貝源文件,如果打開失敗就輸出錯誤信息並退出。如果想了解文件打開模式的詳細內容請使用命令 man 2 open,來查看幫助文檔。
  • 接下來的 2 行,用 creat 系統調用以 COPYMODE 的權限建立一個文件,如果建立失敗函數的返回值為 -1 的話,就輸出錯誤信息並退出。
  • 接下來的循環是拷貝的主要過程。它從輸入文件描述符 in_fd 中,讀入 BUFFERSIZE 字節的數據,存放到 buf 字符數組中。在正常讀入的情況下,read 函數返回實際讀入的字節數,也就是說只要沒有異常情況和文件沒有讀到結尾,那麼 n_chars 中存放的就是實際讀出的字節的數字。然後 write 函數將從 buf 緩沖區中,讀出 n_chars 個字符,寫入 in_out 輸出文件描述符。由於 write 系統調用返回的是實際寫入成功的字節數。所以當讀出 N 個字符,又成功寫入 N 個字符到輸出文件描述符中去的時候,就表示寫成功了,否則就報告寫入錯誤。
  • 最後就是用 close 系統調用關閉打開的輸入和輸出文件描述符。
Copyright © Linux教程網 All Rights Reserved