Linux系統編程——系統調用之 I/O 操作(文件操作)

Linux 技術 cpp軟件架構獅 2018-11-30

文件描述符

在 Linux 的世界裡,一切設備皆文件。我們可以系統調用中 I/O 的函數(I:input,輸入;O:output,輸出),對文件進行相應的操作( open()、close()、write() 、read() 等)。

打開現存文件或新建文件時,系統(內核)會返回一個文件描述符,文件描述符用來指定已打開的文件。這個文件描述符相當於這個已打開文件的標號,文件描述符是非負整數,是文件的標識,操作這個文件描述符相當於操作這個描述符所指定的文件。

程序運行起來後(每個進程)都有一張文件描述符的表,標準輸入、標準輸出、標準錯誤輸出設備文件被打開,對應的文件描述符 0、1、2 記錄在表中。程序運行起來後這三個文件描述符是默認打開的。

#define STDIN_FILENO 0 //標準輸入的文件描述符
#define STDOUT_FILENO 1 //標準輸出的文件描述符
#define STDERR_FILENO 2 //標準錯誤的文件描述符

在程序運行起來後打開其他文件時,系統會返回文件描述符表中最小可用的文件描述符,並將此文件描述符記錄在表中。Linux 中一個進程最多隻能打開 NR_OPEN_DEFAULT (1024)個文件,故當文件不再使用時應及時調用 close()函數關閉文件。

常用 I/0 函數

需要的頭文件:

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
int open(const char *pathname, int flags, mode_t mode);

功能

打開文件,如果文件不存在則創建。

參數

pathname: 文件的路徑及文件名。

flags: 打開文件的行為標誌,如,以只讀方式(O_RDONLY,第一個為字母不是數據)打開,以讀寫或新建新文件的方式(O_RDWR|O_CREAT)打開。

Linux系統編程——系統調用之 I/O 操作(文件操作)

mode: 這個參數,只有在文件不存在時有效,指新建文件時指定文件的權限(文件權限詳情,請點此鏈接)。

Linux系統編程——系統調用之 I/O 操作(文件操作)

返回值:

成功:成功返回打開的文件描述符

失敗:-1

int close(int fd);

功能:關閉已打開的文件

參數:fd: 文件描述符,open()的返回值

返回值:成功:0,失敗:-1

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

功能:把指定數目的數據寫到文件(fd)

參數:fd: 文件描述符,addr: 數據首地址,count: 寫入數據的長度(字節),一般情況下,數據有多少,就往文件裡寫多少,不能多也不能少

返回值:

成功:實際寫入數據的字節個數

失敗:-1

ssize_t read(int fd, void *addr, size_t count);

功能

把指定數目的數據讀到內存(緩衝區)

參數

fd: 文件描述符

addr: 內存首地址

count: 讀取的字節個數

返回值

成功:實際讀取到的字節個數

失敗:-1

實戰示例

接下來,我們使用以上 4 個系統調用 I/O 函數寫一個程序,能實現像系統命令 cp 的功能:

Linux系統編程——系統調用之 I/O 操作(文件操作)

使用 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系統編程——系統調用之 I/O 操作(文件操作)

相關推薦

推薦中...