我正在检索这样的文件
String[] files = assetFiles.list("EngagiaDroid");
我们如何知道它是文件还是目录?
我想遍历assets文件夹中的目录,然后复制其所有内容。
答案 0 :(得分:5)
我认为更通用的解决方案(如果您有子文件夹等)将是这样的(根据您链接的解决方案,我也在那里添加了它):
...
copyFileOrDir("myrootdir");
...
private void copyFileOrDir(String path) {
AssetManager assetManager = this.getAssets();
String assets[] = null;
try {
assets = assetManager.list(path);
if (assets.length == 0) {
copyFile(path);
} else {
String fullPath = "/data/data/" + this.getPackageName() + "/" + path;
File dir = new File(fullPath);
if (!dir.exists())
dir.mkdir();
for (int i = 0; i < assets.length; ++i) {
copyFileOrDir(path + "/" + assets[i]);
}
}
} catch (IOException ex) {
Log.e("tag", "I/O Exception", ex);
}
}
private void copyFile(String filename) {
AssetManager assetManager = this.getAssets();
InputStream in = null;
OutputStream out = null;
try {
in = assetManager.open(filename);
String newFileName = "/data/data/" + this.getPackageName() + "/" + filename;
out = new FileOutputStream(newFileName);
byte[] buffer = new byte[1024];
int read;
while ((read = in.read(buffer)) != -1) {
out.write(buffer, 0, read);
}
in.close();
in = null;
out.flush();
out.close();
out = null;
} catch (Exception e) {
Log.e("tag", e.getMessage());
}
}
答案 1 :(得分:1)
我发现了这个变种:
try {
AssetFileDescriptor desc = getAssets().openFd(path); // Always throws exception: for directories and for files
desc.close(); // Never executes
} catch (Exception e) {
exception_message = e.toString();
}
if (exception_message.endsWith(path)) { // Exception for directory and for file has different message
// Directory
} else {
// File
}
它的速度更快.list()
答案 2 :(得分:0)
依赖例外的另一种方式:
private void checkAssets(String path, AssetManager assetManager) {
String TAG = "CheckAssets";
String[] fileList;
String text = "";
if (assetManager != null) {
try {
fileList = assetManager.list(path);
} catch (IOException e) {
Log.e(TAG, "Invalid directory path " + path);
return;
}
} else {
fileList = new File(path).list();
}
if (fileList != null && fileList.length > 0) {
for (String pathInFolder : fileList) {
File absolutePath = new File(path, pathInFolder);
boolean isDirectory = true;
try {
if (assetManager.open(absolutePath.getPath()) != null) {
isDirectory = false;
}
} catch (IOException ioe) {
isDirectory = true;
}
text = absolutePath.getAbsolutePath() + (isDirectory ? " is Dir" : " is File");
Log.d(TAG, text);
if (isDirectory) {
checkAssets(absolutePath.getPath(), assetManager);
}
}
} else {
Log.e(TAG, "Invalid directory path " + path);
}
}
然后只需调用 checkAssets(&#34; someFolder&#34;,getAssets()); 或 checkAssets(&#34; &#34;,getAssets()); 如果要检查根资产文件夹。但请注意,根资产文件夹还包含其他目录/文件(例如webkit,图像等)
答案 3 :(得分:0)
您可以使用AssetManager的list方法。 资产中的任何目录至少应该有一个文件,构建应用程序时将忽略空目录。 因此,要确定某个路径是否是目录,请使用如下:
AssetManager manager = activity.getAssets();
try{
String[] files = manager.list(path);
if (files.length > 0){
//directory
}
else{
//file
}
}
catch (Exception e){
//not exists.
}
答案 4 :(得分:0)
在特定情况下,由于您是通过list
来检索文件的,因此您已经知道这些名称存在。这大大简化了问题。您可以简单地使用:
public static boolean isAssetAFolder(AssetManager assetManager, String assetPath) throws IOException {
// Attempt opening as a file,
try {
InputStream inputStream = assetManager.open(assetPath); inputStream.close();
return false; // A file indeed.
} catch (FileNotFoundException e) {
// We already know this name exists. This is a folder.
return true;
}
}
另一方面,如果您需要通用的解决方案来检测某个路径是否既存在又是文件夹,则可以使用以下方法:
public static boolean isAssetAFolder(AssetManager assetManager, String assetPath) throws IOException {
// Attempt opening as a file,
try {
InputStream inputStream = assetManager.open(assetPath); inputStream.close();
return false; // A file indeed.
} catch (FileNotFoundException e) {
// This could be a folder, or this path doesn't exist at all. Further checking needed,
return assetPathExists(assetManager, assetPath);
}
}
// If you are checking a file name "icon.png" inside your assets folder, the assetPath should be "icon.png".
public static boolean assetPathExists(AssetManager assetManager, String assetPath) throws IOException {
// Assume that "" exists by default,
if (assetPath.isEmpty()) return true;
// Reject paths that point outside the assets folder,
if (assetPath.startsWith("..") || assetPath.startsWith("/")) return false;
// For other file/folder paths, we'll search the parent folder,
File fileOrFolder = new File(assetPath);
String parent = ((parent=fileOrFolder.getParent()) != null) ? parent : ""; // Handle null parents.
if (!Arrays.asList(assetManager.list(parent)).contains(fileOrFolder.getName())) return false;
// Getting this far means that the specified assetPath indeed exists. However, we didn't handle files
// with trailing "/". For instance, "icon.png/" shouldn't be considered existing although "icon.png"
// does.
// If the path doesn't end with a "/", we are safe,
if (!assetPath.endsWith("/")) return true;
// Remove the trailing slash,
assetPath = assetPath.substring(0, assetPath.length()-1);
// Attempt opening as a file,
try {
InputStream inputStream = assetManager.open(assetPath); inputStream.close();
return false; // It's indeed a file (like "icon.png"). "icon.png/" shouldn't exist.
} catch (FileNotFoundException e) {
return true; // This is a folder that exists.
}
}
我为Web服务器编写了这些代码,因此无法对输入路径的形状进行假设。但是,如果您设置了一些规则,可以稍微简化一下。一旦确定资产的类型,此代码将立即返回,以避免额外的处理开销。
答案 5 :(得分:0)
令人震惊的事实是,尽管将近10年前被问及,但没有一种简单,优雅,全面的方法来确定 AssetManager.list()返回的数组中的元素是文件还是到目前为止,没有提供任何答案的目录。
因此,例如,如果资产目录包含一千个元素,则似乎需要一千个I / O操作来隔离目录。
对于任何元素,也不存在任何本机方法来获取其父目录-这对于诸如资产 Browser / Picker 之类的复杂事物至关重要-在其中最终可能会看到一些非常丑陋的代码。
boolean isAssetDirectory = !elementName.contains(".");
对我有用的横向方法是假设名称中没有点(。)的任何元素都是目录。如果该假设后来被证明是错误的,则可以很容易地纠正。
资产文件通常存在是因为您将它们放在了那里。部署区分目录和文件的命名约定。
答案 6 :(得分:0)
您也可以尝试一下,它对我有用,因为您不能仅依靠.list()
public static boolean isDirectory(Context context, String path) throws IOException {
//If list returns any entries, than the path is a directory
String[] files = context.getAssets().list(path);
if (files != null && files.length > 0) {
return true;
} else {
try {
//If we can open a stream then the path leads to a file
context.getAssets().open(path);
return false;
} catch (Exception ex) {
//.open() throws exception if it's a directory that you're passing as a parameter
return true;
}
}
}
答案 7 :(得分:-1)
您可以使用http://developer.android.com/reference/java/io/File.html#isDirectory()检查文件是否代表目录。这是你的意思吗?
答案 8 :(得分:-1)
您可以从Android File
开始