【问题标题】:Load a file from assets folder in android studio从android studio中的assets文件夹加载文件
【发布时间】:2018-11-26 23:49:13
【问题描述】:

我想知道是否有一种方法可以访问我在 android studio 中的资产文件夹中的文件及其路径?我需要访问文件及其路径的原因是因为我正在使用一种需要文件的字符串路径的方法,并且它必须从其字符串路径访问文件。但是,在 android studio 中,我还没有找到直接从其路径的 String 值访问文件的方法。我决定使用一种解决方法,简单地从 InputStream 中读取文件并将文件写入 OutputStream,但是文件大约 170MB,并且将文件写入 OutputStream 太占用内存。当我实施该策略时,我的应用程序大约需要 10:00 分钟才能下载文件。我搜索了整个网站和众多资源以找到解决方案(书籍和文档),但无法找到可行的解决方案。这是我的代码示例:

@Override
public Model doInBackground(String... params){
        try {
            String filePath = context.getFilesDir() + File.separator + "my_turtle.ttl";
            File destinationFile = new File(filePath);
            FileOutputStream outputStream = new FileOutputStream(destinationFile);
            AssetManager assetManager = context.getAssets();
            InputStream inputStream = assetManager.open("sample_3.ttl");


            byte[] buffer = new byte[10000000];
            int length = 0;
            while ((length = inputStream.read(buffer)) != -1) {
                  outputStream.write(buffer, 0, length);
           }
            outputStream.close();
            inputStream.close();
            model = ModelFactory.createDefaultModel();

            TDBLoader.loadModel(model, filePath, false);//THIS METHOD REQUIRES THE FILE PATH. 
            MainActivity.presenter.setModel(model);

        }catch(FileNotFoundException e){
            e.printStackTrace(System.out);
        }
        catch(IOException e){
            e.printStackTrace(System.out);
        }
        return model;
    }

如您所见,TDBLoader.loadModel() 方法需要文件 URI 的字符串作为第二个参数,因此无需使用 InputStream 即可直接从我的资产文件夹访问文件会很方便。该方法将作为参数(模型模型、字符串 url、布尔 showProgress)。正如我所提到的,我使用的当前策略占用了太多内存,要么完全崩溃应用程序,要么需要 10 分钟才能下载我需要的文件。我正在使用 AsyncTask 执行此操作,但由于执行任务所需的时间长度在这种情况下违背了 AsyncTask 的目的。

更复杂的是,我必须使用旧版本的 Apache Jena,因为我正在使用 Android Studio,而 Apache Jena 的官方版本与 android studio 不兼容。所以我必须使用一个已有 8 年历史的端口,它没有 Apache Jena 提供的更新类。如果我可以使用 RDFParser 类,我可以传递一个 InputStream,但该类在我必须使用的旧版本的 Apache Jena 中不存在。

所以我被困在这一点上。该方法必须利用我的资产文件夹中文件的字符串 url 路径,但我不知道如何在不从 InputStream 写入自定义文件的情况下访问它,但从 InputStream 写入文件会占用太多内存和强制应用程序崩溃。如果有人有解决方案,我将不胜感激。

【问题讨论】:

  • 如果我有正确的库,loadModel() 需要一个 URL,而不是一个 URI。如,它期望格式为http://www.example.com
  • @TheWanderer 它适用于文件路径。它可以是您提到的文件名或 URL,因为在这种情况下它与我传递给它的路径一起使用并加载模型。
  • 我现在有点困惑。为什么你不能从InputStream 加载而只做model.read(inputStream, null)
  • 如果您需要一些新的 API 功能和错误修复,您也可以尝试将 Android Jena port 项目迁移到最新版本。不应该那么困难。现在,它位于2.13.0,迁移到 3.x 可能很容易,因为它主要是依赖于原始二进制文件的 Maven 设置。
  • @AKSW 感谢您的评论。我想我会尝试迁移端口并简单地更新它。获取更新功能是解决此问题的一种方法。

标签: java android rdf jena


【解决方案1】:

这是我的代码示例

new byte[10000000] 可能会失败,因为您可能没有那么大的单个连续内存块。另外,您可能一开始就没有那么多堆空间。使用较小的数字,例如 65536。

当我实施该策略时,我的应用程序大约需要 10:00 分钟才能下载文件

时间因硬件而异。我不认为它在大多数设备上会那么慢,但在某些设备上可能会这样。

我想知道是否有一种方法可以访问我在 android studio 中的资产文件夹中的文件及其路径?

您正在 Android 上运行您的应用。 Android Studio 未在 Android 上运行。资产不是 Android 设备上的文件。它们是 APK 文件中的条目,基本上是一个 ZIP 存档。实际上,您的代码正在解压缩 170MB 的材料并将其写入文件。

如果有人有解决方案,我将不胜感激。

与一些人合作移植更新版本的 Jena,该版本提供从 InputStream 读取 RDF。

或者切换到其他一些 RDF 库。

或者直接使用 RDF 文件格式。

或者使用较小的 RDF 文件,这样复制所需的时间会更短。

或下载 RDF 文件,如果您认为这比复制资产更可取。

或者在前台JobIntentService 中进行资产到文件的复制,更新其关联的Notification 中的进度,以便用户可以在您完成复制时在他们的设备上执行其他操作。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-11-21
    • 1970-01-01
    • 1970-01-01
    • 2018-06-30
    • 2015-03-26
    • 2012-07-28
    • 1970-01-01
    相关资源
    最近更新 更多