![](/img/trans.png)
[英]Using O_CREAT O_WRONLY : How to get current position in the file and append data at the end?
[英]Equivalent of open(O_WRONLY | O_CREAT) in GLib?
我需要打開一個文件進行寫入。 如果文件已經存在,我不想截斷它。
換句話說,用普通的C我會做:
int fd = open("output.bin", O_WRONLY | O_CREAT, 0666);
// I don't mind using O_RDWR, btw.
我正在嘗試使用GLib的GFile(GIO的一部分)做類似的事情。 我首先嘗試:
g_file_create(gfile, G_FILE_CREATE_NONE, NULL, NULL);
但是,如果文件已存在,則失敗。
我看到還有大約5個其他函數返回GFileOutputStream
或GFileIOStream
,但是我看不到一個能滿足我想要的功能。
我想念什么嗎?
我是否需要將此簡單任務分解為幾個小任務? (檢查文件是否存在;如果存在,則創建,否則打開;所有文件都以某種方式包裝在鎖中。)
(順便說一句,如果重要的話:我的文件將駐留在本地文件系統上,而不是網絡文件系統上。另外,我正在Vala工作,這就是為什么我不只是使用open()
(也許我可以找到它的綁定) ,但我更喜歡學習GIO的做事方式。)
我分兩個步驟完成了此操作。 我使用G_IO_ERROR_EXISTS
建議檢查G_IO_ERROR_EXISTS
。 我的代碼:
public class Downloader {
public FileIOStream iostream;
public OutputStream output { get { return iostream.output_stream; } }
public void create_output_file() throws Error
{
File file = File.new_for_path("output.bin");
try {
// If file doesn't exist.
iostream = file.create_readwrite(NONE);
} catch (Error e) {
if (e is IOError.EXISTS)
// It exists.
iostream = file.open_readwrite();
else
throw e;
}
}
}
(這里可能存在比賽條件,但與我的情況無關。)
Valadoc.org文檔提供了很好的示例,因此在這里我不會編寫一個有效的示例。 我認為您需要GLib.File.new_for_path ()
和GLib.File.append_to ()
。 g_file_append_to ()
的C文檔建議'獲取用於將數據追加到文件的輸出流。 如果文件不存在,則會創建它。 請注意, append_to ()
采用FileCreateFlags
參數。 還有一個用於Vala的append_to ()
異步版本, append_to_async ()
。
順便說一下, open ()
的Vala綁定在Posix VAPI中。 請參閱Valadoc.org上的open ()
, O_WRONLY
和O_CREAT
。
官方的上游答案是,GIO作為高級抽象層,最初並未設計來保證原子的創建或打開操作(與O_CREAT
),因此有兩種選擇:
G_IO_ERROR_EXISTS
,請嘗試打開它; G_IO_ERROR_EXISTS
,請嘗試打開它。 如你的回答 。 O_CREAT
open()
創建/打開文件(如問題所示),然后將FD傳遞到g_unix_output_stream_new()
以創建一個新的GOutputStream
來包裝FD,您可以像寫入g_file_create()
一樣將其寫入。 請注意, g_unix_output_stream_new()
不能移植到非Unix平台上,但這與您的情況無關。 如果您確實想消除比賽條件,則建議使用第二種方法。
請注意,還有其他避免競爭情況的原因:更少的代碼,更少的系統調用(這意味着更好的性能)和更多可讀的代碼(如果您忽略open()
API的突然命名)。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.