Python dictionary を 標準出力してJavaでMap として読み込む。
先日書いたものの勢いにまかせて、、、
Python 標準出力→Java受け取り - Oboe吹きプログラマの黙示録
Javaからプロセス起動で実行するPython と文字列の受け渡し - Oboe吹きプログラマの黙示録
では、リストではなく、Pythonの dictionary を 標準出力してJavaでMap として読み込む。というのも、
Base64 エンコードで受け渡せば安定して実行できる、
先日書いた標準 IOをまとめた Python コードに、辞書をBase64エンコードして標準出力するメソッドを
追加する。
util ディレクトリに置く stdio.py
# -*- coding: UTF-8 -*- from base64 import b64encode class StdIO: # 標準入力 # escape=True : inputした文字をUnicode文字列に変換してリストにする # 標準入力=Unicode入力を想定(Javaプロセス標準出力から受信する場合はTrueにする) # escape=False : inputした文字を変換なしでリストにする。 # 標準入力=通常 def input(self, escape=True): inlist = [] try: if escape: while True: inp = input('') if inp == '': break inlist.append(inp.encode().decode('unicode-escape')) else: while True: inp = input('') if inp == '': break inlist.append(inp) except EOFError: pass return inlist # リストを標準出力 # escape=True : リスト要素をunicode-escape にエンコードして出力 # code : 出力する文字コード、デフォルト 'utf-8' ユニコード指定は、'unicode-escape' def printList(self, list, base64=False, code='utf-8'): outlist = [] if base64==True: for e in list: data = e.encode(code) outlist.append(b64encode(data).decode()) else: for e in list: data = e.encode(code) outlist.append(data) print(outlist) # 辞書をBase64エンコードして標準出力 def printDictionary(self, dict): o = {} for k, v in dict.items(): o[b64encode(("%s" % k).encode('utf-8')).decode()] = b64encode(("%s" % v).encode('utf-8')).decode() print(o)
Javaからプロセス起動する Python
testdictout.py
# -*- coding: UTF-8 -*- from util.stdio import StdIO dict = { 'a':'A', 'b':'B', 10:100 , "A":"あ" } stdio = StdIO() stdio.printDictionary(dict)
Java のコード
import java.io.ByteArrayOutputStream; import java.io.IOException; import java.nio.charset.StandardCharsets; import java.util.Base64; import java.util.HashMap; import java.util.Map; import org.yipuran.function.ThrowableConsumer; import org.yipuran.util.process.ScriptExecutor; import com.google.gson.GsonBuilder; import com.google.gson.reflect.TypeToken;
try(ByteArrayOutputStream out = new ByteArrayOutputStream()){ ScriptExecutor.runStream(()->"python script/testdictout.py" , ThrowableConsumer.of(i->i.transferTo(out)) , (t, e)->{ System.out.println("stderr : " + t ); e.printStackTrace(); }); String response = out.toString(); System.out.println(response); // 解析 System.out.println("====== Google gson による解析 ========="); Map<String, String> getmap = new GsonBuilder().serializeNulls() .create().fromJson(response, new TypeToken<Map<String, String>>(){}.getType()); Map<String, String> map = getmap.entrySet().stream() .collect(()->new HashMap<String, String>() , (r, t)->r.put(new String(Base64.getDecoder().decode(t.getKey()), StandardCharsets.UTF_8) , new String(Base64.getDecoder().decode(t.getValue()), StandardCharsets.UTF_8)) , (r, u)->r.putAll(u)); map.entrySet().stream().forEach(e->{ System.out.println(e.getKey() + " : " + e.getValue()); }); }catch(IOException ex){ ex.printStackTrace(); }finally{ }
結果、、、、
{'YQ==': 'QQ==', 'Yg==': 'Qg==', 'MTA=': 'MTAw', 'QQ==': '44GC'} ====== Google gson による解析 ========= a : A A : あ b : B 10 : 100
でも、こんなことするのは、
大量のデータには効率悪いだろうな。。