Paepoi

Paepoi » PyGObject Tips » GIOChannel(PyGObject) Tips

GIOChannel(PyGObject) Tips

# 最終更新日 2019.07.14

GIOChannel はファイルディスクプリタという昔ながらの入出力。
Gio は gvfs による入出力という認識でいいようです。
Gjs と違い文字コード扱いがバラバラなので注意。

標準入出力
#!/usr/bin/env python3

from gi.repository import GLib

# ファイルディスクプリタの stdin=0 にアクセス
channel = GLib.IOChannel.unix_new(0)
# プロンプトの表示、UTF-8 にする必要あり
pr = '何か入力してください > '.encode('utf8')
channel.write_chars(pr, -1)
# フラッシュしないと反映されない
channel.flush()

# stdout=1 のデータを読み込む
channel2 = GLib.IOChannel.unix_new(1)
# 戻り値は 4 つ、最後は \n 位置だけどバイナリ長になる
status, str_return, length, pos = channel2.read_line()
# 行末の \n を取り除く
s = str_return.rstrip()
# こちらは UCS-4 で戻ってくる、ややこしい
print(f'[{s}] が入力されました')

ファイルの読み書き
#!/usr/bin/env python3

# read_to_end では UTF-8 で read_line だと UCS-4 になる

from gi.repository import GLib

s = 'abcdefg\nあいうえお\n3行目'.encode('utf8')
 
channel = GLib.IOChannel.new_file('output.txt', 'w')
channel.write_chars(s, -1)
channel.shutdown(True)
 
channel2 = GLib.IOChannel.new_file('output.txt', 'r')
status, str_return = channel2.read_to_end()
print(str_return.decode())
''' 一行毎に処理したい場合
while True:
    status, str_return, length, pos = channel2.read_line()
    if status == GLib.IOStatus.EOF: break
    # 行末の \n を取り除く
    print(str_return.rstrip());
'''
channel2.shutdown(True)

パイプ入力との振り分け
#!/usr/bin/env python3

from gi.repository import GLib

# stdin=0 stdout=1 
channel = GLib.IOChannel.unix_new(0)
  
if channel.get_flags() == GLib.IOFlags.IS_READABLE:
    # --  Pipe --
    status, str_return = channel.read_to_end()
    s = str_return.decode().rstrip()
    print(f'[{s}] がパイプから渡されました')
else:
    # -- stdin --
    print("パイプから渡してください");
Copyright(C) sasakima-nao All rights reserved 2002 --- 2020.