【问题标题】:Converting InputStream to MappedByteBuffer in java?在 java 中将 InputStream 转换为 MappedByteBuffer?
【发布时间】:2013-10-27 08:22:06
【问题描述】:

我正在尝试创建一个安卓应用。

我使用InputStream inputStream=getAssets().open("book.txt"); 阅读book.txt ;

我只想从 InputStream 中获取 MappedByteBuffer 对象;

谁知道?

====================

我使用FileInputStream fis = (FileInputStream) inputStream; 导致错误! 这是错误日志:

10-27 10:45:55.830: D/dalvikvm(9243): GC_EXTERNAL_ALLOC 释放 22K, 53% 释放 2577K/5379K, 外部 1916K/2428K, 暂停 62ms 10-27 10:45:55.940: D/dalvikvm(9243): GC_EXTERNAL_ALLOC 释放 2K,53% 释放 2577K/5379K,外部 2516K/2516K,暂停 69ms 10-27 10:45:56.230: I/fileName(9243): sahala.txt 10-27 10:45:56.240: D/szipinf(9243): 初始化充气状态 10-27 10:45:56.240: D/AndroidRuntime(9243): 关闭虚拟机 10-27 10:45:56.240: W/dalvikvm(9243): threadid=1: 线程以未捕获的异常退出 (group=0x40015560) 10-27 10:45:56.260: E/AndroidRuntime(9243): 致命异常: main 10-27 10:45:56.260: E/AndroidRuntime(9243): java.lang.RuntimeException: 无法启动活动 ComponentInfo{com.silenceper.bookdemo/com.silenceper.book.shl.activity.ReadBookActivity}: java.lang .ClassCastException: android.content.res.AssetManager$AssetInputStream 10-27 10:45:56.260: E/AndroidRuntime(9243): 在 android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1647) 10-27 10:45:56.260: E/AndroidRuntime(9243): 在 android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1663) 10-27 10:45:56.260: E/AndroidRuntime(9243): 在 android.app.ActivityThread.access$1500(ActivityThread.java:117) 10-27 10:45:56.260: E/AndroidRuntime(9243): 在 android.app.ActivityThread$H.handleMessage(ActivityThread.java:931) 10-27 10:45:56.260: E/AndroidRuntime(9243): 在 android.os.Handler.dispatchMessage(Handler.java:99) 10-27 10:45:56.260: E/AndroidRuntime(9243): 在 android.os.Looper.loop(Looper.java:123) 10-27 10:45:56.260: E/AndroidRuntime(9243): 在 android.app.ActivityThread.main(ActivityThread.java:3683) 10-27 10:45:56.260: E/AndroidRuntime(9243): 在 java.lang.reflect.Method.invokeNative(Native Method) 10-27 10:45:56.260: E/AndroidRuntime(9243): 在 java.lang.reflect.Method.invoke(Method.java:507) 10-27 10:45:56.260: E/AndroidRuntime(9243): 在 com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:839) 10-27 10:45:56.260: E/AndroidRuntime(9243): 在 com.android.internal.os.ZygoteInit.main(ZygoteInit.java:597) 10-27 10:45:56.260: E/AndroidRuntime(9243): at dalvik.system.NativeStart.main(Native Method) 10-27 10:45:56.260: E/AndroidRuntime(9243): 原因: java.lang.ClassCastException: android.content.res.AssetManager$AssetInputStream 10-27 10:45:56.260: E/AndroidRuntime(9243): at com.silenceper.book.shl.utils.BookPageFactory.openBookFromInputStream(BookPageFactory.java:83) 10-27 10:45:56.260: E/AndroidRuntime(9243): 在 com.silenceper.book.shl.activity.ReadBookActivity.initBookData(ReadBookActivity.java:71) 10-27 10:45:56.260: E/AndroidRuntime(9243): at com.silenceper.book.shl.activity.ReadBookActivity.onCreate(ReadBookActivity.java:58) 10-27 10:45:56.260: E/AndroidRuntime(9243): 在 android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047) 10-27 10:45:56.260: E/AndroidRuntime(9243): 在 android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1611) 10-27 10:45:56.260: E/AndroidRuntime(9243): ... 11 更多

【问题讨论】:

    标签: java android


    【解决方案1】:

    我也有类似的需要这样做。这是我所做的:
    1) 使用资产管理器打开资源文件并将常规文件写入 /data/data/com.yourpackage/files 目录。示例代码:

    private void prepareModelFile() throws IOException {
            AssetManager assetManager = getAssets();
            String configDir = getFilesDir().getAbsolutePath();
            InputStream stream = assetManager.open("mytestfile_in_assets.data");
            mTFLiteModelFile = configDir +"/mytestfilename.data";
                OutputStream output = new BufferedOutputStream(new FileOutputStream(mTFLiteModelFile));
                copyFile(stream, output);
        }
    
    public static void copyFile(InputStream in, OutputStream out) throws IOException {
        byte[] buffer = new byte[1024];
        int read;
        while((read = in.read(buffer)) != -1) {
            out.write(buffer, 0, read);
        }
        in.close();;
        out.close();
    }
    

    2) 现在您已经将文件从资产中复制了出来,您可以使用以下方式创建一个 MappedByteBuffer。示例:

            FileInputStream inputStream = new FileInputStream(mTFLiteModelFile);
            FileChannel fileChannel = inputStream.getChannel();
            MappedByteBuffer myMappedBuffer =  fileChannel.map(FileChannel.MapMode.READ_ONLY, 0, fileChannel.size());
    

    希望这会有所帮助。

    大卫

    【讨论】:

      【解决方案2】:

      更新

      为此,您需要先将资产复制到文件中,然后将以下技术应用到文件中。如果您的资产超过 1MB,则需要拆分它 - Load files bigger than 1M from assets folder


      您不能使用InputStream 执行此操作。你应该为你的book.txt 获取一个FileInputStream 或转换你的inputStream,然后从中获取一个FileChannel

      try {
          FileInputStream fis = (FileInputStream) inputStream;
          FileChannel channel = fis.getChannel();
          ByteBuffer buffer = channel.map(FileChannel.MapMode.READ_ONLY, 0, channel.size());
      
          byte[] bytes = new byte[102];
          buffer.get(bytes);
          System.out.println(new String(bytes));
      } catch (IOException e) {
          e.printStackTrace();
      }
      

      【讨论】:

      • 假设 InputStream 可以转换为 FileInputStream。
      • 是的,我希望这不是 @silenceper 试图映射的数据库资产。
      • 代码fis = (FileInputStream) inputStream; 导致错误
      • 您可以将堆栈跟踪添加到您的帖子中吗?
      • 更新了答案 - 您需要先将资产复制到文件中。
      【解决方案3】:

      你不能这样做,原因有很多,其中大部分都暗示这个问题没有意义。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2020-08-13
        • 2021-04-08
        • 2019-11-04
        • 2011-12-26
        • 2010-11-18
        相关资源
        最近更新 更多