1. 程式人生 > >Linux系統程式設計——系統呼叫之 I/O 操作(檔案操作)

Linux系統程式設計——系統呼叫之 I/O 操作(檔案操作)

一、檔案描述符

在 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 //標準錯誤的檔案描述符

上面3個常量定義在/usr/include/unistd.h中。

在程式執行起來後開啟其他檔案時,系統會返回檔案描述符表中最小可用的檔案描述符,並將此檔案描述符記錄在表中。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)開啟。


mode: 這個引數,只有在檔案不存在時有效,指新建檔案時指定檔案的許可權(檔案許可權詳情,請點此連結)。

返回值:

成功:成功返回開啟的檔案描述符
失敗:-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 的功能:


例項程式碼如下:

#include <stdio.h>
#include <unistd.h>
#include <string.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, len;
		
		//只讀方式開啟原始檔
		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};
			// 從原始檔讀取資料
			len = read(fd_src, buf, sizeof(buf));
			
			// 把資料寫到目的檔案,注意最後一個引數,有多少寫多少
			write(fd_dest, buf, len);
		}while(len > 0);
		
		// 關閉已開啟的檔案
		close(fd_src);
		close(fd_dest);
	}
	
	return 0;
}

執行結果:


相關推薦

Linux系統程式設計——系統呼叫 I/O 操作檔案操作

