资产文件夹及其子文件夹中的文件列表

66
我在我的Android项目的“assets”文件夹中有一些带有HTML文件的文件夹。我需要在列表中显示这些来自assets子文件夹的HTML文件。我已经编写了一些关于创建这个列表的代码。
lv1 = (ListView) findViewById(R.id.listView);
// Insert array in ListView

// In the next row I need to insert an array of strings of file names
// so please, tell me, how to get this array

lv1.setAdapter(new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, filel));
lv1.setTextFilterEnabled(true);
// onclick items in ListView:
lv1.setOnItemClickListener(new OnItemClickListener() {
    public void onItemClick(AdapterView<?> a, View v, int position, long id) {
        //Clicked item position
        String itemname = new Integer(position).toString();  
        Intent intent = new Intent();
        intent.setClass(DrugList.this, Web.class);
        Bundle b = new Bundle();
        //I don't know what it's doing here
        b.putString("defStrID", itemname); 
        intent.putExtras(b);
        //start Intent
        startActivity(intent);
    }
});
10个回答

115
private boolean listAssetFiles(String path) {

    String [] list;
    try {
        list = getAssets().list(path);
        if (list.length > 0) {
            // This is a folder
            for (String file : list) {
                if (!listAssetFiles(path + "/" + file))
                    return false;
                else {
                    // This is a file
                    // TODO: add file name to an array list
                }
            }
        } 
    } catch (IOException e) {
        return false;
    }

    return true; 
} 

使用资产文件夹的根文件夹名称调用listAssetFiles函数。

    listAssetFiles("root_folder_name_in_assets");

如果根目录是资源文件夹,则使用以下方式调用:

    listAssetFiles("");    

1
在Java中使用StringBuilder而不是连接字符串。 - Gelldur
7
将假定空的子目录为文件。 - bitluni
是的,但为什么要在资产中放置空文件夹呢? - Nursultan Talapbekov
2
@Motasharred:这已经很久了...但是上面的片段中缺少一个}。 - cafebabe1991
@Motasharred,你的解决方案在路径为“”时无法运行子文件夹,只有在路径不为空时才需要“/”。 - j.c
显示剩余3条评论

27

试试这个,在你的情况下会起作用

f = getAssets().list("");
for(String f1 : f){
    Log.v("names",f1);
}

以上片段将显示资产根目录的内容。

例如... 如果以下是资产结构...

assets
 |__Dir1
 |__Dir2
 |__File1

代码片段的输出将是....Dir1 Dir2 File1

如果您需要目录Dir1的内容

请将目录名称传递给列表函数。

  f = getAssets().list("Dir1");

1
我修改了这段代码,因为Eclipse显示错误。String[] f = null; try { f = getAssets().list(""); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } for(String f1:f){ Log.v("names",f1); } - Max L
1
结果是 - 模拟器显示了一个包含四个项目的列表:药物、图像、声音、WebKit。 - Max L
2
是的,它显示出来了,但在 asset 中传递您目录的名称可以帮助您摆脱它。将父文件夹及其所有内容放入括号中,这样就会列出所有内容,例如 getAssets().list("drugs");。 - cafebabe1991
你需要重复相同的过程来获取资产文件夹内每个文件夹中的文件……而是创建一个字符串数组,包含文件夹名称,并将它们传递到列表函数中。 - cafebabe1991

3
希望这可以帮到您:
以下代码将复制整个文件夹及其内容以及子文件夹的内容到sd卡位置:
 private void getAssetAppFolder(String dir) throws Exception{

    {
        File f = new File(sdcardLocation + "/" + dir);
        if (!f.exists() || !f.isDirectory())
            f.mkdirs();
    }
     AssetManager am=getAssets();

     String [] aplist=am.list(dir);

     for(String strf:aplist){
        try{
             InputStream is=am.open(dir+"/"+strf);
             copyToDisk(dir,strf,is);
         }catch(Exception ex){


            getAssetAppFolder(dir+"/"+strf);
         }
     }



 }


 public void copyToDisk(String dir,String name,InputStream is) throws IOException{
     int size;
        byte[] buffer = new byte[2048];

        FileOutputStream fout = new FileOutputStream(sdcardLocation +"/"+dir+"/" +name);
        BufferedOutputStream bufferOut = new BufferedOutputStream(fout, buffer.length);

        while ((size = is.read(buffer, 0, buffer.length)) != -1) {
            bufferOut.write(buffer, 0, size);
        }
        bufferOut.flush();
        bufferOut.close();
        is.close();
        fout.close();
 }

1

这是我找到的一个解决方案,可以100%地列出所有目录和文件,甚至包括子目录和子目录中的文件。

注意:在我的情况下

  1. Filenames had a . in them. i.e. .htm .txt etc
  2. Directorynames did not have any . in them.

    listAssetFiles2(path); // <<-- Call function where required
    
    
    //function to list files and directories
    public void listAssetFiles2 (String path){
    String [] list;
    
    try {
        list = getAssets().list(path);
        if(list.length > 0){
            for(String file : list){
                System.out.println("File path = "+file);
    
                if(file.indexOf(".") < 0) { // <<-- check if filename has a . then it is a file - hopefully directory names dont have . 
                    System.out.println("This is a folder = "+path+"/"+file);
                    listAssetFiles2(file); // <<-- To get subdirectory files and directories list and check 
                }else{
                    System.out.println("This is a file = "+path+"/"+file);
                }
            }
    
        }else{
            System.out.println("Failed Path = "+path);
            System.out.println("Check path again.");
        }
    }catch(IOException e){
        e.printStackTrace();
    }
    }//now completed
    

