openssl之BIO系列之11---檔案(file)型別BIO (轉)
openssl之BIO系列之11---檔案(file)型別BIO (轉)[@more@](file)型別BIO
---根據open doc/crypto/bio/bio_s_file.pod翻譯和自己的理解寫成
(作者:DragonKing :wzhah@263 釋出於:之openssl專業論壇)
前面我們已經介紹了很多BIO的基本構造和操作,現在,我們開始針對每一個型別BIO進行進一步的介紹,這些介紹都是基本基於openssl的幫助文件的,我儘可能加入自己的一些理解,理清思路。在開始這部分之前,我一直在想該從哪一種型別的BIO開始比較合適,因為這些BIO型別之間有些還是有相互聯絡的,比如BIO_s_bio型就和BIO_f_ssl有關係,最後,考慮到大家對檔案操作都比較熟悉,而且該型別BIO比較獨立,我決定從這個BIO開始介紹,隨後逐步介紹其它/sink型BIO,然後再介紹filter型BIO。
檔案(file)型別BIO的相關和定義如下(opensslbio.h):
BIO_METHOD * BIO_s_file(void);
BIO *BIO_new_file(const char *filename, const char *mode);
BIO *BIO_new_fp(FILE *stream, int flags);
BIO_set_fp(BIO *b,FILE *fp, int flags);
BIO_get_fp(BIO *b,FILE **fpp);
int BIO_read_filename(BIO *b, char *name)
int BIO_write_filename(BIO *b, char *name)
int BIO_append_filename(BIO *b, char *name)
int BIO_rw_filename(BIO *b, char *name)
下面逐一介紹它們的作用和用法。
【BIO_s_file】
經過前面的介紹,大家應該對這種型別的函式結構很熟悉了,他們就是生成BIO型別的基本建構函式,BIO_s_file返回file型別的BIO,file型別的BIO封裝了一個標準的檔案結構,它是一種source/sink型BIO。file型別的BIO_METHOD結構定義如下:
static BIO_METHOD methods_filep=
{
BIO_TYPE_FILE,
"FILE pointer",
file_write,
file_read,
file_puts,
file_gets,
file_ctrl,
file_new,
file_free,
NULL,
};
可以看到,file型別的BIO定義了7個函式,這些函式的實現都在Cryptobiobss_file.c裡面,大家如果要了解該型別BIO的函式實現,可以參考該檔案。事實上,BIO_s_file只是簡單返回一個file型別的BIO_METHOD的結構的指標,其函式實現如下:
BIO_METHOD *BIO_s_file(void)
{
return(&methods_filep);
}
其實,從這個結構可以略見BIO的實現的一班,即BIO的所有動作都是根據它的BIO_METHOD的型別(第一個引數)來決定它的動作和行為的,從而實現BIO對各種型別的多型實現。
在file型別中,使用前面介紹過的BIO_read和BIO_write對底層的file資料流進行讀寫操作,file型別BIO是支援BIO_gets和BIO_puts函式的(大家如果忘了這些函式的作用,請參考前面的《BIO系列之6---BIO的IO操作函式》)。
BIO_flush函式在file型別BIO中只是簡單了函式fflush。
BIO_reset函式則將檔案指標重新指向檔案的開始位置,它呼叫fseek(stream,0,0)函式實現該功能。
BIO_seek函式將檔案指標位置至於所定義的位置ofs上(從檔案開頭開始計算的偏移ofs),它呼叫了檔案的操作函式fseek(stream,ofs,0),是一個宏定義形式的函式,需要注意的是,因為該函式呼叫了fseek函式,所以成功的時候返回0,失敗的時候返回-1,這是跟標準BIO_seek函式定義不一樣的,因為標準的定義是成功返回1,失敗返回非正值。
BIO_eof呼叫了feof函式。
如果在BIO結構中設定了BIO_CLOSE的標誌,則在BIO釋放的時候會自動呼叫fclose函式。
【BIO_new_file】
該函式根據給定的mode型別建立了一個檔案BIO,mode引數的函式跟fopen函式中mode引數的含義是一樣的。返回的BIO設定了BIO_CLOSE標誌。呼叫成功返回一個BIO,否則返回NULL。
事實上,該函式先呼叫了fopen函式開啟一個檔案,然後呼叫BIO_new函式建立一個file型別BIO,最後呼叫函式BIO_set_fp函式給BIO結構跟相關的file幫定。
【BIO_new_fp】
用檔案描述符建立一個file型別BIO,引數Flags可以為BIO_CLOSE,BIO_NOCLOSE(關閉標誌)以及BIO_FP_TEXT(將檔案設定為文字,預設的是二進位制模式,該選項只對平臺有效)。事實上,該函式呼叫BIO_new函式建立一個file型別BIO,然後呼叫函式BIO_set_fp函式給BIO結構跟相關的file幫定。需要注意的是,如果下層封裝的是stdout,stdin和stderr,他們因為跟一般的是不關閉的,所以應該設定BIO_NOCLOSE標誌。呼叫成功返回一個BIO,否則返回NULL。
【BIO_set_fp】
該函式將BIO跟檔案描述符fp幫定在一起,其引數flags的含義跟BIO_new_fp是一樣的。該函式是一個宏定義函式。呼叫成功返回1,否則返回0,不過目前的實現是從來不會出現失敗情況的。
【BIO_get_fp】
該函式返回file型別BIO中檔案描述符,也是一個宏定義。呼叫成功返回1,否則返回0,不過目前的實現是從來不會出現失敗情況的。
【BIO_tell】
返回位置指標的值。是一個宏定義函式。
【BIO_read_filename, BIO_write_filename, BIO_append_filename, BIO_rw_filename】
這四個函式分別設定BIO的讀檔名,寫檔名,附加檔名以及讀寫的檔名。他們都是一些宏定義函式。呼叫成功返回1,否則返回0。
從上面各函式的介紹可以看出,因為BIO呼叫了底層的各種操作函式,所以,如果底層函式的呼叫有任何異常,都會反映在BIO的呼叫上。
下面舉幾個BIO檔案型別操作的簡單例子:
1.最簡單的例項
BIO *bio_out;
bio_out = BIO_new_fp(stdout, BIO_NOCLOSE);
BIO_printf(bio_out, "Hello Worldn");
2.上述例子的另一種實現方法
BIO *bio_out;
bio_out = BIO_new(BIO_s_file());
if(bio_out == NULL) /* 出錯*/
if(!BIO_set_fp(bio_out, stdout, BIO_NOCLOSE)) /* 出錯則將檔案流定向到標準輸出*/
BIO_printf(bio_out, "Hello Worldn");
3.寫檔案操作
BIO *out;
out = BIO_new_file("filename.txt", "w");
if(!out) /*出錯 */
BIO_printf(out, "Hello Worldn");
BIO_free(out);
4.上述例子的另一種實現方法
BIO *out;
out = BIO_new(BIO_s_file());
if(out == NULL) /* Error ... */
if(!BIO_write_filename(out, "filename.txt")) /* Error ... */
BIO_printf(out, "Hello Worldn");
BIO_free(out);
---根據open doc/crypto/bio/bio_s_file.pod翻譯和自己的理解寫成
(作者:DragonKing :wzhah@263 釋出於:之openssl專業論壇)
前面我們已經介紹了很多BIO的基本構造和操作,現在,我們開始針對每一個型別BIO進行進一步的介紹,這些介紹都是基本基於openssl的幫助文件的,我儘可能加入自己的一些理解,理清思路。在開始這部分之前,我一直在想該從哪一種型別的BIO開始比較合適,因為這些BIO型別之間有些還是有相互聯絡的,比如BIO_s_bio型就和BIO_f_ssl有關係,最後,考慮到大家對檔案操作都比較熟悉,而且該型別BIO比較獨立,我決定從這個BIO開始介紹,隨後逐步介紹其它/sink型BIO,然後再介紹filter型BIO。
檔案(file)型別BIO的相關和定義如下(opensslbio.h):
BIO_METHOD * BIO_s_file(void);
BIO *BIO_new_file(const char *filename, const char *mode);
BIO *BIO_new_fp(FILE *stream, int flags);
BIO_set_fp(BIO *b,FILE *fp, int flags);
BIO_get_fp(BIO *b,FILE **fpp);
int BIO_read_filename(BIO *b, char *name)
int BIO_write_filename(BIO *b, char *name)
int BIO_append_filename(BIO *b, char *name)
int BIO_rw_filename(BIO *b, char *name)
下面逐一介紹它們的作用和用法。
【BIO_s_file】
經過前面的介紹,大家應該對這種型別的函式結構很熟悉了,他們就是生成BIO型別的基本建構函式,BIO_s_file返回file型別的BIO,file型別的BIO封裝了一個標準的檔案結構,它是一種source/sink型BIO。file型別的BIO_METHOD結構定義如下:
static BIO_METHOD methods_filep=
{
BIO_TYPE_FILE,
"FILE pointer",
file_write,
file_read,
file_puts,
file_gets,
file_ctrl,
file_new,
file_free,
NULL,
};
可以看到,file型別的BIO定義了7個函式,這些函式的實現都在Cryptobiobss_file.c裡面,大家如果要了解該型別BIO的函式實現,可以參考該檔案。事實上,BIO_s_file只是簡單返回一個file型別的BIO_METHOD的結構的指標,其函式實現如下:
BIO_METHOD *BIO_s_file(void)
{
return(&methods_filep);
}
其實,從這個結構可以略見BIO的實現的一班,即BIO的所有動作都是根據它的BIO_METHOD的型別(第一個引數)來決定它的動作和行為的,從而實現BIO對各種型別的多型實現。
在file型別中,使用前面介紹過的BIO_read和BIO_write對底層的file資料流進行讀寫操作,file型別BIO是支援BIO_gets和BIO_puts函式的(大家如果忘了這些函式的作用,請參考前面的《BIO系列之6---BIO的IO操作函式》)。
BIO_flush函式在file型別BIO中只是簡單了函式fflush。
BIO_reset函式則將檔案指標重新指向檔案的開始位置,它呼叫fseek(stream,0,0)函式實現該功能。
BIO_seek函式將檔案指標位置至於所定義的位置ofs上(從檔案開頭開始計算的偏移ofs),它呼叫了檔案的操作函式fseek(stream,ofs,0),是一個宏定義形式的函式,需要注意的是,因為該函式呼叫了fseek函式,所以成功的時候返回0,失敗的時候返回-1,這是跟標準BIO_seek函式定義不一樣的,因為標準的定義是成功返回1,失敗返回非正值。
BIO_eof呼叫了feof函式。
如果在BIO結構中設定了BIO_CLOSE的標誌,則在BIO釋放的時候會自動呼叫fclose函式。
【BIO_new_file】
該函式根據給定的mode型別建立了一個檔案BIO,mode引數的函式跟fopen函式中mode引數的含義是一樣的。返回的BIO設定了BIO_CLOSE標誌。呼叫成功返回一個BIO,否則返回NULL。
事實上,該函式先呼叫了fopen函式開啟一個檔案,然後呼叫BIO_new函式建立一個file型別BIO,最後呼叫函式BIO_set_fp函式給BIO結構跟相關的file幫定。
【BIO_new_fp】
用檔案描述符建立一個file型別BIO,引數Flags可以為BIO_CLOSE,BIO_NOCLOSE(關閉標誌)以及BIO_FP_TEXT(將檔案設定為文字,預設的是二進位制模式,該選項只對平臺有效)。事實上,該函式呼叫BIO_new函式建立一個file型別BIO,然後呼叫函式BIO_set_fp函式給BIO結構跟相關的file幫定。需要注意的是,如果下層封裝的是stdout,stdin和stderr,他們因為跟一般的是不關閉的,所以應該設定BIO_NOCLOSE標誌。呼叫成功返回一個BIO,否則返回NULL。
【BIO_set_fp】
該函式將BIO跟檔案描述符fp幫定在一起,其引數flags的含義跟BIO_new_fp是一樣的。該函式是一個宏定義函式。呼叫成功返回1,否則返回0,不過目前的實現是從來不會出現失敗情況的。
【BIO_get_fp】
該函式返回file型別BIO中檔案描述符,也是一個宏定義。呼叫成功返回1,否則返回0,不過目前的實現是從來不會出現失敗情況的。
【BIO_tell】
返回位置指標的值。是一個宏定義函式。
【BIO_read_filename, BIO_write_filename, BIO_append_filename, BIO_rw_filename】
這四個函式分別設定BIO的讀檔名,寫檔名,附加檔名以及讀寫的檔名。他們都是一些宏定義函式。呼叫成功返回1,否則返回0。
從上面各函式的介紹可以看出,因為BIO呼叫了底層的各種操作函式,所以,如果底層函式的呼叫有任何異常,都會反映在BIO的呼叫上。
下面舉幾個BIO檔案型別操作的簡單例子:
1.最簡單的例項
BIO *bio_out;
bio_out = BIO_new_fp(stdout, BIO_NOCLOSE);
BIO_printf(bio_out, "Hello Worldn");
2.上述例子的另一種實現方法
BIO *bio_out;
bio_out = BIO_new(BIO_s_file());
if(bio_out == NULL) /* 出錯*/
if(!BIO_set_fp(bio_out, stdout, BIO_NOCLOSE)) /* 出錯則將檔案流定向到標準輸出*/
BIO_printf(bio_out, "Hello Worldn");
3.寫檔案操作
BIO *out;
out = BIO_new_file("filename.txt", "w");
if(!out) /*出錯 */
BIO_printf(out, "Hello Worldn");
BIO_free(out);
4.上述例子的另一種實現方法
BIO *out;
out = BIO_new(BIO_s_file());
if(out == NULL) /* Error ... */
if(!BIO_write_filename(out, "filename.txt")) /* Error ... */
BIO_printf(out, "Hello Worldn");
BIO_free(out);
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/10752043/viewspace-993285/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- openssl之BIO系列之13---Socket型別BIO (轉)型別
- openssl之BIO系列之21---Base64型別的BIO (轉)型別
- BIO到NIO原始碼的一些事兒之BIO原始碼
- Java雜記10—BIO,BIO和NIO的區別Java
- BIO、NIO的區別
- NIO、BIO、AIO區別AI
- BIO、NIO、AIO的區別AI
- From BIO to NIO series —— BIO source code interpretation
- BIO、NIO、AIOAI
- 從零開始netty學習筆記之BIONetty筆記
- Java BIO,NIO,AIOJavaAI
- TS系列之型別型別
- java BIO、NIO學習Java
- BIO,NIO,AIO概覽AI
- BIO到NIO原始碼的一些事兒之NIO 下 之 Selector原始碼
- BIO、NIO、AIO區別(看不懂你打我)AI
- <input type="file"> 限制檔案型別型別
- BIO到NIO原始碼的一些事兒之NIO 中原始碼
- BIO到NIO原始碼的一些事兒之NIO 上原始碼
- java BIO/NIO/AIO 學習JavaAI
- JAVA阻塞IO(BIO)簡介Java
- 三分鐘秒懂BIO/NIO/AIO區別?AI
- 表示一個檔案的 File 型別型別
- struts2檔案上傳型別限制 之 zip和rar檔案型別型別
- 我使用過的Linux命令之file - 檢測並顯示檔案型別Linux型別
- openssl之EVP系列之2---對稱加密演算法概述 (轉)加密演算法
- NIO、BIO、AIO 與 PHP 實現AIPHP
- BIO、NIO、多路複用IO、AIOAI
- 各種檔案用JS轉Base64之後的data型別JS型別
- tomcat執行模式(bio,aio,apr)Tomcat模式AI
- Python3之檔案操作filePython
- oracle檔案管理之 control fileOracle
- 將input type="file" 型別的圖片檔案轉成base64型別
- BIO到NIO原始碼的一些事兒之NIO 下 Buffer解讀 下原始碼
- BIO到NIO原始碼的一些事兒之NIO 下 Buffer解讀 上原始碼
- 一文搞懂NIO、AIO、BIO的核心區別(建議收藏)AI
- 強制型別轉換之(==)型別
- input file控制元件限制上傳檔案型別控制元件型別