Java通过Runtime方法
因为前端跨域和机器访问权限问题,前端访问python代码的获取timelineData数据的接口无法不通过代理的形式直接得到,需要java端来提供一个复写的接口,本来程序已经马上就迁移完成了,怎晓得j在ava端竟然寻不到tensorflow的同构包,无奈,自能在java代码中同时借助python代码来迅速解决该问题了。
-
网上给出过很多通过PythonInterpreter来调用python脚本的方案,若果在您的代码中不包含第三方依赖的话,这未尝不是一种比较方便快捷的方案,在这里就不做讨论了。
-
当在python脚本中包含第三方依赖时,目前的解决方案是通过Runtime工具执行cmd命令来调用本地python解释器,然后通过在本地安装需要的依赖包并在python脚本中正常导入即可。
-
安装tensorflow包步骤(mac通过pip安装,当然也可以通过yum或者rpm安装):
1.安装pip命令`$ sudo easy_install pip` 2.建议使用执行python -m pip install -U pip setuptools进行升级 3.执行安装tensorflow命令:pip install --upgrade tensorflow
-
代码注意事项:
1.java代码实例:
String response="需要穿进python中的代码"
FileUtil.writeToFile(new File("/home/admin/xxx.txt"), response);
String pythonPath = "/home/admin/python/usr/bin/python2.7";
String timelineScript = "/home/admin/aop-service/target/xxxx/BOOT-INF/classes/demo.py";//此处为代码被编译打包之后项目中python脚本被存放的位置,注意原文件应该在resource目录下。
String[] arguments = new String[]{pythonPath, timelineScript};
//通过python脚本来读取文件并将tensorflow执行timeline转化后重新写入data文件
Process exec = Runtime.getRuntime().exec(arguments);
StringBuilder resultAppend = new StringBuilder();
//等待脚本执行完成
exec.waitFor();
//用输入输出流来截取结果
BufferedReader bufferedReader = FileUtil.readFile("/home/admin/timelineData.txt", "UTF-8");
String lintTxt;
while ((lintTxt = bufferedReader.readLine()) != null) {
resultAppend.append(lintTxt);
}
2.python代码实例:
# -*- coding: utf-8 -*-
import collections
import tensorflow as tf
from google.protobuf import text_format
from tensorflow.python.client import timeline
import json
def analyze_step_stats(self, show_dataflow=True, show_memory=True):
self._allocate_pids()
self._assign_lanes()
self._analyze_tensors(show_memory)
self._show_compute(show_dataflow)
if show_memory:
self._show_memory_counters()
return StepStatsAnalysis(
chrome_trace=self._chrome_trace,
allocator_maximums=self._allocator_maximums)
def generate_chrome_trace_format(self, show_dataflow=True, show_memory=False):
"""Produces a trace in Chrome Trace Format.
Args:
show_dataflow: (Optional.) If True, add flow events to the trace
connecting producers and consumers of tensors.
show_memory: (Optional.) If True, add object snapshot events to the trace
showing the sizes and lifetimes of tensors.
Returns:
A JSON formatted string in Chrome Trace format.
"""
step_stats_analysis = self.analyze_step_stats(
show_dataflow=show_dataflow, show_memory=show_memory)
return step_stats_analysis.chrome_trace.format_to_string(pretty=True)
a = open('/home/admin/xxx.txt')
response = a.read()
a.close()
response = json.loads(response)
debug_info = response['xxx']
all_meta = []
for line in debug_info.split('\n'):
if not line.startswith("RUN_METADATA"):
continue
space = line.find(' ')
if space == -1:
continue
line = line[space + 1:]
all_meta.append(line)
if len(all_meta) == 0:
print ' '
else:
pb_meta = tf.RunMetadata()
line_number = 0
for record in all_meta:
part_meta = tf.RunMetadata()
text_format.Merge(record, part_meta)
for stat in part_meta.step_stats.dev_stats:
stat.device = str(line_number) + ':' + stat.device
pb_meta.MergeFrom(part_meta)
line_number += 1
tl = timeline.Timeline(pb_meta.step_stats)
ret = tl.generate_chrome_trace_format()
b = open('/home/admin/xxx.txt', 'w')
timelinedata = b.write(ret)
b.close()
class StepStatsAnalysis(collections.namedtuple(
'StepStatsAnalysis', ('chrome_trace', 'allocator_maximums'))):
"""Stores the step stats analysis output.
Parameters:
chrome_trace: A dict containing the chrome trace analysis.
allocator_maximums: A dict mapping allocator names to AllocationMaximum.
"""
pass
3.本人python代码基本功不太好,稍加评论不要见笑:
在python脚本中依然可以定义需要的函数供被执行的代码调用,但是注意java中利用Runtime调用python解释器时一定要选中对应已安装相关模板的解释器才可以,不然你不会看到任何错误信息但是代码缺却依然执行完成了。
只有单独通过python解释器执行py脚本才能看到python脚本是否完善,建议一定要先确保自己的python脚本没有问题
5. 当然你也可以通过不利用IO流读写的形式来传入参数和获取python脚本执行结果。可以通过另外一种方式将java端参数传给python脚本:
此处为借鉴
# encoding: utf-8
import sys
from selenium import webdriver
#a即为java传入的参数
def main(a):
driver = webdriver.Chrome() # 打开浏览器
driver.get(a) # 浏览器打开指定页面
if __name__ == '__main__':
for i in range(1, len(sys.argv)):
url = sys.argv[i]
main(url)
package com.taobao.recommendplatform.solutions.jiayu_test.aop;
import java.io.BufferedReader;
import java.io.InputStreamReader;
public class TestJavaCallPython {
public static void main(String[] args) {
try {
String url = "http://blog.csdn.net/thorny_v/article/details/61417386";
System.out.println("start;" + url);
//通过字符串数组的形式向python脚本传入参数,,第一位和第二位为oython解释器的路径和python 脚本路径,后面即为参数,可以随意传递多个参数。
String[] args1 = new String[]{"python", "/Users/morningrain/IdeaProjects/jcy_test/src/main/resources/demo.py", url};
Process pr = Runtime.getRuntime().exec(args1);
BufferedReader in = new BufferedReader(new InputStreamReader(
pr.getInputStream()));
String line;
while ((line = in.readLine()) != null) {
System.out.println(line);
}
in.close();
pr.waitFor();
System.out.println("end");
} catch (Exception e) {
e.printStackTrace();
}
}
}
- 注意使用第二种方式向python脚本传递参数时,当传入的参数过长时,首先可能会出现java编译问题,其次python解析器也可能无法取得过长的传递参数。