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()的阻塞问题。