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 --- 2025.