Android JNI之命名管道(FIFO/mkfifo)的使用(2)

场景描述:在JNI层使用mkfifo,并且读写数据,同时在Android Java层读写fifo数据。

Android Java层读写fifo数据,获取fifo路径后,new File能够成功,说明路径是对的,但是然后用各种Stream,都无法成功获得可用的流,进而无法继续操作。暂时的结论,Java层读写fifo数据比较有困难,new 各种Stream时会阻塞住出不来,有空了再试,可能的原因可以看完本文,可能与底层申请只读权限不会成功有关系。

先说说在JNI层使用mkfifo,首先,FIFO的路径怎么确定,不是随便给个路径就能mkfifo成功的,经过试验,路径可以这样确定,在ANDROID JAVA层写如下代码:

  String fifoName="my_test_fifo";     
  String seprator = File.separator;
  //get full fifo auto
  String dataDir=context.getApplicationInfo().dataDir;

  String fullFifoPath=dataDir+seprator+fifoName;//this is the full path you want!!!

获取到完整的FIFO路径(fullFifoPath)后,便可以通过JNI接口传入底层C/C++代码,底层利用这个完整的路径进行mkfifo,open,write,read等操作:

//fifo操作自己本身需要的几个头文件,其它需要的头文件自己看着加
#include <unistd.h>
#include <fcntl.h>
#include <sys/stat.h>

int fd_fifo;//fifo handle
char *fifoPath="your fifo path";//不要hard code,换成你自己的fifo路径
if (mkfifo(fifoPath, 0666)<0 && errno != EEXIST)
{
    //LOGI("can't create fifo ");
   return; 
}

//mkfifo success

fd_fifo=open(fifoPath, O_RDONLY | O_NONBLOCK);
if( fd_fifo<0)
{
   // LOGI("fd=%d,can't open fifoPath%s",fd_fifo,fifoPath);
   return;
}
else
{
   // LOGI("fd=%d,Success open fifoPath=%s",fd_fifo,fifoPath);
}

需要额外提醒大家一点的就是,在进行open操作的时候,关于权限问题,这是在ANDROID上调用底层代码特有的一个诡异的地方,还没找到具体的原因,大家注意一下就行了:

如果打开时权限参数为只写,会失败,如下代码:

 fd_fifo=open(fifoPath, O_WRONLY | O_NONBLOCK);

返回值fd_fifo会是-1,代表失败,如果把O_NONBLOCK去掉,则会一直阻塞住出不来。但是如果打开权限是可读写(O_RDWR)和只读(O_RDONLY)都会成功,同时,一个诡异的地方,一旦申请过O_RDWR,后面再用O_WRONLY就会成功了,下面是我依次以不同权限open的返回值结果:

2020-12-10 19:00:30.005 5327-5383/com.example.myapplication I/log_c: testfd_wo=-1 //O_WRONLY | O_NONBLOCK,失败
2020-12-10 19:00:30.005 5327-5383/com.example.myapplication I/log_c: testfd_wr=94//O_RDWR | O_NONBLOCK,成功
2020-12-10 19:00:30.005 5327-5383/com.example.myapplication I/log_c: testfd_ro=95//O_RDONLY | O_NONBLOCK,成功
2020-12-10 19:00:30.005 5327-5383/com.example.myapplication I/log_c: testfd_w=96//O_WRONLY | O_NONBLOCK,成功,因为前面以O_RDWR的权限open过,所以这里成功了!

呼应文章开头,JAVA层new各种stream会阻塞住出不来的现象,暂时能得到的原因是:java里面new stream的时候默认是以阻塞方式去new 的,虽然路径存在,但是申请不到,就一直阻塞住。

至于为什么会申请不到,有可能是没有以读写权限申请过,恰好我申请的时候申请的是各种OutStream类,是write权限。可能的解决办法:在底层以读写权限先open一下,或者在java层new 有读写权限的Stream。有空了我再试一下,大家如果有兴趣也可以尝试以下,有结果了可以告诉我,互相交流。

  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值