Java 创建内存中的FileDescriptor

Java 创建内存中的FileDescriptor,java,android,file-descriptor,bytearrayoutputstream,bytearrayinputstream,Java,Android,File Descriptor,Bytearrayoutputstream,Bytearrayinputstream,Android中的API表示: 文件描述符类的实例用作 表示打开文件的基础计算机特定结构, 一个开放的套接字,或另一个字节的源或接收器 我想使用和创建FileDescriptor对象 另外,FileDescriptor是最后一个类,不能被重写。它唯一的构造师说- 构造一个(无效)文件描述符对象 知道如何在Android中使用FileDescriptor吗 编辑 我想把它用在汽车上。我希望将媒体数据存储在内存中,并将其复制到TCP套接字以进行实时流媒体传输,而不是写入文件。因此,我的文件描述符应该

Android中的API表示:

文件描述符类的实例用作 表示打开文件的基础计算机特定结构, 一个开放的套接字,或另一个字节的源或接收器

我想使用和创建FileDescriptor对象

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

构造一个(无效)文件描述符对象

知道如何在Android中使用FileDescriptor吗

编辑


我想把它用在汽车上。我希望将媒体数据存储在内存中,并将其复制到TCP套接字以进行实时流媒体传输,而不是写入文件。因此,我的文件描述符应该是“字节汇”。

您可以将System.out重定向到ByteArrayOutputStream 并使用FileDescriptor.out作为FileDescriptor

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()));

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

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

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

//为套接字创建唯一的名称。
String name=“your.package.name-”+UUID.randomUUID();
//将服务器绑定到套接字。
最终LocalServerSocket服务器=新的LocalServerSocket(名称);
//将客户端连接到套接字。
LocalSocket客户端=新的LocalSocket(LocalSocket.SOCKET\u流);
connect(新的LocalSocketAddress(名称,LocalSocketAddress.Namespace.ABSTRACT));
//启动一个线程以从服务器套接字读取。
新线程(新的可运行线程){
@凌驾
公开募捐{
LocalSocket=server.accept();
//要读取客户端发送的数据,请从socket.getInputStream()读取。
//要向客户端发送数据,请写入socket.getOutputStream()。
//完成后,需要调用socket.close()。
}
}).start();
//获取与客户端关联的FileDescriptor。
//您可以使用此FileDescriptor将数据写入和/或读取数据
//从服务器发送。
FileDescriptor FileDescriptor=client.getFileDescriptor();
//完成后,需要调用server.close()和client.close()。
这将在抽象套接字命名空间中创建套接字。这是不安全的,因为域套接字是系统范围的,抽象命名空间中的套接字不受任何权限系统的限制。连接或绑定到抽象命名空间中的名称的唯一要求是知道名称,并且攻击者可以通过反编译轻松发现应用程序使用的套接字名称。另一个应用程序也有可能意外使用相同的套接字名称。因此,另一个应用程序可能会截获您的数据,或通过套接字发送意外数据,这很难防范

更好但更复杂的解决方案是在文件系统名称空间中创建套接字。实现这一点的API非常奇怪,但可以通过以下方式实现:

//在应用程序的私有数据区域中为套接字创建唯一名称。
//注意:此示例在的根目录中创建一个名为socket xxxx的文件
//你的应用程序的私有数据区域。您可能希望将其放在子目录中。
字符串名称=上下文
.getFileStreamPath(“套接字-”+UUID.randomUUID())
.getAbsolutePath();
LocalSocketAddress address=新的LocalSocketAddress(名称,LocalSocketAddress.Namespace.FILESYSTEM);
//将服务器绑定到套接字。
LocalSocket服务器=新的LocalSocket(LocalSocket.SOCKET\u流);
服务器绑定(地址);
final LocalServerSocket serverWrapper=新的LocalServerSocket(server.getFileDescriptor());
//将客户端连接到套接字。
LocalSocket客户端=新的LocalSocket(LocalSocket.SOCKET\u流);
client.connect(地址);
//启动一个线程以从服务器套接字读取。
新线程(新的可运行线程){
@凌驾
公开募捐{
LocalSocket-socket=serverWrapper.accept();
//要读取客户端发送的数据,请从socket.getInputStream()读取。
//要向客户端发送数据,请写入socket.getOutputStream()。
//完成后,需要调用socket.close()和
//serverWrapper.close()。
}
}).start();
//获取与客户端关联的FileDescriptor。
//您可以使用此FileDescriptor将数据写入和/或读取数据
//从服务器发送。
FileDescriptor FileDescriptor=client.getFileDescriptor();
//完成后,需要调用server.close()和client.close()。
这确实会在文件系统上创建一个文件,但通过套接字的所有数据都不会写入磁盘,而是完全在内存中。该文件只是一个表示套接字的名称,类似于
/dev
中表示设备的文件。由于套接字是通过文件系统访问的,因此它受通常的文件系统权限的约束,因此很容易通过将套接字放置在应用程序的私有数据区域来限制对套接字的访问


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

您想从哪里返回
文件描述符
?从
ContentProvider
?使用
ParcelFileDescriptor.createPipe()
和kin,尽管我不确定它是否能满足您的要求。我想在
MediaMuxer(FileDescriptor fd,int格式)中使用它
这样我就可以将字节写入TCP套接字的输出流,而无需将数据写入文件。然后使用
ParcelFileDescriptor#fromSocket()
方法#fromSocket()对我不起作用<代码>E/MPEG4Writer:无法查找mFd:非法查找(29)47
无法查找TCP套接字的输出流。这么好看