一个在linux环境执行io操作的bug

今天项目有了一个奇葩的要求。。。是什么呢

后台上传了视频后,解析其中的时长,和预览图,并拼接在一起,然而,之东西并不是太麻烦,很快写好了,在本地测试后也没有问题,嗯,发布到测试环境后,一个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();//阻塞
 

原文地址:https://www.cnblogs.com/dmeck/p/9457120.html

时间: 08-10

一个在linux环境执行io操作的bug的相关文章

Linux 设备驱动IO操作

每个外设都是通过读写其寄存器来控制的.外设寄存器也称为I/O端口,通常包括:控制寄存器.状态寄存器和数据寄存器三大类. 根据CPU体系结构的不同,CPU对IO端口的编址方式有两种: (1)I/O映射方式(I/O-mapped) 典型地,如X86处理器将外设的寄存器看成一个独立的地址空间(称为"I/O地址空间"或者"I/O端口空间"),所以访问内存的指令不能用来访问这些寄存器,而要为对外设寄存器的读/写设置专用指令,如IN和OUT指令. (2)内存映射方式(Memor

深入理解JAVA I/O系列六:Linux中的IO模型

IO模型 linux系统IO分为内核准备数据和将数据从内核拷贝到用户空间两个阶段. 这张图大致描述了数据从外部磁盘向运行中程序的内存中移动的过程. 用户空间.内核空间 现在操作系统都是采用虚拟存储器,那么对32位操作系统而言,它的寻址空间(虚拟储存空间)为4G(2的32次方).操作系统的核心是内核,独立于普通的应用程序,可以访问受保护的内存空间,也有访问底层硬件设备的所有权限.为了保证用户进程不能直接操作内核,保证内核的安全,操作系统将虚拟空间划分为两个部分,一个部分为内核空间,一部分为用户空间

linux环境下(非UI操作)所有软件的安装与卸载总结

UI界面的软件管理 linux下的软件一般都是经过压缩的,主要的格式有这几种:rpm.tar.tar.gz.tgz等.所以首先拿到软件后第一件事就是解压缩. 在xwindow下以rpm格式的软件安装比较容易,只要在把鼠标移到文件上单击右键,在弹出的菜单里会有专门的三项(只有在右键单击rpm文件才会出现)show info,upgrade和install,这 三项的意思大家都很清楚了,我就不多说了. rpm格式说了,接着就是tar,tar.gz,tgz等,在xwindow下双击这些格式的文件就会自

Linux环境编程之文件I/O(七):目录文件及操作

什么是数据结构? 数据结构是相互之间存在一种或多种特定关系的数据元素的集合. 还有一些概念(数据.数据元素.数据项.数据对象.数据类型...) 传统上,我们把数据结构分为逻辑结构和物理结构. 逻辑结构:是指数据对象中数据元素之间的相互关系,也是我们今后最需要关注和讨论的问题. 物理结构:是指数据的逻辑结构在计算机中的存储形式. 逻辑结构分为以下四种: 1.集合:集合结构中的数据元素除了同属于一个集合外,之间没有任何关系. 2.线性结构:元素之间一对一. 3.树形结构:一对多. 4.图形结构:多对

【UNIX环境高级编程】文件 IO 操作 - 基础函数 open close creat lseek write read 详解

博客地址 : http://blog.csdn.net/shulianghan/article/details/46980271 一. 文件打开关闭操作相关函数介绍 1. open 函数 (1) open 函数简介 open 函数解析 : -- 函数定义 : #include <fcntl.h> int open(const char *path, int oflag, ...); -- 函数作用 : 打开或者创建一个文件; -- 返回值 : 打开文件成功, 返回文件描述符; 如果失败, 返回

如何在linux中执行一个脚本

---恢复内容开始--- 如何在LINUX中在系统启动时自动执行一个执行脚本 如果是开机马上执行的脚本,可以将脚本写到rc.local中: 如果是用户登录后自动执行脚本,可以将脚本写到相应的用户目录下"-/.bash_profile",若脚本"-/.bash_profile"不存在,可以直接拷贝"/etc/profile"命名为"-/.bash_profile": 如果是要任一用户登录后自动执行脚本,可以将脚本写到"

Linux环境下部署完JDK后运行一个简单的Java程序

前言 前一篇文章详细讲解了如何在Windows环境下安装虚拟机+Linux系统,并且成功部署了JDK. 不过部署完JDK之后,我们判断部署是否成功的依据是看"java -version"命令是否有正确的内容打印,也许这并不具备太大的说服力.可能能够运行起一个正确的java程序来,不管从感性角度还是理性角度来说,都会有一个更好的认识. 所以本文写一段很简单的java代码,并且在Linux环境下编译运行,以证明JDK部署得确实没有问题. 代码验证JDK部署是否正确 1.级联建立两个目录 首

linux环境中执行Mysql脚本

1.首先进入shell~ 2.进入服务器后,输入mysql -h localhost -u root -p,进入MySql: 3.输入MySql密码: 4.将脚本复制到服务器,具体怎么做,可以用Xftp; 5.例如,我执行的test.sql,在/usr/local/test.sql目录下,在shell中输入source /usr/local/test.sql linux环境中执行Mysql脚本,布布扣,bubuko.com

由一个简单需求到Linux环境下的syslog、unix domain socket

本文记录了因为一个简单的日志需求,继而对linux环境下syslog.rsyslog.unix domain socket的学习.本文关注使用层面,并不涉及rsyslog的实现原理,感兴趣的读者可以参考rsyslog官网.另外,本文实验的环境实在debian8,如果是其他linux发行版本或者debian的其他版本,可能会稍微有些差异. 需求: 工作中有一个在Linux(debian8)环境下运行的服务器程序,用python语言实现,代码中有不同优先级的日志需要记录,开发的时候都是使用pytho

linux 环境变量笔记及bash操作

$PATH 是环境变量中的一个较常用变量,不代表环境变量仅有$PATH 一个.查看环境变量可使用env 命令,不同用户的环境变量可以不同,一般也确实不同. 在bash 中执行.sh 文件,实质是生成一个新的子bash 程序.若要验证,可在.sh 文件中加入语句echo $$ ,$$ 即本程序的pid .会发现父bash 和子bash 显示的pid 不一致. 默认情况下,子进程只能继承父进程的环境变量,父进程的自定义变量 不能被子进程继承.如果想要继承,可以使用export 变量名 的方式.可通过