简体   繁体   English

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

[英]Don't quite understand how InputStream.read( byte[], int, int ) works

I know this is trivial, but it doesn't make sense to me. 我知道这很简单,但是对我来说这没有意义。 Java can't pass pointers/references as parameters, yet the read() function is passed a buffer into which the data is read , and only returns an int as the total number of bytes read into the buffer . Java无法将指针/引用作为参数传递,但是read()函数传递了一个buffer into which the data is read ,并且仅返回int作为the total number of bytes read into the buffer

I am expecting to read five separate bytes from this device, but when I pass the function a buffer, and try to access it afterwards it continues to be null . 我期望从此设备读取五个单独的字节,但是当我将函数传递给缓冲区时,然后尝试对其进行访问后,该缓冲区仍为null If I print out the return value from the function it gives me the int 5 , which is expected. 如果我从函数中打印出返回值,它将得到预期的int 5 But how can I access the data which was actually put into the buffer? 但是,如何访问实际放入缓冲区的数据?

Here is a link to the JavaDocs .... 这是指向JavaDocs的链接。

EDIT: 编辑:

This is the original call to the read function. 这是对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 );
    }
}

Note, this read function is a function declared in my class called BluetoothService. 请注意,此读取函数是在我的类BluetoothService中声明的函数。 This class contains another class called ConnectedThread, which calls the InputStream read... 此类包含另一个名为ConnectedThread的类,该类将InputStream读取为...

Here is MY read function.... 这是我的阅读功能。

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;

}

And here is the ConnectedThread class, which calls read itself.... 这是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 can't pass pointers/references as parameters Java无法将指针/引用作为参数传递

Yes it can. 是的,它可以。

A fundamental misconception like this would leave you very confused ... 这样一个基本的误解离开你很迷茫......

The way that read(...) is supposed to be used is like this: 应该使用read(...)的方式是这样的:

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

You allocate a buffer object and pass it as a parameter to the read method. 您分配一个缓冲区对象,并将其作为参数传递给read方法。 Bytes are read and copied into the buffer starting at (in this case) offset zero. 读取字节并将其复制到缓冲区(从本例开始)从零偏移开始。 When the method call returns, it returns the number of bytes actually read ... and the bytes are in the buffer ready for the caller to process. 当方法调用返回时,它返回实际读取的字节数...,并且这些字节在缓冲区中,可供调用者处理。

As you can see, this relies on passing a byte array reference as a parameter to the read method. 如您所见,这依赖于将字节数组引用作为参数传递给read方法。

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

Perhaps you have a C background that confused you on making the call to read() appropriate. 也许您的C背景使您对read()的调用变得困惑。 Instead of returning an array or creating one using a pointer to a pointer, read(byte[]) and read(byte[] b, int offset, int len) expect an actual byte array (in the latter form, of size bigger or equal to offset+len) in the argument list. read(byte [])和read(byte [] b,int offset,int len)不会返回数组或使用指向指针的指针来创建一个数组,而是期望一个实际的字节数组(后一种形式,其大小更大或更大)。等于参数列表中的offset + len)。 Assuming the value x is returned from the method, the array elements from offset to offset+x-1 will be defined in the array (unless -1 was returned, which indicates an EOF). 假设从方法返回值x,则将从offsetoffset + x-1的数组元素定义在数组中(除非返回-1,这表示EOF)。

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

相关问题 Java InputStream.read(byte [],int,int)方法,如何阻塞,直到读取了确切的字节数 - Java InputStream.read(byte[], int, int) method, how to block until the exact number of bytes has been read JAVA:InputStream.read(byte [] b,int off,int len)中的字节数组分配 - JAVA: Byte array allocation in InputStream.read(byte[] b, int off, int len) InputStream.read() 返回的 int 值代表什么? - What does an int value returned by InputStream.read() represent? InputStream.read(byte)方法如何工作? - How could InputStream.read(byte) method ever work? InputStream.read(byte[]) 返回的 0 是什么意思? 如何处理? - What 0 returned by InputStream.read(byte[]) means? How to handle this? 如何通过java中InputStream中的read函数读取一个字节并将其作为int返回? - How is one byte read and returned as an int by read function in InputStream in java? InputStream.read(byte [],0 length)提前停止? - InputStream.read(byte[], 0 length) stops early? 间谍 InputStream.read(byte[] buffer) - Spy InputStream.read(byte[] buffer) 在Java中,使用从InputStream.read()返回的int调用Character.isXxx()方法是否安全? - In Java, is it safe to call Character.isXxx() methods with an int returned from InputStream.read()? 如何设置InputStream.read的读取超时? - How to set the read timeout for InputStream.read?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM