【问题标题】:How to get URI from an asset File?如何从资产文件中获取 URI?
【发布时间】:2011-06-16 18:56:09
【问题描述】:

我一直在尝试获取资产文件的 URI 路径。

uri = Uri.fromFile(new File("//assets/mydemo.txt"));

当我检查文件是否存在时,我发现该文件不存在

File f = new File(filepath);
if (f.exists() == true) {
    Log.e(TAG, "Valid :" + filepath);
} else {
    Log.e(TAG, "InValid :" + filepath);
}

谁能告诉我如何提及资产文件夹中存在的文件的绝对路径

【问题讨论】:

    标签: android uri filepath assets


    【解决方案1】:

    没有“资产文件夹中存在的文件的绝对路径”。您项目的assets/ 文件夹的内容打包在APK 文件中。使用 AssetManager 对象获取资产上的 InputStream

    对于WebView,您可以使用file Uri 方案,其方式与使用URL 的方式大致相同。资产的语法是 file:///android_asset/...(注意:三个斜杠),其中省略号是 assets/ 文件夹中文件的路径。

    【讨论】:

    • file://android_asset/...,其中... 是您项目的assets/ 目录中的相对路径。
    • 这里是一个使用file://android_asset/的示例项目,虽然不是Urigithub.com/commonsguy/cw-advandroid/tree/master/WebView/GeoWeb1
    • @CommonsWare 看起来您在 URI 中遗漏了一个“/”。应该是file:///
    • 我以new File("file:///android_asset/sounds/beep.mid"); 尝试过此操作,但结果文件不存在。有任何想法吗?附言文件位于assets/sounds/ 文件夹中。
    • 'file:///android_asset/...' 只在 WebView 中有效并且无法在 WebView 之外使用 URI/URL/Uri 获取 InputStream 是否正确?
    【解决方案2】:

    正确的网址是:

    file:///android_asset/RELATIVEPATH
    

    其中 RELATIVEPATH 是资源相对于资产文件夹的路径。

    注意方案中的 3 个 /。如果没有 3,Web 视图将无法加载我的任何资产。我尝试了 CommonsWare(之前)评论的 2,但它不起作用。然后我在 github 上查看了 CommonsWare 的源代码,发现了多余的正斜杠。

    这个测试虽然只在 1.6 Android 模拟器上完成,但我怀疑它在真实设备或更高版本上的不同。

    编辑:CommonsWare 更新了他的答案以反映这个微小的变化。所以我已经编辑了这个,所以他现在的答案仍然有意义。

    【讨论】:

    • 不再工作 String fileName = "file:///android_asset/file.csv"; System.out.println(new File(fileName).exists()); // prints false
    • @Elgirhath 接受字符串的File 的构造函数需要path 而不是URI。我已经有几年没有为 Android 编码了,事情可能已经改变了。我不确定您是否可以使用普通的 java File 类访问嵌入式资产文件夹。我似乎记得你必须使用AssetManager。 assets 文件夹中的文件放在设备上的只读捆绑 APK 中并压缩(APK 实际上是 zip 文件),因此需要做更多的工作来读取它。试试new File(new URI(filename))
    【解决方案3】:

    最后,我找到了一种从 Kotlin 中的this 答案获取资产中存在的文件路径的方法。在这里,我们将资产文件复制到缓存并从该缓存文件中获取文件路径。

    @Throws(IOException::class)
        fun getFileFromAssets(context: Context, fileName: String): File = File(context.cacheDir, fileName)
                .also {
                   if (!it.exists()) {
                    it.outputStream().use { cache ->
                        context.assets.open(fileName).use { inputStream ->
                                inputStream.copyTo(cache)
                        }
                      }
                    }
                }
    

    获取文件的路径,如:

    val filePath =  getFileFromAssets(context, "fileName.extension").absolutePath
    

    【讨论】:

    • 请注意,如果fileName 有目录dir/file。它会因cache/dir/file 不存在的路径而崩溃。另外我认为最好在also 块内检查if(!it.exist),这样即使文件已经在缓存中,它也不会每次都复制文件
    • @ShylendraMadda, @Yeung, if(!it.exist) 抛出一个未解决的错误参考。有什么解决办法吗?
    • 检查缓存中是否存在具有该文件名的文件? @binrebin
    • @ShylendraMadda,我只知道文件名。我们可以在不知道实际 uri 的情况下用脚本加载它吗
    • 我认为if(!it.exist)应该放在it.outputStream()之前...
    【解决方案4】:

    请试试这段代码是否正常

     Uri imageUri = Uri.fromFile(new File("//android_asset/luc.jpeg"));
    
        /* 2) Create a new Intent */
        Intent imageEditorIntent = new AdobeImageIntent.Builder(this)
                .setData(imageUri)
                .build();
    

    【讨论】:

      【解决方案5】:

      确保您的资产文件夹放置在正确的位置。

      【讨论】:

      • 你可以把它放在任何你想要的地方,并在你的 build.gradle 文件中定义路径如下sourceSets { main { assets.srcDirs = ['src/main/assets'] } }
      • 如何获取 hello.html 的路径?请添加
      【解决方案6】:

      适用于 WebView,但似乎在 URL.openStream() 上失败。所以需要区分file://协议,按照建议通过AssetManager处理。

      【讨论】:

        【解决方案7】:

        试试这个,它有效:

        InputStream in_s = 
            getClass().getClassLoader().getResourceAsStream("TopBrands.xml");
        

        如果你得到一个空值异常,试试这个(类TopBrandData):

        InputStream in_s1 =
            TopBrandData.class.getResourceAsStream("/assets/TopBrands.xml");
        

        【讨论】:

        • 如果不行,请试试这个:InputStream in_s1 = TopBrandData.class.getResourceAsStream("/assets/TopBrands.xml");
        【解决方案8】:
        InputStream is = getResources().getAssets().open("terms.txt");
        String textfile = convertStreamToString(is);
            
        public static String convertStreamToString(InputStream is)
                throws IOException {
        
            Writer writer = new StringWriter();
            char[] buffer = new char[2048];
        
            try {
                Reader reader = new BufferedReader(new InputStreamReader(is, "UTF-8"));
                int n;
                while ((n = reader.read(buffer)) != -1) {
                    writer.write(buffer, 0, n);
                }
            } finally {
                is.close();
            }
        
            String text = writer.toString();
            return text;
        }
        

        【讨论】:

          【解决方案9】:

          试试这个:

          Uri uri = Uri.parse("android.resource://"+getPackageName()+"/"+R.raw.cat); 
          

          我做到了,它成功了

          【讨论】:

          • 其实可以的。检查ContentResolver.openAssetFileDescriptor
          • 工作。非常感谢。大声笑,我只是在寻找获取 URI 内部文件//在 RES 中创建原始文件夹,然后名称文件仅包含 a..z0..9 字符,没有大写!!!
          【解决方案10】:

          是的,你不能从你的安卓手机或模拟器访问你的驱动器文件夹,因为你的电脑和安卓是两个不同的操作系统。我会去安卓的 res 文件夹,因为它有很好的资源管理方法。除非您有充分的理由将文件放在资产文件夹中。相反,您可以这样做

          try {
                Resources res = getResources();
                InputStream in_s = res.openRawResource(R.raw.yourfile);
          
                byte[] b = new byte[in_s.available()];
                in_s.read(b);
                String str = new String(b);
              } catch (Exception e) {
                Log.e(LOG_TAG, "File Reading Error", e);
           }
          

          【讨论】:

            【解决方案11】:

            为我工作试试这个代码

               uri = Uri.fromFile(new File("//assets/testdemo.txt"));
               String testfilepath = uri.getPath();
                File f = new File(testfilepath);
                if (f.exists() == true) {
                Toast.makeText(getApplicationContext(),"valid :" + testfilepath, 2000).show();
                } else {
               Toast.makeText(getApplicationContext(),"invalid :" + testfilepath, 2000).show();
             }
            

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 2014-03-10
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2012-10-30
              • 1970-01-01
              相关资源
              最近更新 更多