【问题标题】:How to get the android Path string to a file on Assets folder?如何将android路径字符串获取到资产文件夹中的文件?
【发布时间】:2012-01-18 11:26:35
【问题描述】:

我需要知道 assets 文件夹中文件的 字符串路径,因为我使用的地图 API 需要接收字符串路径,并且我的地图必须存储在 assets 文件夹中

这是我正在尝试的代码:

    MapView mapView = new MapView(this);
    mapView.setClickable(true);
    mapView.setBuiltInZoomControls(true);
    mapView.setMapFile("file:///android_asset/m1.map");
    setContentView(mapView);

"file:///android_asset/m1.map" 出了点问题,因为地图没有加载。

存储在我的资产文件夹中的文件 m1.map 的正确字符串路径文件是什么?

谢谢

为 Dimitru 编辑:此代码不起作用,它在 is.read(buffer); 上失败并出现 IOException

        try {
            InputStream is = getAssets().open("m1.map");
            int size = is.available();
            byte[] buffer = new byte[size];
            is.read(buffer);
            is.close();
            text = new String(buffer);
        } catch (IOException e) {throw new RuntimeException(e);}

【问题讨论】:

  • 我找到了一种方法来参考我的答案here

标签: android assets android-assets


【解决方案1】:

你可以使用这个方法。

    public static File getRobotCacheFile(Context context) throws IOException {
        File cacheFile = new File(context.getCacheDir(), "robot.png");
        try {
            InputStream inputStream = context.getAssets().open("robot.png");
            try {
                FileOutputStream outputStream = new FileOutputStream(cacheFile);
                try {
                    byte[] buf = new byte[1024];
                    int len;
                    while ((len = inputStream.read(buf)) > 0) {
                        outputStream.write(buf, 0, len);
                    }
                } finally {
                    outputStream.close();
                }
            } finally {
                inputStream.close();
            }
        } catch (IOException e) {
            throw new IOException("Could not open robot png", e);
        }
        return cacheFile;
    }

在这种情况下,您应该永远不要使用 InputStream.available()。它仅返回缓冲的字节。带有 .available() 的方法将永远无法处理更大的文件,并且根本无法在某些设备上运行。

在 Kotlin (;D) 中:

@Throws(IOException::class)
fun getRobotCacheFile(context: Context): File = File(context.cacheDir, "robot.png")
    .also {
        it.outputStream().use { cache -> context.assets.open("robot.png").use { it.copyTo(cache) } }
    }

【讨论】:

  • 感谢 Jacket,Kotlin 部分确实帮助了我。
【解决方案2】:

只是为了添加 Jacek 的完美解决方案。如果您尝试在 Kotlin 中执行此操作,它不会立即起作用。相反,你会想要使用这个:

@Throws(IOException::class)
fun getSplashVideo(context: Context): File {
    val cacheFile = File(context.cacheDir, "splash_video")
    try {
        val inputStream = context.assets.open("splash_video")
        val outputStream = FileOutputStream(cacheFile)
        try {
            inputStream.copyTo(outputStream)
        } finally {
            inputStream.close()
            outputStream.close()
        }
    } catch (e: IOException) {
        throw IOException("Could not open splash_video", e)
    }
    return cacheFile
}

【讨论】:

    【解决方案3】:

    AFAIK 资产目录中的文件不会被解压。 相反,它们是直接从 APK (ZIP) 文件中读取的。

    所以,你真的不能让期望 file 的东西接受资产“文件”。

    相反,您必须提取资产并将其写入单独的文件,就像 Dumitru 建议的那样:

      File f = new File(getCacheDir()+"/m1.map");
      if (!f.exists()) try {
    
        InputStream is = getAssets().open("m1.map");
        int size = is.available();
        byte[] buffer = new byte[size];
        is.read(buffer);
        is.close();
    
    
        FileOutputStream fos = new FileOutputStream(f);
        fos.write(buffer);
        fos.close();
      } catch (Exception e) { throw new RuntimeException(e); }
    
      mapView.setMapFile(f.getPath());
    

    【讨论】:

    • 我得到异常:java.io.FileNotFoundException: m1.map
    • 异常就行 InputStream is = getAssets().open("m1.map");
    • 好的,解决了,但现在我得到了与 Dumitru 回答相同的异常,12-12 15:06:41.452:DEBUG/asset(3760):数据超过 UNCOMPRESS_DATA_MAX(3491923 与 1048576)跨度>
    • 很好,完全正确,资产目录中的文件已压缩,因此您必须提取到字节数组,写入临时文件并加载该文件,谢谢!
    • 哦,是的,您可以使用“file:///android_asset/FILENAME”作为 url
    【解决方案4】:

    查看 SDK 附带的 API 示例中的 ReadAsset.java。

           try {
            InputStream is = getAssets().open("read_asset.txt");
    
            // We guarantee that the available method returns the total
            // size of the asset...  of course, this does mean that a single
            // asset can't be more than 2 gigs.
            int size = is.available();
    
            // Read the entire asset into a local byte buffer.
            byte[] buffer = new byte[size];
            is.read(buffer);
            is.close();
    
            // Convert the buffer into a string.
            String text = new String(buffer);
    
            // Finally stick the string into the text view.
            TextView tv = (TextView)findViewById(R.id.text);
            tv.setText(text);
        } catch (IOException e) {
            // Should never happen!
            throw new RuntimeException(e);
        }
    

    【讨论】:

    • 它对我不起作用,行 is.read(buffer);给我 IOException
    • 它到底抛出了什么异常?
    • 12-12 15:06:41.452: DEBUG/asset(3760): 数据超过 UNCOMPRESS_DATA_MAX (3491923 vs 1048576)
    猜你喜欢
    • 2014-05-19
    • 1970-01-01
    • 1970-01-01
    • 2011-06-29
    • 1970-01-01
    • 2018-04-22
    • 2023-03-15
    • 2015-08-01
    • 2013-07-06
    相关资源
    最近更新 更多