确定android资产条目是文件还是目录

时间:2011-12-06 12:30:31

标签: android

HeJ小鼠,

我有一些随应用程序发送的数据,应该复制到外部存储器上。它嵌套在几个子文件夹中,我想复制整个结构。

我很难在/assets中获取任何资源的File对象。但我认为我依赖于那个'因为我需要像File.isDirectory()这样的东西来确定我是否必须开始复制或深入了解系统。

我的第一种方法是使用Assets Manager,但似乎课程没有提供我需要的信息。最有希望的是获得AssetFileDescriptor并下到[FileDescriptor][2]。然而,它们中没有一个似乎有isDirectory - 方法。

所以我的另一种方法很简单:创建一个文件对象并开心。然而,似乎我正在运行这个缺少正确路径来实例化文件对象的问题。我知道file://android_asset但它似乎不适用于file构造函数。

我的最后一个想法是利用InputStream(无论如何我需要复制)并以某种方式过滤字节以获得一个重要的位,这表明该资源是一个目录。这是一个非常糟糕的解决方案,可能正处于无效的地狱,但我没有看到另一种解决方法。

3 个答案:

答案 0 :(得分:13)

我遇到了同样的问题。在某些时候,我意识到list()非常慢(每次调用50ms),所以我现在使用不同的方法:

我有一个(eclipse)ant-builder,每次我的asset-folder更改时都会创建一个索引文件。该文件每行只包含一个文件名,因此目录被隐含列出(如果它们不为空)。

建造者:

<?xml version="1.0"?>
<project default="createAssetIndex">
    <target name="createAssetIndex">
        <fileset id="assets.fileset" dir="assets/" includes="**"
            excludes="asset.index" />
        <pathconvert pathsep="${line.separator}" property="assets"
            refid="assets.fileset">
            <mapper>
                <globmapper from="${basedir}/assets/*" to="*"
                    handledirsep="yes" />
            </mapper>
        </pathconvert>
        <echo file="assets/asset.index">${assets}</echo>
    </target>
</project>

asset.index加载到字符串列表中的类,因此您可以快速执行任意操作:

import android.content.ContextWrapper;

import com.google.common.collect.ImmutableList;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;

import java.util.Scanner;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * uses asset.index file (which is pregenerated) since asset-list()s take very long
 *
 */
public final class AssetIndex {

    //~ Static fields/initializers -------------------------------------------------------------------------------------

    private static final Logger L = LoggerFactory.getLogger(AssetIndex.class);

    //~ Instance fields ------------------------------------------------------------------------------------------------

    private final ImmutableList<String> files;

    //~ Constructors ---------------------------------------------------------------------------------------------------

    public AssetIndex(final ContextWrapper contextWrapper) {

        ImmutableList.Builder<String> ib = ImmutableList.builder();

        L.debug("creating index from assets");

        InputStream in  = null;
        Scanner scanner = null;
        try {
            in          = contextWrapper.getAssets().open("asset.index");
            scanner     = new Scanner(new BufferedInputStream(in));

            while (scanner.hasNextLine()) {
                ib.add(scanner.nextLine());
            }

            scanner.close();
            in.close();

        } catch (final IOException e) {
            L.error(e.getMessage(), e);
        } finally {
            if (scanner != null) {
                scanner.close();
            }
            if (in != null) {
                try {
                    in.close();
                } catch (final IOException e) {
                    L.error(e.getMessage(), e);
                }
            }
        }

        this.files = ib.build();
    }

    //~ Methods --------------------------------------------------------------------------------------------------------

    /* returns the number of files in a directory */
    public int numFiles(final String dir) {

        String directory = dir;
        if (directory.endsWith(File.separator)) {
            directory = directory.substring(0, directory.length() - 1);
        }

        int num = 0;
        for (final String file : this.files) {
            if (file.startsWith(directory)) {

                String rest = file.substring(directory.length());
                if (rest.charAt(0) == File.separatorChar) {
                    if (rest.indexOf(File.separator, 1) == -1) {
                        num = num + 1;
                    }
                }
            }
        }

        return num;
    }
}

答案 1 :(得分:4)

如果您尝试获取文件上的列表,但是目录上的有效响应,则AssetManager上的

list()可能会给出null / zero长度数组/ IOException。

但是否则它应该是file:/// android_asset(with 3 /)

答案 2 :(得分:4)

在我的特定情况下,常规文件的名称类似于filename.ext,而目录只有一个名称,没有扩展名,并且它们的名称从不包含“。”。 (点)字符。 因此,可以通过测试其名称来区分常规文件与目录:

filename.contains(".")

如果你的情况也是如此,那么同样的解决方案应该适合你。