一、檔案描述符 在 Linux 的世界裡,一切裝置皆檔案。我們可以系統呼叫中 I/O 的函式(I:input,輸入;O:output,輸出),對檔案進行相應的操作( open()、close()、write() 、read() 等)。 開啟現存檔案或新建檔案時,系統(核心

Linux系統呼叫I/O操作

一、檔案描述符 在 Linux 的世界裡,一切裝置皆檔案。我們可以系統呼叫中 I/O 的函式(I:input,輸入;O:output,輸出),對檔案進行相應的操作( open()、close()、write() 、read() 等)。 開啟現存檔案或新建檔案時,系統

嵌入式Linux應用程式設計I/O程序

【1】i/o 本質就是輸入輸出函式,也是讀寫函式 【2】系統呼叫和庫函式 系統呼叫: 使用函式控制linux核心,linux核心來操作硬體 庫函式: 庫函式的本質還是系統呼叫,只不過需要在記憶體當中開闢一塊空間(緩衝區),從而減少系統呼叫的次數 【3】io分類

Linux 環境程式設計——淺談標準I/O緩衝區

標準I/O庫提供緩衝的目的是儘可能地減少使用read和write呼叫的次數。它也對每個I/O流自動地進行緩衝管理,從而避免了應用程式需要考慮這一點所帶來的麻煩。不幸的是,標準I/O庫最令人迷惑的也是它的緩衝。   標準I/O提供了三種類型的緩衝: 1、全緩衝: 在填滿標準I

Linux C程式設計——基於流的I/O操作

1、基於字元的I/O 基於字元的I/O通常是用來處理單個字元的。   (1)字元的輸入 以下三個函式用於一次讀入一個字元: #include <stdio.h> Int getc(FILE *fp); Int fgetc(FILE *fp); I

java基礎I/O-------轉換流

一.轉換流的概念: 轉換流即包裝流,可以使位元組流轉換成字元流,也可以字元流轉成位元組流。         二.位元組流轉字元流:                    1.InputStreamReader 是位元組流通向字元流的橋樑:它使用指定的 charset

java基礎I/O------------字元流的檔案讀寫操作

一.流的概念: java的輸入輸出稱為流,流是一組有順序的集合。而流的本質則是資料傳輸 二.流的分類:                  1.根據處理的功能分為位元組流(InputStream,OutPutStrean)和字元流(Writer,Reader)  

系統學習機器學習維度歸約完整篇

這裡,我們討論特徵選擇和特徵提取,前者選取重要的特徵子集,後者由原始輸入形成較少的新特徵,理想情況下,無論是分類還是迴歸,我們不應該將特徵選擇或特徵提取作為一個單獨的程序,分類或者回歸方法應該能夠利用任何必要的特徵,而丟棄不相關的特徵。但是,考慮到演算法儲存量和時間的複雜

I/O模型非同步事件

非同步事件    WSAEventSelect模型是WindowsSockets提供的另外一個有用的非同步I/O模型。該模型允許一個或多個套接字上接收以事件為基礎的網路事件通知。Windows Sockets應用程式在建立套接字後,呼叫WSAEventSlect()函式,將一

I/O模型非同步選擇

非同步選擇 非同步選擇(WSAAsyncSelect)模型是一個有用的非同步 I/O 模型。利用這個模型,應用程式可在一個套接字上,接收以 Windows 訊息為基礎的網路事件通知。具體的做法是在建好一個套接字後,呼叫WSAAsyncSelect函式。 WSAAsyncSelect模型是Se

QDU第一屆程式設計大賽——E到I題解法非官方題解

題目連結https://qduoj.com/contest/28/problems,密碼:qdu1230 E題: 思路:先進行排序,然後去暴力模擬就可以,但可能WA了幾次,導致此題沒解出來,有點可惜 程式碼: #include<cstdio> #include<al

androidPopUpWindow顯示Listview檔案列表

main.xml <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" and

Linux系統程式設計 ---系統呼叫

系統呼叫 計算機系統的各種硬體資源是有限的,在現代多工作業系統上同時執行的多個程序都需要訪問這些資源,為了更好的管理這些資源程序是不允許直接操作的,所有對這些資源的訪問都必須有作業系統控制。也就是說作業系統是使用這些資源的唯一入口,而這個入口就是作業系統提供的系統呼叫 (System

Linux系統程式設計—共享記憶體mmap

共享記憶體概念 共享記憶體是通訊效率最高的IPC方式,因為程序可以直接讀寫記憶體,而無需進行資料的拷備。但是它沒有自帶同步機制,需要配合訊號量等方式來進行同步。 共享記憶體被建立以後,同一塊實體記憶體被對映到了多個程序地址空間,當有一個程序修改了共享記憶體的資料,其餘的程序均可看見所修改的內容,反之亦然。

Linux檔案系統程式設計 系統呼叫 檔案偏移指標測試

測試1: #include <stdio.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <unistd.h>

linux應用程式設計I/O程式設計

相關函式: 一、相關函式 1 fopen() 呼叫open開啟指定的檔案,返回 一個檔案描述符(int 型),分配一個file結構體,包括檔案描述符,I/O快取區,和當前讀寫位置等資訊。 2 fgetc() 通過傳入的資訊到I/O快取區讀取一個字元,如果能讀取成功則直接返回

Linux系統程式設計第二版 編譯程式指令

Linux系統程式設計第二版還在學習中。。。零碎記錄一些東西: 前言中提到的編譯命令: gcc -Wall -Wextra -02 -g -o snippet snippet.c 上面的命令會

Linux網路程式設計I/O複用迴圈伺服器

原文:http://blog.csdn.net/chenjin_zhong/article/details/7270166 1.介紹 在前幾節,我們介紹了迴圈伺服器,併發伺服器. 簡單的迴圈伺服器每次只能處理一個請求,即處理的請求是序列的。而併發伺服器可以通過建立多

Linux系統程式設計 —共享記憶體mmap

**共享記憶體概念** 共享記憶體是通訊效率最高的IPC方式,因為程序可以直接讀寫記憶體,而無需進行資料的拷備。但是它沒有自帶同步機制,需要配合訊號量等方式來進行同步。 共享記憶體被建立以後,同一塊實體記憶體被對映到了多個程序地址空間,當有一個程序修改了共享記憶體的資料,其餘的程序均可看見所修改的內容,反

Linux 併發echo伺服器I/O複用select

select 簡介: 將待監聽套接字加入集合,監測,若有資料到來,進行echo,若有新連線請求到來,accept並將對應套接字加入集合 函式: int select(int , fd_set* rd, fd_set* wr , fd_set* except ,