[英]Java InputStream.read(byte[], int, int) method, how to block until the exact number of bytes has been read
[英]Don't quite understand how InputStream.read( byte[], int, int ) works
我知道这很简单,但是对我来说这没有意义。 Java无法将指针/引用作为参数传递,但是read()函数传递了一个buffer into which the data is read
,并且仅返回int作为the total number of bytes read into the buffer
。
我期望从此设备读取五个单独的字节,但是当我将函数传递给缓冲区时,然后尝试对其进行访问后,该缓冲区仍为null
。 如果我从函数中打印出返回值,它将得到预期的int 5
。 但是,如何访问实际放入缓冲区的数据?
这是指向JavaDocs的链接。
编辑:
这是对read函数的原始调用。
public boolean onOptionsItemSelected( MenuItem item ) {
switch( item.getItemId() ) {
case R.id.connect:
startActivityForResult( new Intent( this, DeviceList.class ), 1 );
return true;
case R.id.readTest:
Log.i(TAG, "Before write." );
byte[] b = {'$'};
for( int i = 0 ; i < 3 ; i++ ) {
mService.write( b );
}
Log.i(TAG, "After write." );
return true;
case R.id.readData:
byte[] c = mService.read( 5 );
Toast.makeText(this, Integer.toString( mService.bytes ), Toast.LENGTH_LONG).show();
default:
return super.onContextItemSelected( item );
}
}
请注意,此读取函数是在我的类BluetoothService中声明的函数。 此类包含另一个名为ConnectedThread的类,该类将InputStream读取为...
这是我的阅读功能。
public byte[] read( int length ) {
Log.i( TAG, "Inside read." );
ConnectedThread r;
buffer = null;
synchronized( this ) {
if( mState != STATE_CONNECTED ) return null;
r = mConnectedThread;
}
Log.i(TAG, "Before run." );
r.run( length );
Log.i( TAG, "After run." );
Log.i( TAG, Integer.toString( bytes ) );
return buffer;
}
这是ConnectedThread类,它调用读取自身。
/**
* This thread runs during a connection with a remote device.
* It handles all incoming and outgoing transmissions.
*/
private class ConnectedThread extends Thread {
private final BluetoothSocket mmSocket;
private final InputStream mmInStream;
private final OutputStream mmOutStream;
public ConnectedThread(BluetoothSocket socket, String socketType) {
Log.d(TAG, "create ConnectedThread: " + socketType);
mmSocket = socket;
InputStream tmpIn = null;
OutputStream tmpOut = null;
// Get the BluetoothSocket input and output streams
try {
tmpIn = socket.getInputStream();
tmpOut = socket.getOutputStream();
} catch (IOException e) {
Log.e(TAG, "temp sockets not created", e);
}
mmInStream = tmpIn;
mmOutStream = tmpOut;
}
public void run(int length) {
Log.i(TAG, "BEGIN mConnectedThread");
byte[] buffer = new byte[1024];
// Keep listening to the InputStream while connected
//while (true) {
try {
// Read from the InputStream
bytes = mmInStream.read(buffer, 0, length);
// Send the obtained bytes to the UI Activity
mHandler.obtainMessage(MainMenu.MESSAGE_READ, bytes, -1, buffer)
.sendToTarget();
} catch (IOException e) {
Log.e(TAG, "disconnected", e);
connectionLost();
// Start the service over to restart listening mode
BluetoothService.this.start();
//break;
}
// }
Log.i(TAG, "MADE IT HERE" );
}
/**
* Write to the connected OutStream.
* @param buffer The bytes to write
*/
public void write(byte[] buffer) {
try {
mmOutStream.write(buffer);
// Share the sent message back to the UI Activity
mHandler.obtainMessage(MainMenu.MESSAGE_WRITE, -1, -1, buffer)
.sendToTarget();
} catch (IOException e) {
Log.e(TAG, "Exception during write", e);
}
}
public void cancel() {
try {
mmSocket.close();
} catch (IOException e) {
Log.e(TAG, "close() of connect socket failed", e);
}
}
}
Java无法将指针/引用作为参数传递
是的,它可以。
这样一个基本的误解会离开你很迷茫......
应该使用read(...)
的方式是这样的:
byte[] buffer = new byte[42];
int nosRead = is.read(buffer, 0, buffer.length);
您分配一个缓冲区对象,并将其作为参数传递给read
方法。 读取字节并将其复制到缓冲区(从本例开始)从零偏移开始。 当方法调用返回时,它返回实际读取的字节数...,并且这些字节在缓冲区中,可供调用者处理。
如您所见,这依赖于将字节数组引用作为参数传递给read
方法。
您必须初始化数组,否则它将继续保持为空。
也许您的C背景使您对read()的调用变得困惑。 read(byte [])和read(byte [] b,int offset,int len)不会返回数组或使用指向指针的指针来创建一个数组,而是期望一个实际的字节数组(后一种形式,其大小更大或更大)。等于参数列表中的offset + len)。 假设从方法返回值x,则将从offset到offset + x-1的数组元素定义在数组中(除非返回-1,这表示EOF)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.