一个在linux环境执行io操作的bug
2018-08-10 20:08
344 查看
今天项目有了一个奇葩的要求。。。是什么呢
后台上传了视频后,解析其中的时长,和预览图,并拼接在一起,然而,之东西并不是太麻烦,很快写好了,在本地测试后也没有问题,嗯,发布到测试环境后,一个jar包报错,看到这想想今天要加班了\/..\/
出现的错误是javacv解析视频后,一个jni错误/home/travis/build/javacpp-presets/opencv/cppbuild/linux-x86_64/opencv-3.4.2/modules/videostab/src/frame_source.cpp:71: error: (0:No Error) can't open file:
在git的lssues提交了一个问题后,很快有大佬跟我交流了,也就是基本说说,你怎么使用的,并没有解决我的问题
总不能晾着啊,所以苦逼的我,到ffmpeg官网下载了他们的源码,在linux编译了有半小时,总算完成了,在我 的window上同样装了一个环境,
下面是我的一个错误代码,在linux上获取一个视频的时长,嗯没问题,放到环境后,打印日志后什么都没有发生。。。。。。。。。。。
public static int getliunxFileLenth(String fileName) throws InterruptedException { String command = "ffmpeg -i "+fileName+" 2>&1 | grep 'Duration' | cut -d ' ' -f 4 | sed s/,//"; Runtime rt = Runtime.getRuntime(); InputStream inputStream = null; Process proc = null; String line = null; BufferedReader reader=null; try { proc = rt.exec(command); inputStream = proc.getInputStream(); reader = new BufferedReader(new InputStreamReader(inputStream)); while ((line = reader.readLine()) != null){ line = line; } } catch (IOException e) { e.printStackTrace(); }finally { try { inputStream.close(); reader.close(); } catch (IOException e) { e.printStackTrace(); } } return DateUtil.getSecond(line); }
先说下出现这种问题的原因是什么把,第一,ffmpeg使用异步io处理文件的,所以,
proc = rt.exec(command);这种方式只是给系统一个通知,,
第二,window与liunx不同的地方是,处处是阻塞,linux之所以能很好的完成大并发,靠的就是异步io,
而window之所以图形界面做的好,是因为,系统之间的阻塞通知,可以让系统运行在一个流程中。
解决的办法就是让通知阻塞我们的程序,
public static int getliunxFileLenth(String fileName) throws InterruptedException { List<String> commands = new ArrayList<>(); commands.add("ffmpeg"); commands.add("-i"); commands.add(fileName); try { ProcessBuilder builder = new ProcessBuilder(); int time = 0; builder.command(commands); Process p = builder.start(); //从输入流中读取视频信息 BufferedReader br = new BufferedReader(new InputStreamReader(p.getErrorStream())); StringBuilder stringBuilder = new StringBuilder(); String line = ""; while ((line = br.readLine()) != null) { stringBuilder.append(line); } p.waitFor();//阻塞 br.close(); //从视频信息中解析时长 String regexDuration = "Duration: (.*?), start: (.*?), bitrate: (\\d*) kb\\/s"; 。。。。。。。。。。。。
.waitFor();//阻塞
相关文章推荐
- 工作中遇到的一个相当有意思的问题(关于Windows和linux环境下执行PHP,ajax,javascript,flexigrid的一个莫名异常)
- 一次ORA-4030问题诊断及解决【解决思路不错,说明了对象的统计信息与优化器的优化操作(即选择执行一个SQL语句在该优化参数环境下最佳的执行计划)间的关系】
- [构思]设计&实现一个执行Excel的Import&Export操作的类
- 在IE关闭时,转到一个页面中,执行一些操作,然后关闭IE.
- "执行SQL语句时出现问题操作必须使用一个可更新的查询"错误的解决方法
- cygwin是一个在windows平台上运行的linux模拟环境
- 转贴:Linux 环境下多网卡使用一个IP提高效率--Bonding
- linux多线程使用siglongjmp打断io操作
- linux操作之:设置系统启动时,自动启动一些程序,或者执行一些命令
- linux_把可执行程序做成一个服务
- 执行SQL语句时出现问题操作必须使用一个可更新的查询错误的解决方法
- 配置一个完美的linux工作环境
- Linux环境中Oracle数据导入与导出备份操作
- 当鼠标N秒内无操作时执行一个操作(如:执行屏保、返回首页等)
- (原創) 如何让一个thread在背景不断的执行? (使用semaphore) (OS) (Linux) (C/C++) (C)
- 可供多线程调用的只能有一个在执行的原子操作实现
- 在Linux(红旗AdvanceServer4.1)执行oracle的imp操作报错的原因和解决的办法
- linux_把可执行程序做成一个服务
- 一个项目中使用到的通用函数库(3) 文件IO操作!
- 点击一个按钮后,它会根据不同的情况执行不同的操作,执行客户段的应用程序