繁体   English   中英

不太了解InputStream.read(byte [],int,int)的工作方式

[英]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,则将从offsetoffset + x-1的数组元素定义在数组中(除非返回-1,这表示EOF)。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM