日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > linux >内容正文

linux

Linux系统文件I/O编程(一)---open()等基本函数

發布時間:2025/3/21 linux 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Linux系统文件I/O编程(一)---open()等基本函数 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

Linux文件I/O系統概述

??? 虛擬文件系統(VFS)

??? Linux系統成功的關鍵因素之一就是具有與其他操作系統和諧共存的能力。Linux系統的文件系統由兩層結構構建:第一層是虛擬文件系統(VFS),第二層是各種不同的具體的文件系統。

??? VFS就是把各種具體的文件系統的公共部分抽取出來,形成一個抽象層,是系統內核的一部分,它位于用戶程序和具體的文件系統之間。它對用戶提供了標準的文件系統調用接口,對具體的文件系統(如EXT2、FAT32等),它通過一系列的對不同文件系統公用的函數指針來實際調用具體的文件系統函數,完成實際的各有差異的操作。任何使用文件系統的程序必須經過這層接口來使用它。通過這樣的方式,VFS就對用戶屏蔽了底層文件系統的實現細節和差異。

??? VFS的作用:①對具體的文件系統的數據結構進行抽象,以一種統一的數據結構進行管理;②接受用戶層的系統調用,如open()、read()、write()、stat()、link()等;③支持多種具體文件系統之間的相互訪問,接受內核其他子系統的操作請求,例如,內存管理和進程調度。

??? VFS在linux系統中的位置如下圖1所示:

???

??? 通過命令:cat /proc/filesystems 可以查看系統中支持哪些文件系統

???

??? 第一列說明文件系統是否需要掛接在一個塊設備上。nodev表明后面的文件系統不需要掛接在塊設備上。

??? 第二列是內核支持的文件系統。

Linu中的文件及文件描述符

??? 與windows不同,Linux操作系統都是基于文件概念的(這個很很重要啊),文件是以字符序列構成的信息載體。根據這一點,可以把I/O設備當做文件來處理。因此,與磁盤上的普通文件進行交互所用的同一系統調用可以直接用于I/O設備。這樣大大簡化了系統對不同設備的處理,提高了效率。

??? Linux中的文件主要分為4種:普通文件、目錄文件、鏈接文件和設備文件,如下圖:

???

?????? 內核如何區分和引用特定的文件呢?這里用到了一個重要的概念-------文件描述符。

?????? 在Linux中,所有對設備和文件的操作都是使用文件描述符來進行的。文件描述符是一個非負的整數,它是一個索引值,并指向在內核中每個進程打開文件的記錄表。當打開一個現存文件或創建一個新文件時,內核就向程返回一個文件描述符;當需要讀寫文件時,也需要把文件描述符作為參數傳遞給相應的函數。(咱可以這樣理解,只有當對文件進行操作時,該文件才會有文件描述符,進程沒有用到的文件統統不給描述符)

????? 通常,一個進程啟動時,都會打開3個文件:標準輸入、標準輸出和標準出錯處理。這3個文件分別對應描述符為0、1和2(也就是宏替換 STDIN_FILENO、STDOUT_FILENO、STDERR_FILENO)。

