Linux系統程式設計——IO程式設計
1.Linux檔案操作
“一切皆檔案”是Linux系統的基本思想。Linux 提供的虛擬檔案系統為多種檔案系統和外設驅動提供了統一的介面,基於此類介面,可以實現檔案的新建、開啟(open)、讀(read)、寫(write)、關閉(close),及對隨機檔案的定位(lseek)。
通常,一個程序開啟現有檔案或新建檔案時,系統會返回一個檔案描述符fd(file descriptor),指示特定的檔案,後面的讀寫、關閉檔案都通過此檔案描述符進行操作。無錯誤狀態下的檔案描述符是非負數,開啟檔案前應檢查該標識是否為非負數。
一個程序執行時,都有一張自身的檔案描述符,即是開啟三個檔案:標準輸入、標準輸出和標準出錯處理。程式執行起來後,這三個檔案是預設開啟的。對應的巨集描述為如下。
#define STDIN_FILENO 0 //標準輸入的檔案描述符
#define STDOUT_FILENO 1 //標準輸出的檔案描述符
#define STDERR_FILENO 2 //標準錯誤的檔案描述符
2.常用IO函式
2.1 open函式
函式原型:
int open(const char *pathname, int flags, mode_t mode);
所需標頭檔案:
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
函式功能:
開啟檔案,檔案不存在時則建立一個檔案。
函式引數:
pathname:被開啟檔名,包括檔案路徑;
flags:開啟檔案的行為標識,如只讀、只寫、讀寫等;具體引數選擇標識及含義如下。
注意:
1)前三個取值引數不可使用“|”,但可以與後面幾個取值引數進行“|”操作,進行選擇相應功能;
2)以讀寫方式開啟只能用“O_RDWR”,不能用“O_REONLY|O_WRONLY”。
mode:此引數只有在開啟的檔案不存時才有效,即是指定建立檔案時的使用者許可權。
函式返回值:
成功:開啟檔案描述符。
失敗:-1。
2.2close函式
函式原型:
int close(int fd);
所需標頭檔案:
#include<uniste.h>
函式功能:
關閉已開啟的檔案。
函式引數:
fd:檔案描述符,open函式的返回值。
函式返回值:
成功:0。
失敗:-1。
2.3read函式
函式原型:
ssize_t read(int fd, void *addr, size_t count);
所需標頭檔案:
#include<unistd.h>
函式功能:
讀取指定的資料到記憶體。
函式引數:
fd:檔案描述符。
addr:記憶體首地址,存放讀取返回資料。
count:讀取的位元組數。
函式返回值:
成功:實際讀取位元組數。
失敗:-1。
2.4write函式
函式原型:
ssize_t write(int fd, const void *addr, size_t count);
所需標頭檔案:
#include<unistd.h>
函式功能:
向檔案寫入指定的資料。
函式引數:
fd:檔案描述符。
addr:資料緩衝區首地址。
count:待寫資料位元組數。
函式返回值:
成功:實際寫入的位元組數。
失敗:-1。
2.5lseek函式
函式原型:
off_t lseek(int fd,off_t offset,int whence)
所需標頭檔案:
#include<unistd.h>
#include<sys/types.h>
函式功能:
指定檔案操作地址偏移量。
函式引數:
fd:檔案描述符。
offset:偏移量,每一讀寫操作所需要移動的距離,單位是位元組的數量,可正可負(向前移,向後移)。
whence:當前位置基點,取值及含義如下。
函式返回值:
成功:當前檔案位置。
失敗:-1。
3.程式設計例項
3.1例項1
利用IO函式讀寫檔案。
#include <fcntl.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
int main(void)
{
char *buf="Read and write test!";
char buf_r[strlen(buf)+1];
int fd,size,len;
len = strlen(buf);
buf_r[len] = '/0';
//首先呼叫open 函式,並指定相應的許可權
if ((fd = open("io_test0.txt", O_CREAT | O_TRUNC | O_RDWR,0666 ))<0)
{
perror("open:");
exit(1);
}
else
printf("open and create file:io_test0.txt %d OK\n",fd);
//呼叫write 函式,將buf 中的內容寫入到開啟的檔案中
if ((size = write( fd, buf, len)) < 0)
{
perror("write:");
exit(1);
}
else
printf("write:%s OK\n",buf);
// 呼叫lseek 函式將檔案指標移動到檔案開始8個位元組,並讀出餘下內容
lseek(fd, 8, SEEK_SET );
if ((size = read( fd, buf_r, len-8))<0)
{
perror("read:");
exit(1);
}
else
printf("read form file:%s OK\n",buf_r);
if ( close(fd) < 0 )
{
perror("close:");
exit(1);
}
else
printf("close io_test0.txt OK\n");
return 0;
}
Linux下執行結果:
3.2例項2
利用IO函式實現Linux命令終端的複製(cp)命令。使用 open() 開啟原始檔,使用 read() 從檔案讀資料,使用 write() 向目標檔案寫資料。
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
int main(int argc, char *argv[])
{
if((argc == 3) && (strcmp(argv[1], argv[2]) != 0))
{// 保證有 3 個引數,而且原始檔和目的檔名字不能一樣
int fd_src, fd_dest, ret;
//只讀方式開啟原始檔
fd_src = open(argv[1], O_RDONLY);
if(fd_src < 0)
{
perror("open argv[1]");
return -1;
}
// 新建目的檔案
fd_dest = open(argv[2], O_WRONLY|O_CREAT, 0755);
if(fd_dest < 0)
{
close(fd_src);
perror("open argv[2]");
return -1;
}
do
{
char buf[1024] = {0};
// 從原始檔讀取資料
ret = read(fd_src, buf, sizeof(buf));
// 把資料寫到目的檔案,注意最後一個引數,有多少寫多少
write(fd_dest, buf, ret);
}while(ret > 0);
// 關閉已開啟的檔案
close(fd_src);
close(fd_dest);
}
return 0;
}
Linux下執行結果:
4.參考