不太明白InputStream.read(byte [],int,int)是如何工作的

时间:2012-07-24 14:11:37

标签: java android inputstream

我知道这是微不足道的,但对我来说没有意义。 Java不能将指针/引用作为参数传递,但read()函数传递buffer into which the data is read,并且仅返回the total number of bytes read into the buffer的int。

我希望从这个设备中读取五个单独的字节,但是当我向函数传递一个缓冲区,然后尝试访问它时,它仍然是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 );
    }
}

注意,这个read函数是我的类中声明的一个名为BluetoothService的函数。该类包含另一个名为ConnectedThread的类,它调用InputStream read ...

这是我的阅读功能....

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类,它调用read本身....

/**
 * 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);
        }
    }
}

3 个答案:

答案 0 :(得分:3)

  

Java无法将指针/引用作为参数传递

是的,可以。

这样的基本误解会让你非常困惑......

应该使用read(...)的方式是这样的:

byte[] buffer = new byte[42];
int nosRead = is.read(buffer, 0, buffer.length);

您分配缓冲区对象并将其作为参数传递给read方法。从(在这种情况下)偏移零开始读取字节并将其复制到缓冲区中。当方法调用返回时,它返回实际读取的字节数...并且字节在缓冲区中,供调用者处理。

如您所见,依赖将字节数组引用作为参数传递给read方法。

答案 1 :(得分:2)

您必须初始化数组,否则它将继续保持为空。

答案 2 :(得分:1)

也许你有一个C背景让你对read()的调用感到困惑。 read(byte [])和read(byte [] b,int offset,int len)不是返回数组或使用指向指针创建数组,而是期望一个实际的字节数组(后一种形式,大小更大或者等于参数列表中的offset + len)。假设从方法返回值x,将在数组中定义从偏移偏移+ x-1 的数组元素(除非返回-1,表示一个EOF)。