创建内存中的 FileDescriptor

2024-02-13

文件描述符 https://developer.android.com/reference/java/io/FileDescriptor.htmlAndroid 中的 API 说:

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

我想使用创建一个 FileDescriptor 对象字节数组输出流 https://docs.oracle.com/javase/8/docs/api/java/io/ByteArrayOutputStream.html and 字节数组输入流 https://docs.oracle.com/javase/8/docs/api/java/io/ByteArrayInputStream.html

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

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

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

EDIT

我想用它媒体混合器 https://developer.android.com/reference/android/media/MediaMuxer.html#MediaMuxer(java.io.FileDescriptor,%20int)。我不想写入文件,而是希望将媒体数据保存在内存中并将其复制到 TCP 套接字以进行实时流传输。所以我的 FileDescriptor 应该是“字节接收器”。


Use a 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().

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

更好但更复杂的解决方案是在文件系统名称空间中创建套接字。执行此操作的 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代表设备。由于套接字是通过文件系统访问的,因此它受到通常的文件系统权限的约束,因此通过将套接字放置在应用程序的私有数据区域中可以轻松限制对套接字的访问。

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

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

创建内存中的 FileDescriptor 的相关文章

  • 如何更改 Swagger-ui URL 前缀?

    我正在使用 Springfox Swagger2 和 Spring boot 1 5 9 我可以通过此链接访问 swagger UI http localhost 8090 swagger ui html http localhost 80
  • 如何在 60 分钟后删除共享首选项

    我想存储登录数据 但希望在 60 分钟后删除该数据 执行此操作的正确方法是什么 在这 60 分钟内可以关闭 停止 打开应用程序 我不想使用内部数据库 这是我的访问代码SharedPreferences sharedpreferences g
  • Android - 状态栏阻止全屏

    我的应用程序启动时可以全屏正确运行 然而 在最小化然后返回应用程序后 状态栏会弹出 并将我的视图向下推一点 如何防止状态栏移动我的视图 这是我的布局
  • 如何自定义舍入形式

    我的问题可能看起来很简单 但仍然无法得到有效的东西 我需要自定义 Math round 舍入格式或其他格式以使其工作如下 如果数字是 1 6 他应该四舍五入到 1 如果大于或等于 1 7 他应该四舍五入到 2 0 对于所有其他带有 6 的小
  • Android Google Map V2:如何在单击另一个标记时更改先前单击的标记的图标

    更新 我通过添加 previousMarker 对象解决了性能问题 因此 只有先前单击的标记将被删除并替换为默认图标 但是 当我单击标记时 信息窗口仍然不显示 我有一个地图视图并在上面设置了一些标记 我想要的是 当我单击一个标记时 它将其图
  • 数据库中的持久日期不等于检索日期

    我有一个具有 Date 属性的简单实体类 此属性对应于 MySQL 日期时间列 Entity public class Entity Column name start date Temporal TemporalType TIMESTAM
  • 从三点求圆心的算法是什么?

    我在圆的圆周上有三个点 pt A A x A y pt B B x B y pt C C x C y 如何计算圆心 在Processing Java 中实现它 我找到了答案并实施了一个可行的解决方案 pt circleCenter pt A
  • 如何使用 Jersey 将嵌套列表封送为 JSON?我得到一个空数组或一个包含数组的单元素字典数组

    我正在开发一个使用 Jersey 将对象转换为 JSON 的项目 我希望能够写出嵌套列表 如下所示 data one two three a b c 我想要转换的对象首先将数据表示为 gt gt 我认为 Jersey 会做正确的事情 以上输
  • Lombok 不适用于 Eclipse Neon

    我下载了lombok jar lombok 1 16 14 jar 并将其放入我的下载中 然后我点击这个 jar 执行正确地识别了我的 MacOS 上的 Eclipse 实例 然后我选择了我想要的实例 Lombok也在pom xml中指定
  • 即使禁用安全性,OAuth 令牌 API 也无法在 Elastic Search 中工作

    我是 Elastic search 新手 使用 Elastic search 版本 7 7 1 我想通过以下方式生成 OAuth 令牌弹性搜索文档 https www elastic co guide en elasticsearch re
  • XML 配置中的 screenName 不起作用

    我刚刚在我的应用程序中添加了对 Google Analytics 分析 的支持 但我无法
  • 调试android数据绑定?

    谁能告诉我如何调试或找到数据绑定生成的代码 从this https www youtube com watch v NBbeQMOcnZ0链接我发现它生成了所需的代码 我猜您正在寻找自动生成的绑定 java 文件 我也在寻找他们 最后我在这
  • TabLayout 的不同 tabMode

    我正在使用 ViewPager 和 TabLayout 如果选项卡可以放置在显示 tabMode 上 则它们必须是 app tabMode fixed else app tabMode scrollable 我怎样才能做到这一点 我不明白你
  • Android:透明活动问题

    最近 在我们的一款生产应用程序上 透明活动已停止工作 我的意思是它变成了黑色背景而不是透明背景 当我将活动的背景颜色设置为纯色 即红色 绿色等 时 它的应用不会出现问题 该问题可能是由于迁移到 AndroidX 引起的 但我没有这方面的证据
  • 如何从DataSource.Factory获取数据

    我必须调用此方法才能获取所有人员 我根本无法修改这个方法 Query SELECT FROM PERSON TABLE ORDER BY NAME DESC abstract fun getElements DataSource Facto
  • 检测到 JVM 正在关闭

    我有一个使用 addShutdownHook 处理 Ctrl C 的 Swing 应用程序 它工作正常 直到我的关闭任务之一调用一个在正常情况下更改 JLabel 文本的函数 此时它挂起 我认为问题是 Swing EDT 已终止或正在等待某
  • 如何让 Firebase 与 Java 后端配合使用

    首先 如果这个问题过于抽象或不适合本网站 我想表示歉意 我真的不知道还能去哪里问 目前我已经在 iOS 和 Android 上开发了应用程序 他们将所有状态保存在 Firebase 中 因此所有内容都会立即保存到 Firebase 实时数据
  • Spring 作为 JNDI 提供者?

    我想使用 Spring 作为 JNDI 提供程序 这意味着我想在 Spring 上下文中配置一个 bean 可以通过 JNDI 访问该 bean 这看起来像这样
  • Android 的代码覆盖率[重复]

    这个问题在这里已经有答案了 可能的重复 Android测试代码覆盖率 Eclipse https stackoverflow com questions 3282702 android test code coverage eclipse
  • GAE 无法部署到 App Engine

    我正在尝试从 Eclipse 发布 Web 应用程序 我在 GAE 上创建了四个项目 可以通过登录我的帐户并查看控制台来查看它们 我已经改变了appengine web xml到项目的应用程序 ID 如果我将其更改为 GAE 上第一个创建的

随机推荐