???? 基于文件描述符的I/O操作雖然不能直接移植到類Linux以外的系統上(如Windows),但它往往是實現某些I/O操作的唯一途徑,如Linux中底層文件操作函數(下邊會講)、多路I/O、TC[/IP套接字編程接口等、同時,它們也很好地兼容Posix標準,因此,可以很方便地移植到任何Posix平臺上?;谖募枋龇腎/O操作是Linux中最常用的操作之一,下面就講講它。

底層文件I/O操作

??? 這次主要介紹文件I/O操作的系統調用,主要用到5個函數:open()、read()、write()、lseek()和close()。這些函數的特點不帶緩存,直接對文件(包括設備)進行讀寫操作。

1、基本文件操作

函數說明

??? ● open()函數用于打開或創建文件,在打開或者創建文件時可以指定文件的屬性及用戶的權限等各種參數。

????● close()函數用于關閉一個被打開的文件。當一個進程終止時,所有被它打開的文件都由內核自動關閉,很多程序都使用這一功能而不顯示地關閉一個文件。

??? ● read()函數用于將從指定的文件中讀出的數據放到緩存區中,并返回實際讀入的字節數。若返回0,則表示沒有數據可讀,即已到達文件尾。讀操作從文件的當前指針位置開始。當從設備文件中讀出數據時,通常一次最多讀一行。

??? ● write()函數用于向打開的文件寫數據。寫操作從文件的當前指針位置開始,對磁盤文件進行寫操作,若磁盤已滿或者超出該文件的長度,則write()函數返回失敗。

??? ● lseek()函數用于在指定的文件描述符中將文件指針定位到相應的位置。每一個已打開的文件都有一個讀寫位置,當打開文件時,其讀寫位置通常指向文件開頭;若是以附加的方式打開文件(如O_APPEND),則讀寫位置會指向文件尾。當read()或者write()時,讀寫位置會隨之增加,lseek()便是用來控制該文件的讀寫位置的。它只能用在可定位(可隨機訪問)文件操作中。管道、套接字和大部分字符設備文件是不可定位的,所以在這些文件的操作中無法使用lseek()調用。

函數格式

??? 下面我以表格的形式將這5個函數的格式寫出來,接下來再加上我的基礎實驗。

???

???? 在open()函數中,flag參數可通過 “|” 組合構成,但前3個標志常量(O_RDONLY、O_WRONLY及O_RDWR)不能相互組合。perms是文件的存取權限,既可以用宏定義表示法,也可以用八進制表示法。

????

???

????? 在讀普通文件時,若讀到要求的字節數前已到達文件的尾部,則返回的字節數會小于希望讀書的字節數。

?????? 關于size_t和ssize_t的區別,如果有不懂的請看:http://blog.csdn.net/mybelief321/article/details/8992052,也可以簡單的記住:ssize_t是有符號整形,size_t是無符號整形。

?????

?? 在寫普通文件時,寫操作從文件的當前指針位置開始。

?

?? 下面是lseek較特別的使用

??? ☆ 欲將讀寫位置移到文件開頭時:lseek(int fd,0,SEEK_SET)

??? ☆ 欲將讀寫位置移到文件尾時:lseek(int fd,0,SEEK_END)

??? ☆ 想要取得目前文件位置時:lseek(ind fd,0,SEEK_CUR)

????注意:Linux系統不允許lseek()對tty裝置作用,此動作會令lseek()返回ESPIPE。

??? 另外,其實還有一個文件創建函數creat(),它的函數原型是int creat(const char *pathname,int perms),它相當于使用下列的調用方式調用open():

??? open(const char *pathname,(O_CREAT|O_WRONLY|O_TRUNC));

基礎實驗1:

??? 實驗說明:主要是為了演示open()函數的使用方法。首先在自己的目錄下使用命令:vi open.c創建一個文件,如下圖,我在路徑/home/song/lianxi文件夾下創建的:
???

??? 然后編寫open.c文件內容,內容如下:

???

????編輯并保存open.c后的文件夾所含全部文件,如下:

???

??? 使用命令:gcc open.c -o open編譯c文件,如下:

???

??? 執行命令:./open 可以看到咱們的實驗成功輸出了:

???

?? 使用命令:more temp查看一下temp的文件,里邊有咱們使用write()寫的內容:

??

??? 我將這個文件內容上傳到了:點此下載,可以自行下載

基礎實驗2

??? 實驗說明:基本功能是從一個文件(源文件)中讀取最后2KB數據并復制到另一個文件(目標文件)。在實例中源文件是以只讀方式打開的,目標文件是以只寫方式(可以使讀/寫方式)打開的。若目標文件不存在,可以創建并設置權限的初始值為644,即文件所有者可讀可寫,文件所屬組合其他用戶只能讀。

??? 首先先后使用命令:vi copy_file.c和 vi src.c 在自己的實驗目錄下創建文件,如下圖

??

?? 然后再編輯copy_file.c的文件內容,如下

#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>

#define Buffer_Size?1024???/*每次讀寫緩存大小為1KB,大小不同,運行效率不同*/
#define Src_File_Name??"/home/song/lianxi/src.c"????/*源文件名,建議使用宏定義*/
#define Dest_File_Name?"/home/song/lianxi/dest.c"????? //目標文件名*/
#define Offset?????1024*2????? //復制的數據大小,這里為2KB*/

int main()
{
?int src_fd,dest_fd;??/*文件描述符*/
?unsigned char buff[Buffer_Size];?? /*定義用于緩沖數據的數組*/
?int real_read_len;???? /*read()函數實際讀取到的字節*/
?/*以只讀方式打開源文件*/
?src_fd=open(Src_File_Name,O_RDONLY);
?/* 以只寫方式打開目標文件,若此文件不存在則創建該文件,訪問權限為644*/
?dest_fd=open(Dest_File_Name,O_WRONLY|O_CREAT,S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH);
?/*如果打開文件出錯,則退出程序*/
?if(src_fd<0||dest_fd<0)
?{
??printf("Open file error\n");
??exit(1);???
?}?
?/* 將源文件的讀/寫指針移到最后2KB的起始位置*/
?lseek(src_fd,-Offset,SEEK_END);
?/* 讀取源文件的最后2KB數據并寫到目標文件中,每次讀寫1KB*/
?while((real_read_len=read(src_fd,buff,sizeof(buff)))>0)
?{
??write(dest_fd,buff,real_read_len);?
?}
?/* 關閉文件,釋放資源*/
?close(dest_fd);
?close(src_fd);
?return 0;
}

?

???? 其中src.c的文件內容你可以自己隨便的放內容,但是要注意文件內容要大于2KB。

??? 這兩個文件我上傳到資源網站,可以自行下載:點此下載

??? 編輯完之后,使用命令: gcc copy_file.c -o copy_file 編譯文件,然后執行命令:./copy_file,可以看到自動生成了dest.c文件

???

??? 使用命令:more dest.c可以看到文件的內容

??? 使用命令:ls -l dest.c可以看到該文件的大小正好為2KB(2048)

????

總結

以上是生活随笔為你收集整理的Linux系统文件I/O编程(一)---open()等基本函数的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。