簡體   English   中英

GLib中的open(O_WRONLY | O_CREAT)是否等效?

[英]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個其他函數返回GFileOutputStreamGFileIOStream ,但是我看不到一個能滿足我想要的功能。

我想念什么嗎?

我是否需要將此簡單任務分解為幾個小任務? (檢查文件是否存在;如果存在,則創建,否則打開;所有文件都以某種方式包裝在鎖中。)

(順便說一句,如果重要的話:我的文件將駐留在本地文件系統上,而不是網絡文件系統上。另外,我正在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_WRONLYO_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的突然命名)。

將來可能會支持使用GFile上的方法直接執行此操作:在GLib中支持它存在一個未解決的問題

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM