I/O程式設計技術(檔案IO)筆記綱要梳理

舟清颺發表於2024-05-28

序言
Linux基本知識回顧
Linux核心安全管理機制
根檔案系統rootfs
Linux根目錄下檔案結構
Linux檔案型別
標準IO
標準IO運算元據流分析
檔案 開啟、關閉
fopen( )
fclose( )
檔案 字元讀寫
fgetc( )
fputc( )
檔案 行讀寫
fgets( )
fputs( )
檔案 資料快讀寫
fread( )
fwrite( )
檔案 當前位置偏移量 獲取 設定
ftell( )
fseek( )
rewind( )
檔案 狀態判斷
feof( )、ferror( )
標準輸入裝置 讀取、輸出
getchar( )
putchar( )
時間函式
time( )
localtime( )
重新整理緩衝區
fflush( )
系統IO
開啟關閉
open( )
close( )
資料讀寫
read( )
write( )
檔案位置偏移量
lseek( )
記憶體對映
mmap( )
實踐開發
LCD螢幕顯像原理
驅動架構
軟體層
LCD核心原始碼
檔案控制
ioctl( ) 檔案控制
mmap( )記憶體對映
munmap()解除對映
螢幕顯示
BMP影像的儲存
其它函式
sscanf( )
描述
宣告
引數
返回值
strcmp( )
remove()
getchar()
strftime()
atoi()
參考文件

序言

儘可能壓縮筆記,核心在於構建核心知識單元網路。

Linux基本知識回顧

Linux核心安全管理機制

fig:

根檔案系統rootfs

fig:

Linux根目錄下檔案結構

fig:

Linux檔案型別

-(regular) 普通檔案
d(directory) 目錄檔案
p(pipe) 管道檔案
s(socket) 套接字檔案
l(link) 連結檔案
c(character) 字元裝置檔案
b(block) 塊裝置檔案

標準IO

標準IO運算元據流分析

fig:

檔案操作介面

檔案 開啟、關閉

fopen( )

fig:

加b是以二進位制處理

fclose( )

fig:

檔案 字元讀寫

fgetc( )

fig:

fputc( )

fig:

檔案 行讀寫

fgets( )

fig:

fputs( )

fig:

檔案 資料快讀寫

fread( )

fig:

fwrite( )

fig:

字串要用strlen函式,sizeof(“字串”)得到的是地址一個字長。

檔案 當前位置偏移量 獲取 設定

ftell( )

fig:

相較於檔案開頭的位元組數

fseek( )

fig:

rewind( )

fig:

rewind(fp)相等於fseek(fp, 0L, SEEK_SE);

檔案 狀態判斷

feof( )、ferror( )

fig:

標準輸入裝置 讀取、輸出

getchar( )

getchar( )預設從標準輸入裝置讀取一個字元。

putchar( )

putchar( )預設從標準輸出裝置輸出一個字元。

時間函式

time( )

獲取1970至今的秒數

localtime( )

轉換timer的值為tm結構 後的值

重新整理緩衝區

fflush( )

重新整理全緩衝

系統IO

api:應用程式程式設計介面

sdk:軟體開發工具包

標準I/O可以看成是在系統I/O的基礎上封裝了緩衝機制。

檔案描述符是一個小的非負整數。

開啟關閉

open( )

fig:

close( )

fig:

資料讀寫

read( )

fig:

write( )

fig:

檔案位置偏移量

lseek( )

fig:

記憶體對映

mmap( )

fig:

fig:

實踐開發

LCD螢幕顯像原理

偏光片、彩色濾光片

畫素數量、

畫素色深(位深度、色域) : bit-->4Bytes-->ARGB

驅動架構

Framebuffer驅動子系統

粵嵌螢幕解析度 800*480。

ll: c或b開頭的都是硬體裝置驅動提供的檔案

裝置檔案在/dev/fb0

軟體層

LCD核心原始碼

要看核心原始碼

Linux最多支援32塊(編號0~31)LCD螢幕.

檔案控制

ioctl( ) 檔案控制

該函式是一個專用於裝置輸入輸出操作的系統呼叫,該呼叫傳入一個跟裝置有關的請求碼,系統呼叫的功能完全取決於請求碼。

fig:

ioctl(檔案描述符,請求碼,某型別指標) 可以獲取或設定硬體裝置的引數

#include <sys/ioctl.h>
int ioctl(int fd, unsigned long request, ...);

下面我們解釋各個引數的含義。
1)fd是檔案描述符。當我們的裝置作為特殊檔案被open()函式開啟後,會返回一個檔案描述符,透過操作這個檔案描述符達到操作裝置檔案的目的。

2)request是命令碼,應用程式透過下發命令碼來控制驅動程式完成對應操作。

3)第三個引數“…”是可變引數arg,一些情況下應用程式需要向驅動程式傳參,引數就透過ag來傳遞。ioctl函式中的“…”只能傳遞一個引數,但核心不會檢查這個引數的型別。那麼,就有兩種傳參方式:只傳一個整數,傳遞一個指標。

如果ioctl執行成功,它的返回值就是驅動程式中ioctl介面給的返回值,驅動程式可以透過返回值向使用者程式傳參。但驅動程式最好返回一個非負數,因為使用者程式中的ioctl執行失敗時一定會返回-1並設定全域性變數errorno。

errono不同的值代表的含義如下:

EBADF:fd是一個無效的檔案描述符。
EFAULT:在arg是指標的前提下,argp指向一個不可訪問的記憶體空間。
EINVAL:request或argp是無效的。
ENOTTY:fd沒有關聯到一個字元特殊裝置,或該request不適用於檔案描述符fd引用的物件型別。(說人話就是fd沒有指向一個字元裝置,或fd指向的檔案不支援ioctl操作)

因此,在使用者空間呼叫ioctl時,可以使用如下的錯誤判斷處理。包括的兩個標頭檔案,string.h宣告瞭strerror函式,errno.h定義了錯誤碼errno。

#include <string.h>
#include <errno.h>

int ret;
ret = ioctl(fd, MYCMD);
if (ret == -1)
printf("ioctl: %s\n", strerror(errno));

  • ioctl函式詳解(Linux核心 ) - 知乎 (zhihu.com)
  • linux驅動開發(四):ioctl()函式_ioctl函式-CSDN部落格

mmap( )記憶體對映

fig:

fig:

munmap()解除對映

#include <sys/mman.h>

int munmap(void *addr, size_t length);

munmap()系統呼叫解除指定地址範圍內的對映,引數 addr 指定待解除對映地址範圍的起始地址,它必須是系統頁大小的整數倍;引數 length 是一個非負整數,指定了待解除對映區域的大小(位元組數),被解除對映的區域對應的大小也必須是系統頁大小的整數倍,即使引數 length 並不等於系統頁大小的整數倍,與 mmap()函式相似。

需要注意的是,當程序終止時也會自動解除對映(如果程式中沒有顯式呼叫 munmap()),但呼叫 close() 關閉檔案時並不會解除對映。

通常將引數 addr 設定為 mmap()函式的返回值,將引數 length 設定為 mmap()函式的引數 length,表示解除整個由 mmap()函式所建立的對映。

螢幕顯示

BMP影像的儲存

BMP影像記憶體採用小端儲存.

fig:

其它函式

sscanf( )

描述

C 庫函式 int sscanf(const char *str, const char *format, ...) 從字串讀取格式化輸入。

宣告

下面是 sscanf() 函式的宣告。

int sscanf(const char *str, const char *format, ...)

引數

  • str -- 這是 C 字串,是函式檢索資料的源。
  • format -- 這是 C 字串,包含了以下各項中的一個或多個:空格字元、非空格字元format 說明符
    format 說明符形式為 [=%*[modifiers]type=],具體講解如下:

引數

描述

*

這是一個可選的星號,表示資料是從流 stream 中讀取的,但是可以被忽視,即它不儲存在對應的引數中。

width

這指定了在當前讀取操作中讀取的最大字元數。

modifiers

為對應的附加引數所指向的資料指定一個不同於整型(針對 d、i 和 n)、無符號整型(針對 o、u 和 x)或浮點型(針對 e、f 和 g)的大小: h :短整型(針對 d、i 和 n),或無符號短整型(針對 o、u 和 x) l :長整型(針對 d、i 和 n),或無符號長整型(針對 o、u 和 x),或雙精度型(針對 e、f 和 g) L :長雙精度型(針對 e、f 和 g)

type

一個字元,指定了要被讀取的資料型別以及資料讀取方式。具體參見下一個表格。

sscanf 型別說明符:

型別

合格的輸入

引數的型別

c

單個字元:讀取下一個字元。如果指定了一個不為 1 的寬度 width,函式會讀取 width 個字元,並透過引數傳遞,把它們儲存在陣列中連續位置。在末尾不會追加空字元。

char *

d

十進位制整數:數字前面的 + 或 - 號是可選的。

int *

e,E,f,g,G

浮點數:包含了一個小數點、一個可選的前置符號 + 或 -、一個可選的後置字元 e 或 E,以及一個十進位制數字。兩個有效的例項 -732.103 和 7.12e4

float *

o

八進位制整數。

int *

s

字串。這將讀取連續字元,直到遇到一個空格字元(空格字元可以是空白、換行和製表符)。

char *

u

無符號的十進位制整數。

unsigned int *

x,X

十六進位制整數。

int *

  • 附加引數
  • -- 這個函式接受一系列的指標作為附加引數,每一個指標都指向一個物件,物件型別由 format 字串中相應的 % 標籤指定,引數與 % 標籤的順序相同。
  • 針對檢索資料的 format 字串中的每個 format 說明符,應指定一個附加引數。如果您想要把 sscanf 操作的結果儲存在一個普通的變數中,您應該在識別符號前放置引用運算子(&),例如:
  • int n;
    sscanf (str,"%d",&amp;n);

返回值

如果成功,該函式返回成功匹配和賦值的個數。如果到達檔案末尾或發生讀錯誤,則返回 EOF。

strcmp( )

C 庫函式 int strcmp(const char *str1, const char *str2)str1 所指向的字串和 str2 所指向的字串進行比較。

宣告

下面是 strcmp() 函式的宣告。

int strcmp(const char *str1, const char *str2)

引數

  • str1 -- 要進行比較的第一個字串。
  • str2 -- 要進行比較的第二個字串。

返回值

該函式返回值如下:

  • 如果返回值小於 0,則表示 str1 小於 str2。
  • 如果返回值大於 0,則表示 str1 大於 str2。
  • 如果返回值等於 0,則表示 str1 等於 str2。

remove()

描述

C 庫函式 int remove(const char *filename) 刪除給定的檔名 filename,以便它不再被訪問。

宣告

下面是 remove() 函式的宣告。

int remove(const char *filename)

引數

  • filename -- 這是 C 字串,包含了要被刪除的檔名稱。

返回值

如果成功,則返回零。如果錯誤,則返回 -1,並設定 errno。

getchar()

描述

C 庫函式 int getchar(void) 從標準輸入 stdin 獲取一個字元(一個無符號字元)。這等同於 getc 帶有 stdin 作為引數。

宣告

下面是 getchar() 函式的宣告。

int getchar(void)

引數

  • NA

返回值

該函式以無符號 char 強制轉換為 int 的形式返回讀取的字元,如果到達檔案末尾或發生讀錯誤,則返回 EOF。

strftime()

描述

C 庫函式 size_t strftime(char *str, size_t maxsize, const char *format, const struct tm *timeptr) 根據 format 中定義的格式化規則,格式化結構 timeptr 表示的時間,並把它儲存在 str 中。

宣告

下面是 strftime() 函式的宣告。

size_t strftime(char *str, size_t maxsize, const char *format, const struct tm *timeptr)

引數

  • str -- 這是指向目標陣列的指標,用來複制產生的 C 字串。
  • maxsize -- 這是被複制到 str 的最大字元數。
  • format -- 這是 C 字串,包含了普通字元和特殊格式說明符的任何組合。這些格式說明符由函式替換為表示 tm 中所指定時間的相對應值。格式說明符是:

說明符

替換為

例項

%a

縮寫的星期幾名稱

Sun

%A

完整的星期幾名稱

Sunday

%b

縮寫的月份名稱

Mar

%B

完整的月份名稱

March

%c

日期和時間表示法

Sun Aug 19 02:56:02 2012

%d

一月中的第幾天(01-31)

19

%H

24 小時格式的小時(00-23)

14

%I

12 小時格式的小時(01-12)

05

%j

一年中的第幾天(001-366)

231

%m

十進位制數表示的月份(01-12)

08

%M

分(00-59)

55

%p

AM 或 PM 名稱

PM

%S

秒(00-61)

02

%U

一年中的第幾周,以第一個星期日作為第一週的第一天(00-53)

33

%w

十進位制數表示的星期幾,星期日表示為 0(0-6)

4

%W

一年中的第幾周,以第一個星期一作為第一週的第一天(00-53)

34

%x

日期表示法

08/19/12

%X

時間表示法

02:50:06

%y

年份,最後兩個數字(00-99)

01

%Y

年份

2012

%Z

時區的名稱或縮寫

CDT

%%

一個 % 符號

%

  • timeptr

-- 這是指向 tm 結構的指標,該結構包含了一個被分解為以下各部分的日曆時間:

struct tm {
int tm_sec; /* 秒,範圍從 0 到 59 */
int tm_min; /* 分,範圍從 0 到 59 */
int tm_hour; /* 小時,範圍從 0 到 23 */
int tm_mday; /* 一月中的第幾天,範圍從 1 到 31 */
int tm_mon; /* 月份,範圍從 0 到 11 */
int tm_year; /* 自 1900 起的年數 */
int tm_wday; /* 一週中的第幾天,範圍從 0 到 6 */
int tm_yday; /* 一年中的第幾天,範圍從 0 到 365 */
int tm_isdst; /* 夏令時 */
};

返回值

如果產生的 C 字串小於 size 個字元(包括空結束字元),則會返回複製到 str 中的字元總數(不包括空結束字元),否則返回零。

atoi()

描述

C 庫函式 int atoi(const char *str) 把引數 str 所指向的字串轉換為一個整數(型別為 int 型)。

宣告

下面是 atoi() 函式的宣告。

int atoi(const char *str)

引數

  • str -- 要轉換為整數的字串。

返回值

該函式返回轉換後的長整數,如果沒有執行有效的轉換,則返回零。

參考文件

  • 如何在 Linux 中使用 SCP 安全地傳輸檔案 | Linux 中國 - 知乎 (zhihu.com)

相關文章