谢谢


1
我认为最好检查文件是否为目录,备选方案是使用try-catch!
 public static  List<String> listAssetFiles(Context c,String rootPath) {
    List<String> files =new ArrayList<>();
    try {
        String [] Paths = c.getAssets().list(rootPath);
        if (Paths.length > 0) {
            // This is a folder
            for (String file : Paths) {
                String path = rootPath + "/" + file;
                if (new File(path).isDirectory())
                    files.addAll(listAssetFiles(c,path));
                else files.add(path);
            }
        }
    } catch (IOException e) {
        e.printStackTrace();
    }
   return files;
}

使用以下代码替换原有代码:if (c.getAssets().list(path).length > 0),以取代 if (new File(path).isDirectory()) - Siklab.ph
使用if (c.getAssets().list(path).length > 0)代替if (new File(path).isDirectory()) - Siklab.ph

0

基于 @Kammaar 的回答。这段 Kotlin 代码扫描文件树的叶子节点:

private fun listAssetFiles(path: String, context: Context): List<String> {
    val result = ArrayList<String>()
    context.assets.list(path).forEach { file ->
        val innerFiles = listAssetFiles("$path/$file", context)
        if (!innerFiles.isEmpty()) {
            result.addAll(innerFiles)
        } else {
            // it can be an empty folder or file you don't like, you can check it here
            result.add("$path/$file")
        }
    }
    return result
}

0
这里是使用Kotlin的解决方案:
val assetManager = context.resources.assets
assetManager
    .list("myDirectoryNameInAssetsFolder")
    .also { Log.i("Meow", "Detected files: ${it?.joinToString()}") }
    ?.map { "myDirectoryNameInAssetsFolder/$it" }
    ?.map(assetManager::open)
    ?.map { it.bufferedReader().use(BufferedReader::readText) }
    ?.also { Log.i("Meow", "Text of each file:") }
    ?.forEach { fileText -> Log.i("Meow", fileText) }
    ?: error("Could not access/read files in assets folder")

0

此方法返回 Assets 文件夹中一个目录中的文件名

 private fun getListOfFilesFromAsset(path: String, context: Context): ArrayList<String> {
            val listOfAudioFiles = ArrayList<String>()
            context.assets.list(path)?.forEach { file ->
                val innerFiles = getListOfFilesFromAsset("$path/$file", context)
                if (innerFiles.isNotEmpty()) {
                    listOfAudioFiles.addAll(innerFiles)
                } else {
                    // it can be an empty folder or file you don't like, you can check it here
                    listOfAudioFiles.add("$path/$file")
                }
            }
            return listOfAudioFiles
        }

例如,您想从声音文件夹中加载音乐文件路径。

enter image description here

您可以像这样获取所有声音:

  private const val SOUND_DIRECTORY = "sound"


   fun fetchSongsFromAssets(context: Context): ArrayList<String> {
        return getListOfFilesFromAsset(SOUND_DIRECTORY, context)
    }

0
public static String[] getDirectoryFilesRecursive(String path)
{
    ArrayList<String> result  = new ArrayList<String>();
    try
    {
        String[] files = Storage.AssetMgr.list(path);
        for(String file : files)
        {
            String filename = path + (path.isEmpty() ? "" : "/") + file;
            String[] tmp = Storage.AssetMgr.list(filename);
            if(tmp.length!=0) {
                result.addAll(Arrays.asList(getDirectoryFilesRecursive(filename)));
            }
            else {
                result.add(filename);
            }
        }
    }
    catch (IOException e)
    {
        Native.err("Failed to get asset file list: " + e);
    }
    Object[] objectList = result.toArray();
    return Arrays.copyOf(objectList,objectList.length,String[].class);
}

0
改进版的@Kammaar的答案,使用Kotlin [递归]
fun listAssetFiles(
    context: Context,
    path: String,
    dirCallback: ((dirPath: String) -> Unit)? = null,
    fileCallback: (filePath: String) -> Unit,
): Boolean {
    try {
        context.assets.list(path)?.also { files ->
            if (files.isNotEmpty()) {
                for (file in files) {
                    val relativePath = if (path.isEmpty()) file else "$path${File.separatorChar}$file"
                    if (!listAssetFiles(context, relativePath, dirCallback,fileCallback))
                        fileCallback.invoke(relativePath) else dirCallback?.invoke( relativePath)
                }
            } else return false
        }
    } catch (e: IOException) {return false}
    return true
}

如何使用:
    listAssetFiles(getApplication(), ""){Log.e("TAG", "File found ->  $it")}

另一个示例,用于检索文件和文件夹的分隔列表:
    val fileList = mutableListOf<String>()
    val folderList = mutableListOf<String>()
    listAssetFiles(
        context = getApplication(),
        path = "sample_folder",
        dirCallback = {folderList.add(it)},
        fileCallback = {fileList.add(it)})

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接