首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >创建内存中的FileDescriptor

创建内存中的FileDescriptor
EN

Stack Overflow用户
提问于 2017-10-24 18:23:02
回答 2查看 2.5K关注 0票数 6

Android中的FileDescriptor API说:

文件描述符类的实例充当底层机器特定结构的不透明句柄,表示打开的文件、打开的套接字或另一个字节源或接收器。

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

另外,FileDescriptor是最后一个类,不能被重写。它唯一的构造函数是-

构造(无效) FileDescriptor对象。

你知道如何在安卓系统中使用FileDescriptor吗?

编辑

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

EN

回答 2

Stack Overflow用户

发布于 2020-06-30 05:45:10

使用LocalSocket,但要小心,因为存在安全问题。

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

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

代码语言:javascript
复制
// 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().

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

一个更好但更复杂的解决方案是在文件系统命名空间中创建一个套接字。这样做的API是非常奇怪的,但它可以实现如下:

代码语言:javascript
复制
// 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中表示设备的文件。因为套接字是通过文件系统访问的,因此它受制于通常的文件系统权限,因此很容易通过将套接字放置在应用程序的私有数据区域中来限制对套接字的访问。

由于这种技术在文件系统上创建了一个文件,所以在完成之后删除该文件是个好主意,也许还可以经常检查和清理旧套接字,以防应用程序崩溃并留下旧文件。

票数 1
EN

Stack Overflow用户

发布于 2018-07-09 08:34:39

您可以将System.out重定向到ByteArrayOutputStream,并使用FileDescriptor.out作为文件复制器。

代码语言:javascript
复制
ByteArrayOutputStream buff = new ByteArrayOutputStream();
PrintStream old = System.out;
System.setOut(new PrintStream(buff));

... use FileDescriptor.out ...

System.setOut(old);
System.out.println(new String(buff.toByteArray()));
票数 -1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/46917506

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档