支援的版本:目前 (17) / 16 / 15 / 14 / 13
開發版本:devel
不支援的版本:12 / 11 / 10 / 9.6 / 9.5 / 9.4 / 9.3 / 9.2 / 9.1 / 9.0 / 8.4 / 8.3 / 8.2 / 8.1 / 8.0 / 7.4 / 7.3 / 7.2 / 7.1

33.3. 用戶端介面 #

本節描述 PostgreSQLlibpq 用戶端介面函式庫為存取大型物件提供的功能。PostgreSQL 大型物件介面是仿照Unix檔案系統介面,具有 openreadwritelseek 等類似項目。

使用這些函式的所有大型物件操作必須在 SQL 交易區塊內進行,因為大型物件檔案描述元僅在交易期間有效。唯讀交易不允許寫入操作,包括使用 INV_WRITE 模式的 lo_open

如果在執行其中任何一個函式時發生錯誤,該函式將傳回一個其他情況下不可能出現的值,通常為 0 或 -1。描述錯誤的訊息會儲存在連線物件中,可以使用 PQerrorMessage 擷取。

使用這些函式的用戶端應用程式應包含標頭檔 libpq/libpq-fs.h 並連結 libpq 函式庫。

當 libpq 連線處於管線模式時,用戶端應用程式無法使用這些函式。

33.3.1. 建立大型物件 #

函式

Oid lo_create(PGconn *conn, Oid lobjId);

會建立新的大型物件。要指派的 OID 可以由 lobjId 指定;如果是這樣,如果該 OID 已被某些大型物件使用,則會發生失敗。如果 lobjIdInvalidOid(零),則 lo_create 會指派一個未使用的 OID。傳回值是指派給新大型物件的 OID,如果失敗,則為 InvalidOid(零)。

範例

inv_oid = lo_create(conn, desired_oid);

較舊的函式

Oid lo_creat(PGconn *conn, int mode);

也會建立一個新的大型物件,總是會指派一個未使用的 OID。傳回值是指派給新大型物件的 OID,如果失敗,則為 InvalidOid(零)。

PostgreSQL 8.1 及更高版本中,mode 會被忽略,因此 lo_creat 與具有零第二個引數的 lo_create 完全等效。但是,除非您需要使用舊於 8.1 的伺服器,否則沒有太多理由使用 lo_creat。若要使用如此舊的伺服器,您必須使用 lo_creat 而不是 lo_create,並且您必須將 mode 設定為 INV_READINV_WRITEINV_READ | INV_WRITE 之一。(這些符號常數定義在標頭檔 libpq/libpq-fs.h 中。)

範例

inv_oid = lo_creat(conn, INV_READ|INV_WRITE);

33.3.2. 匯入大型物件 #

若要將作業系統檔案匯入為大型物件,請呼叫

Oid lo_import(PGconn *conn, const char *filename);

filename 指定要匯入為大型物件的檔案的作業系統名稱。傳回值是指派給新大型物件的 OID,如果失敗,則為 InvalidOid(零)。請注意,檔案由用戶端介面函式庫讀取,而不是由伺服器讀取;因此它必須存在於用戶端檔案系統中,並且可由用戶端應用程式讀取。

函式

Oid lo_import_with_oid(PGconn *conn, const char *filename, Oid lobjId);

也會匯入新的大型物件。要指派的 OID 可以由 lobjId 指定;如果是這樣,如果該 OID 已被某些大型物件使用,則會發生失敗。如果 lobjIdInvalidOid(零),則 lo_import_with_oid 會指派一個未使用的 OID(這與 lo_import 的行為相同)。傳回值是指派給新大型物件的 OID,如果失敗,則為 InvalidOid(零)。

lo_import_with_oidPostgreSQL 8.4 的新功能,並且在內部使用 lo_create,而 lo_create 是 8.1 的新功能;如果此函數在 8.0 或更早版本上執行,它將會失敗並傳回 InvalidOid

33.3.3. 匯出大型物件 #

要將大型物件匯出到作業系統檔案,請呼叫

int lo_export(PGconn *conn, Oid lobjId, const char *filename);

lobjId 引數指定要匯出的大型物件的 OID,而 filename 引數指定檔案的作業系統名稱。 請注意,該檔案是由用戶端介面程式庫寫入,而不是由伺服器寫入。 成功時傳回 1,失敗時傳回 -1。

33.3.4. 開啟現有的大型物件 #

要開啟現有的大型物件以進行讀取或寫入,請呼叫

int lo_open(PGconn *conn, Oid lobjId, int mode);

lobjId 引數指定要開啟的大型物件的 OID。 mode 位元控制物件是開啟以進行讀取 (INV_READ)、寫入 (INV_WRITE) 還是兩者皆可。(這些符號常數定義在標頭檔 libpq/libpq-fs.h 中。) lo_open 傳回一個(非負數)大型物件描述元,供稍後在 lo_readlo_writelo_lseeklo_lseek64lo_telllo_tell64lo_truncatelo_truncate64lo_close 中使用。 描述元僅在目前交易期間有效。 失敗時,傳回 -1。

伺服器目前不區分模式 INV_WRITEINV_READ | INV_WRITE:在任何一種情況下,您都可以從描述元讀取。 但是,這些模式與單獨的 INV_READ 之間存在顯著差異:使用 INV_READ,您無法寫入描述元,並且從中讀取的資料將反映大型物件在執行 lo_open 時處於活動狀態的交易快照的內容,無論稍後此交易或其他交易的寫入如何。 從使用 INV_WRITE 開啟的描述元讀取會傳回反映其他已提交交易的所有寫入以及目前交易的寫入的資料。 這與用於普通 SQL SELECT 指令的 REPEATABLE READREAD COMMITTED 交易模式的行為類似。

如果大型物件沒有 SELECT 權限,或者指定了 INV_WRITE 且沒有 UPDATE 權限,lo_open 將會失敗。(在 PostgreSQL 11 之前的版本中,這些權限檢查是在使用描述元的第一次實際讀取或寫入呼叫時執行的。) 可以使用 lo_compat_privileges 執行期參數來停用這些權限檢查。

範例

inv_fd = lo_open(conn, inv_oid, INV_READ|INV_WRITE);

33.3.5. 將資料寫入大型物件 #

函數

int lo_write(PGconn *conn, int fd, const char *buf, size_t len);

buf 中的 len 個位元組(必須為 len 大小)寫入大型物件描述元 fdfd 引數必須由先前的 lo_open 傳回。 傳回實際寫入的位元組數(在目前的實作中,除非發生錯誤,否則這將始終等於 len)。 如果發生錯誤,傳回值為 -1。

雖然 len 參數宣告為 size_t,但此函數將拒絕大於 INT_MAX 的長度值。 在實務上,最好還是以最多幾 MB 的區塊傳輸資料。

33.3.6. 從大型物件讀取資料 #

函數

int lo_read(PGconn *conn, int fd, char *buf, size_t len);

從大型物件描述元 fd 讀取最多 len 個位元組到 buf 中(必須為 len 大小)。 fd 引數必須由先前的 lo_open 傳回。 傳回實際讀取的位元組數;如果首先到達大型物件的結尾,則該值將小於 len。 如果發生錯誤,傳回值為 -1。

雖然 len 參數宣告為 size_t,但此函數將拒絕大於 INT_MAX 的長度值。 在實務上,最好還是以最多幾 MB 的區塊傳輸資料。

33.3.7. 在大型物件中搜尋 #

要變更與大型物件描述元關聯的目前讀取或寫入位置,請呼叫

int lo_lseek(PGconn *conn, int fd, int offset, int whence);

此函數將由 fd 識別的大型物件描述元的目前位置指標移動到由 offset 指定的新位置。 whence 的有效值為 SEEK_SET(從物件開頭搜尋)、SEEK_CUR(從目前位置搜尋)和 SEEK_END(從物件結尾搜尋)。 傳回值為新的位置指標,如果發生錯誤,則為 -1。

處理大小可能超過 2GB 的大型物件時,請改用

pg_int64 lo_lseek64(PGconn *conn, int fd, pg_int64 offset, int whence);

此函數的行為與 lo_lseek 相同,但它可以接受大於 2GB 的 offset 和/或提供大於 2GB 的結果。 請注意,如果新的位置指標大於 2GB,lo_lseek 將會失敗。

lo_lseek64PostgreSQL 9.3 的新功能。 如果此函數在較舊的伺服器版本上執行,它將會失敗並傳回 -1。

33.3.8. 取得大型物件的搜尋位置 #

要取得大型物件描述元的目前讀取或寫入位置,請呼叫

int lo_tell(PGconn *conn, int fd);

如果發生錯誤,傳回值為 -1。

處理大小可能超過 2GB 的大型物件時,請改用

pg_int64 lo_tell64(PGconn *conn, int fd);

此函數的行為與 lo_tell 相同,但它可以提供大於 2GB 的結果。 請注意,如果目前的讀取/寫入位置大於 2GB,lo_tell 將會失敗。

lo_tell64PostgreSQL 9.3 的新功能。 如果此函數在較舊的伺服器版本上執行,它將會失敗並傳回 -1。

33.3.9. 截斷大型物件 #

要將大型物件截斷至給定的長度,請呼叫

int lo_truncate(PGconn *conn, int fd, size_t len);

此函數會將大型物件描述符 fd 截斷至長度 lenfd 參數必須是由先前的 lo_open 所回傳。如果 len 大於大型物件目前的長度,則大型物件會延伸至指定的長度,並以空位元組 ('\0') 填充。成功時,lo_truncate 會回傳零。發生錯誤時,回傳值為 -1。

與描述符 fd 相關聯的讀/寫位置不會變更。

雖然 len 參數宣告為 size_t,但 lo_truncate 會拒絕大於 INT_MAX 的長度值。

當處理可能超過 2GB 大小的大型物件時,請改用

int lo_truncate64(PGconn *conn, int fd, pg_int64 len);

此函數的行為與 lo_truncate 相同,但它可以接受超過 2GB 的 len 值。

lo_truncate 是從 PostgreSQL 8.3 開始新增的;如果此函數針對較舊的伺服器版本執行,則會失敗並回傳 -1。

lo_truncate64 是從 PostgreSQL 9.3 開始新增的;如果此函數針對較舊的伺服器版本執行,則會失敗並回傳 -1。

33.3.10. 關閉大型物件描述符 #

可以透過呼叫以下函數來關閉大型物件描述符

int lo_close(PGconn *conn, int fd);

其中 fd 是由 lo_open 回傳的大型物件描述符。成功時,lo_close 會回傳零。發生錯誤時,回傳值為 -1。

在交易結束時仍保持開啟的任何大型物件描述符都會自動關閉。

提交更正

如果您在文件中發現任何不正確、與您使用特定功能的經驗不符或需要進一步澄清的地方,請使用此表單來報告文件問題。