Paepoi

Paepoi » PyGObject Tips » GIOChannel(PyGObject) Tips

GIOChannel(PyGObject) Tips

# 最終更新日 2026.01.03

GIOChannel はファイルディスクプリタという昔ながらの入出力。
Gjs で行う場合と違い文字コードの扱いがバラバラなので注意。
正直 Python 標準機能でやったほうがいいけど他言語への応用も兼ねて。

標準入出力
#!/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()
# stdin へのアクセス終了
channel.shutdown(True)

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

ファイルの読み書き
#!/usr/bin/env python3
 
'''
    output.txt が存在する場合上書きされるので注意
    作成される output.txt は自分で削除してください
'''

from gi.repository import GLib
 
WRITE_TEXT = '''abcABC
日本語
3行目'''

# 書き込み、UTF-8 つまりバイナリに変換してから書き込む
channel1 = GLib.IOChannel.new_file('output.txt', 'w')
channel1.write_chars(WRITE_TEXT.encode('utf8'), -1)
channel1.shutdown(True)

# 一括読み込み、UTF-8 つまりバイナリのままなのでデコードが必要
print('1')
channel2 = GLib.IOChannel.new_file('output.txt', 'r')
status, str_return = channel2.read_to_end()
print(str_return.decode())
channel2.shutdown(True)

# 一行毎に処理した場合は Python 文字列で戻る、だからー
print('2')
channel3 = GLib.IOChannel.new_file('output.txt', 'r')
while True:
    status, str_return, length, pos = channel3.read_line()
    if status == GLib.IOStatus.EOF:
        break
    print(str_return, end='');

channel3.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('パイプから渡してください')
channel.shutdown(True)
Copyright(C) sasakima-nao All rights reserved 2002 --- 2026.