Paepoi » PyGObject Tips » Gio(PyGObject) Tips
Gio(PyGObject) Tips
# 最終更新日 2019.07.20
Python2 関連の削除、点在していた GFile 関連を整理
文字列をシングルクォートに統一、及び fstring 化(python 3.6 以降)を行いました
Python2 関連の削除、点在していた GFile 関連を整理
文字列をシングルクォートに統一、及び fstring 化(python 3.6 以降)を行いました
GFile 基本
#!/usr/bin/env python3 ''' ファイルの作成、書き込み、コピー、ゴミ箱へ移動 は GIR ではすべて GFile のメソッドで行います ''' from gi.repository import Gio # 以下を都合のいいように変更してください FILENAME = '新規ファイル.txt' CONTENTS = '内容\nです'.encode('utf8') COPYFILE = 'コピー.txt' # GFile の作成は存在しないファイルでもいい f = Gio.file_new_for_path(FILENAME) # 存在しないことの確認 print(f.query_exists()) #=> False # 新規作成、この関数を呼んだ時点でファイルは作られる ostream = f.create(Gio.FileCreateFlags.NONE) # 上書きの場合は replace を使う、実は新規でも使える # 第二引数を True にすると 新規ファイル.txt~ が自動で作られる #ostream = f.replace(None, False, Gio.FileCreateFlags.NONE) # 戻り値の GFileOutputStream を使ってファイル内容を書き込む # 文字列の場合は UTF-8 に変換するのを忘れずに ostream.write(CONTENTS) # 閉じる、この後何もしないならガベージコレクションにまかせてもいい ostream.close() # コピー、詳細不要なら以下でいい c = Gio.file_new_for_path(COPYFILE) f.copy(c, Gio.FileCopyFlags.NONE) # ゴミ箱へ移動 f.trash() # COPYFILE が存在して FILENAME がゴミ箱に入っていることを確認
ファイルの詳細を得る
#!/usr/bin/env python3 ''' g_file_query_info の引数に得たい情報をコンマ区切りで指定し GFileInfo を得る FileInfo オブジェクトのメソッドで情報を出力、という流れで取得できます ファイルの種類(Description) は Content Type から変換します 存在するファイルであれば拡張子は関係無く詳細を取得できる ''' import sys from gi.repository import Gio attr = ','.join([ Gio.FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME, Gio.FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE, Gio.FILE_ATTRIBUTE_STANDARD_SIZE ]) # このスクリプト自身の詳細を得る f = Gio.file_new_for_path(__file__) # g_file_query_info info = f.query_info(attr, Gio.FileQueryInfoFlags.NONE) # Content Type を先に得ておく ct = info.get_content_type() # 出力 print(f'''---------- Name : {info.get_display_name()} Size : {info.get_size()} byte Content Type: {ct} Mime Type : {Gio.content_type_get_mime_type(ct)} Description : {Gio.content_type_get_description(ct)} ----------''')
ファイルの詳細を得る(簡易版)
#!/usr/bin/env python3 ''' ファイルの中身をみないどころか存在すら関係ない版 Gio.content_type_guess は拡張子依存のようです result_uncertain は確実性ですが中身を見ないのでほぼ意味無い ''' from gi.repository import Gio # 拡張子から ContentType を得る ctype = Gio.content_type_guess('a.xml') print(ctype) #=> ('application/xml', result_uncertain=False) # 不明拡張子ならバイナリ扱い、存在しても中身は見ない b = Gio.content_type_guess('a.homura') print(b) #=> ('application/octet-stream', result_uncertain=True) # 説明を得る desc = Gio.content_type_get_description ('application/xml') print(desc) #=> XML ドキュメント # サブセットであるか(以下はテキストファイルであるか) sub = Gio.content_type_is_a('application/xml', 'text/plain') print(sub) #=> True # 実行可能か(+x 属性が付いているかどうかではない) x = Gio.content_type_can_be_executable('application/x-shellscript') print(x) #=> True # ここから GAppInfo appinfo = Gio.app_info_get_default_for_type('text/plain', False) # デフォルトアプリ defapp = appinfo.get_name() # or executable() print(defapp) #=> テキストエディター
非同期読み込み
#!/usr/bin/env python3 ''' 同期読み込みでいいなら下記ストリーミング I/O を 又は f.load_contents にて一気読みしてください ''' from gi.repository import GLib, Gio def on_read_file(gfile, res): r, contents, etag = gfile.load_contents_finish(res) print(contents.decode()) mainloop.quit() f = Gio.file_new_for_path(__file__) # 非同期読み込み開始 f.load_contents_async(None, on_read_file) # メインループが必要 # GUI で使う場合は Gtk.main() が担当するので必要無い mainloop = GLib.MainLoop() mainloop.run()
ストリーミング I/O
#!/usr/bin/env python3 ''' こちらを使う場合 Python 文字列と UTF-8 は自動変換されます ''' from gi.repository import Gio FILENAME = 'suzuki.txt' TEXT = 'スズキはスクーターも\n\nカッコイイ〜!' # Write f = Gio.file_new_for_path(FILENAME) fstream = f.create(Gio.FileCreateFlags.NONE) dstream = Gio.DataOutputStream(base_stream=fstream) dstream.put_string(TEXT) fstream.close() # Read f = Gio.file_new_for_path(FILENAME) fstream = f.read() dstream = Gio.DataInputStream(base_stream=fstream) while True: # line に lf は入らない、length はバイト単位 # line == '' では空文字を判定する、EOF で None になる line, length = dstream.read_line_utf8() if line == None: break print(line) fstream.close()
ディレクトリ内容列挙
#!/usr/bin/env python3 from gi.repository import Gio, GLib # ディレクトリも GFile d = Gio.file_new_for_path(GLib.get_home_dir()) # 表示名と隠しファイルかどうかを得る enum = d.enumerate_children( 'standard::display-name,standard::is-hidden', Gio.FileQueryInfoFlags.NONE) # info は GFileInfo for info in enum: if not info.get_is_hidden(): print(info.get_display_name())
ディレクトリを監視
#!/usr/bin/env python3 ''' ホームディレクトリを監視するサンプル GFileMonitor の changed シグナルが変更毎に飛んできます ''' # mainloop を強制終了させるため import signal signal.signal(signal.SIGINT, signal.SIG_DFL) from gi.repository import Gio, GLib def on_monitor(monitor, f, other_f, event): ''' 隠しファイルの変更も感知します( /.bash.history 等 ) 作成は上書きやリネームでも反応します ''' s = f.get_basename() # 隠しファイルは無視、ココを消すと何故かが解る if s.startswith('.'): return if event == Gio.FileMonitorEvent.CHANGED: print(f'{s} の内容が変更されました') elif event == Gio.FileMonitorEvent.CHANGES_DONE_HINT: print(f'{s} のファイル情報が変更されました') elif event == Gio.FileMonitorEvent.DELETED: print(f'{s} が削除又は移動されました') elif event == Gio.FileMonitorEvent.CREATED: print(f'{s} が作成されました') elif event == Gio.FileMonitorEvent.ATTRIBUTE_CHANGED: print(f'{s} のパーミッションが変更されました') f = Gio.File.new_for_path(GLib.get_home_dir()) monitor = f.monitor(Gio.FileMonitorFlags.NONE) monitor.connect('changed', on_monitor) print('終了するには Ctrl+C を行ってください') # メインループ mainloop = GLib.MainLoop() mainloop.run()
Copyright(C) sasakima-nao All rights reserved 2002 --- 2024.