2025年9月25日: PostgreSQL 18 釋出!
支援的版本: 當前 (18) / 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_creatlo_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,後者是 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 事務模式的行為。

lo_open 會在大型物件沒有 SELECT 許可權,或者指定了 INV_WRITE 但沒有 UPDATE 許可權時失敗。(在 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 位元組(buf 的大小必須為 len)寫入大型物件描述符 fdfd 引數必須是由之前的 lo_open 返回的。實際寫入的位元組數將被返回(在當前實現中,除非發生錯誤,否則這將始終等於 len)。發生錯誤時,返回值是 -1。

儘管 len 引數被宣告為 size_t,但此函式將拒絕大於 INT_MAX 的長度值。實際上,最好還是將資料分塊傳輸,每塊不超過幾兆位元組。

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

函式

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

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

儘管 len 引數被宣告為 size_t,但此函式將拒絕大於 INT_MAX 的長度值。實際上,最好還是將資料分塊傳輸,每塊不超過幾兆位元組。

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 大小的較大型物件時,請改用

int64_t lo_lseek64(PGconn *conn, int fd, int64_t 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 大小的較大型物件時,請改用

int64_t 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, int64_t len);

此函式與 lo_truncate 具有相同的行為,但它可以接受大於 2GB 的 len 值。

lo_truncatePostgreSQL 8.3 新增的;如果此函式在舊版本伺服器上執行,它將失敗並返回 -1。

lo_truncate64PostgreSQL 9.3 新增的;如果此函式在舊版本伺服器上執行,它將失敗並返回 -1。

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

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

int lo_close(PGconn *conn, int fd);

其中 fdlo_open 返回的大型物件描述符。成功時,lo_close 返回零。錯誤時,返回值是 -1。

在事務結束時仍開啟的任何大型物件描述符將自動關閉。

提交更正

如果您在文件中看到任何不正確、與您在該特定功能上的使用經驗不符或需要進一步闡明的內容,請使用 此表單 報告文件問題。