gpt4 book ai didi

java - 创建内存中的 FileDescriptor

转载 作者:行者123 更新时间:2023-11-29 02:36:15 26 4
gpt4 key购买 nike

FileDescriptor Android 中的 API 说:

Instances of the file descriptor class serve as an opaque handle to the underlying machine-specific structure representing an open file, an open socket, or another source or sink of bytes.

我想使用 ByteArrayOutputStream 创建一个 FileDescriptor 对象和 ByteArrayInputStream

此外,FileDescriptor 是最终类,不能被覆盖。它唯一的构造函数说 -

Constructs an (invalid) FileDescriptor object.

知道如何在 Android 中使用 FileDescriptor 吗?

编辑

我想在 MediaMuxer 中使用它.我不想写入文件,而是希望将媒体数据存入内存并将其复制到 TCP 套接字以进行实时流式传输。所以我的 FileDescriptor 应该是一个“字节汇”。

最佳答案

使用 LocalSocket,但要小心,因为存在安全隐患。

LocalSocket 是用于处理 Unix 域套接字的 Android API。域套接字类似于 TCP/IP 套接字,只是它们仅存在于设备上,不能用于跨网络通信。

针对您的问题的一个简单但不安全的解决方案如下:

// Create a unique name for the socket.
String name = "your.package.name-" + UUID.randomUUID();

// Bind a server to the socket.
final LocalServerSocket server = new LocalServerSocket(name);

// Connect a client to the socket.
LocalSocket client = new LocalSocket(LocalSocket.SOCKET_STREAM);
client.connect(new LocalSocketAddress(name, LocalSocketAddress.Namespace.ABSTRACT));

// Start a thread to read from the server socket.
new Thread(new Runnable {
@Override
public void run() {
LocalSocket socket = server.accept();

// To read data sent by the client, read from socket.getInputStream().
// To send data to the client, write to socket.getOutputStream().

// After you are done you will need to call socket.close().
}
}).start();

// Get the FileDescriptor associated with the client.
// You can use this FileDescriptor to write data to and/or read data
// sent from the server.
FileDescriptor fileDescriptor = client.getFileDescriptor();

// After you are done you will need to call server.close() and client.close().

这会在抽象套接字命名空间中创建一个套接字。这是不安全的,因为域套接字是系统范围的,抽象命名空间中的套接字不受任何权限系统的限制。连接或绑定(bind)到抽象命名空间中的名称的唯一要求是知道该名称,并且您的应用程序使用的套接字名称很容易被攻击者通过反编译发现。另一个应用程序也有可能意外使用相同的套接字名称。因此另一个应用程序可能会拦截您的数据,或通过套接字发送意外数据,并且很难防范这种情况。

更好但更复杂的解决方案是在文件系统命名空间中创建套接字。执行此操作的 API 非常奇怪,但可以按如下方式实现:

// Create a unique name for the socket in your app's private data area.
// Note this example creates a file named like socket-xxxx in the root of
// your app's private data area. You might want to put it in a subdirectory.
String name = context
.getFileStreamPath("socket-" + UUID.randomUUID())
.getAbsolutePath();
LocalSocketAddress address = new LocalSocketAddress(name, LocalSocketAddress.Namespace.FILESYSTEM);

// Bind a server to the socket.
LocalSocket server = new LocalSocket(LocalSocket.SOCKET_STREAM);
server.bind(address);
final LocalServerSocket serverWrapper = new LocalServerSocket(server.getFileDescriptor());

// Connect a client to the socket.
LocalSocket client = new LocalSocket(LocalSocket.SOCKET_STREAM);
client.connect(address);

// Start a thread to read from the server socket.
new Thread(new Runnable {
@Override
public void run() {
LocalSocket socket = serverWrapper.accept();

// To read data sent by the client, read from socket.getInputStream().
// To send data to the client, write to socket.getOutputStream().

// After you are done you will need to call socket.close() and
// serverWrapper.close().
}
}).start();

// Get the FileDescriptor associated with the client.
// You can use this FileDescriptor to write data to and/or read data
// sent from the server.
FileDescriptor fileDescriptor = client.getFileDescriptor();

// After you are done you will need to call server.close() and client.close().

这确实在文件系统上创建了一个文件,但是通过套接字的数据都没有写入磁盘,它完全在内存中。该文件只是一个代表套接字的名称,类似于 /dev 中代表设备的文件。因为套接字是通过文件系统访问的,所以它受制于通常的文件系统权限,所以通过将套接字放在应用程序的私有(private)数据区域中可以很容易地限制对套接字的访问。

由于此技术会在文件系统上创建一个文件,因此最好在完成后删除该文件,并且还可以经常检查并清理旧套接字,以防您的应用程序崩溃并留下旧文件。

关于java - 创建内存中的 FileDescriptor,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46917506/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com