简体   繁体   English

如何将android Path字符串转换为Assets文件夹中的文件?

[英]How to get the android Path string to a file on Assets folder?

I need to know the string path to a file on assets folder, because I'm using a map API that needs to receive a string path, and my maps must be stored on assets folder 我需要知道assets文件夹上文件的字符串路径 ,因为我使用的是需要接收字符串路径的map API,我的地图必须存储在assets文件夹中

This is the code i'm trying: 这是我正在尝试的代码:

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

Something is going wrong with "file:///android_asset/m1.map" because the map is not being loaded. "file:///android_asset/m1.map"因为没有加载地图。

Which is the correct string path file to the file m1.map stored on my assets folder? 哪个是存储在我的assets文件夹中的文件m1.map的正确字符串路径文件?

Thanks 谢谢

EDIT for Dimitru: This code doesn't works, it fails on is.read(buffer); 编辑Dimitru:此代码不起作用,它在is.read(buffer);上失败is.read(buffer); with IOException 使用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);}

AFAIK the files in the assets directory don't get unpacked. AFAIK资产目录中的文件无法解压缩。 Instead, they are read directly from the APK (ZIP) file. 相反,它们直接从APK(ZIP)文件中读取。

So, you really can't make stuff that expects a file accept an asset 'file'. 所以,你真的不能制作期望文件接受资产'文件'的东西。

Instead, you'll have to extract the asset and write it to a seperate file, like Dumitru suggests: 相反,您必须提取资产并将其写入单独的文件,如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());

You can use this method. 您可以使用此方法。

    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;
    }

You should never use InputStream.available() in such cases. 在这种情况下,您永远不应该使用InputStream.available() It returns only bytes that are buffered. 它仅返回缓冲的字节。 Method with .available() will never work with bigger files and will not work on some devices at all. 使用.available()的方法永远不会使用更大的文件,根本无法在某些设备上使用。

In Kotlin (;D): 在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) } }
    }

Have a look at the ReadAsset.java from API samples that come with the SDK. 请查看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);
    }

Just to add on Jacek's perfect solution. 只是添加Jacek的完美解决方案。 If you're trying to do this in Kotlin, it wont work immediately. 如果你想在Kotlin做这件事,它就不会马上工作。 Instead, you'll want to use this: 相反,你会想要使用这个:

@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
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM