Android USB通讯中FileInputStream函数available()无法使用时,read()阻塞的解决

3 篇文章 0 订阅
1 篇文章 0 订阅

available()无法使用

在进行USB UsbAccessory 转RS232通讯时使用

UsbManager usbmanager = (UsbManager) (context.getSystemService(Context.USB_SERVICE));
if(usbAccessory==null)return false;
parcelFileDescriptor = usbmanager.openAccessory(usbAccessory);
if(parcelFileDescriptor==null)return false;
FileDescriptor fileDescriptor = parcelFileDescriptor.getFileDescriptor();
inputStream = new FileInputStream(fileDescriptor);
outputStream = new FileOutputStream(fileDescriptor);

try {
    int a = inputStream.available();
} catch (IOException e) {
    e.printStackTrace();
}

在运行

int a = inputStream.available();

时,出现异常,如下图。

未找到原因以及直接解决方案,于是考虑对read()函数的阻塞问题进行变通处理。

想到两种方法,其一是:使用FileReader类。

 
UsbManager usbmanager = (UsbManager) (context.getSystemService(Context.USB_SERVICE));
if(usbAccessory==null)return false;
parcelFileDescriptor = usbmanager.openAccessory(usbAccessory);
if(parcelFileDescriptor==null)return false;
FileDescriptor fileDescriptor = parcelFileDescriptor.getFileDescriptor();
outputStream = new FileOutputStream(fileDescriptor);

fileReader = new FileReader(fileDescriptor);
 
final char[] ch = new char[5];
new Thread(new Runnable() {
    @Override
    public void run() {
        while (true) {
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            int len = 0;
            try {
                len = fileReader.read(ch);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}).start();
但是又出现问题,这个方法的 read()函数也是类似阻塞的,要将数组读满才行。

另一种方法是:自己做一个缓存。

public class FIFOStack {
    /** 存储区域 */
    private static byte[] data;
    /** 最大存储量 */
    private static int maxSize;
    /**已有数据个数*/
    private static int top;

    private static boolean isPush=false;
    private static boolean isRead=false;

    public FIFOStack(int maxSize) {
        FIFOStack.maxSize = maxSize;
        FIFOStack.data = new byte[maxSize];
        top = 0;
    }

    /**
     * 将数据放入堆栈
     * @param buff
     * @return
     */
    public boolean push(byte[] buff,int len) {
        if(data==null) return true;
        while(isRead) try {
            Thread.sleep(1);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        if(top+len>maxSize) return false;
        isPush = true;
        System.arraycopy(buff, 0, data, top, len);
        top+=len;
        isPush = false;
        return true;
    }

    /**
     *将数据取出堆栈
     * @return
     * @throws Exception
     */
    public int read(byte[] buff) throws Exception {
        while(isPush)Thread.sleep(1);
        if(top==0)return 0;
        if(buff==null)return 0;
        isRead=true;
        if(top<=buff.length){
            System.arraycopy(data, 0, buff, 0, top);
            int len = top;
            top=0;
            isRead=false;
            return len;
        }else{
            System.arraycopy(data, 0, buff, 0, buff.length);
            byte[] mid = Arrays.copyOfRange(data,buff.length,top);
            top-=buff.length;
            System.arraycopy(mid, 0, data, 0, mid.length);
            isRead=false;
            return buff.length;
        }
    }
}
 
final byte[] buff = new byte[500];
final FIFOStack fifoStack = new FIFOStack(65535);
new Thread(new Runnable() {
 @Override
 public void run() {
  int num=0,len=0;
  byte[] cmdRecv = null;
  while (true) {
   try {
    num = fileInputStream.read(buff);
    fifoStack.push(buff,num);
    num=0;
   } catch (IOException e) {
    e.printStackTrace();
   }
  }
 }
}).start();

new Thread(new Runnable() {
 @Override
 public void run() {
  int len=0;
  while (true) {
   try {
    byte[] readBuff=new byte[30];
    len=fifoStack.read(readBuff);
    if(len>0)ToastUtils.showToastHandler(Arrays.toString(readBuff));
   } catch (Exception e) {
    e.printStackTrace();
   }
  }
 }
}).start();


用此方法完美解决 available()无法使用时 read()的阻塞问题。


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值