1

我目前正在开发一个使用 Android 的VpnService. 在性能测试期间,我发现FileInputStream我在FileDescriptor返回的establish()方法上创建的读取速度很慢。我的工作代码片段如下所示。

private val vpnIf0 = FileInputStream(fd)

suspend fun readVpnIf0(): IPDatagram = withContext(Dispatchers.IO) {
    val bytes = ByteArray(BUFFER_SIZE)
    val count = vpnIf0.read(bytes)
    return@withContext IPMarshaller.marshal(bytes, count)
}

为了优化代码,我进行了如下封装FileInputStreamBufferedInputStream保持其他所有内容相同。

private val vpnIf0 = BufferedInputStream(FileInputStream(fd))

但是现在我的读取方法已经停止工作,这是我得到的错误。

Caught java.io.IOException: Invalid argument
        at java.io.FileInputStream.available0(Native Method)
        at java.io.FileInputStream.available(FileInputStream.java:389)
        at java.io.BufferedInputStream.read(BufferedInputStream.java:355)
        at java.io.FilterInputStream.read(FilterInputStream.java:107)

.txt只是为了确保我没有做任何不正确的事情,我尝试了使用文件和 a完全相同的读取方法,BufferedInputStream它就像一个魅力。在进一步检查FileInputStream实现后,我在方法附近看到了一些注释available(),如下所示。在我看来,Android 使用的版本似乎比标准 JDK 稍有修改。

// BEGIN Android-changed: available() implementation changed from bare native.
public int available() throws IOException {
    // Android-added: close() check before I/O.
    if (closed) {
        throw new IOException("Stream Closed");
    }

    return available0();
}

private native int available0() throws IOException;
// END Android-changed: available() implementation changed from bare native.

注意:我拥有的用例在 Android 世界中是一个BufferedInputStream过大的用例。这里,是一个虚拟网络接口。FileInputStreamFileDescriptorFileDescriptor/dev/tun0

问题:

  1. 我的理解是否存在差距,根本不可能将 a 包裹BufferedInputStream在 a上?FileDescriptor我还没有在 JVM 上尝试过同样的方法。
  2. 或者这是 Android 特有的细微差别?在这种情况下,如何克服这个问题并确保缓冲读取。

任何帮助深表感谢!

4

0 回答 0