I\'m retrieving files like this
String[] files = assetFiles.list(\"EngagiaDroid\");
How can we know whether it is a file or is a director
Another way relying on exceptions:
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);
}
}
and then just call checkAssets("someFolder", getAssets()); or checkAssets("", getAssets()); if you want to check the root assets folder. But be aware that the root assets folder contains also other directories/files (Eg. webkit, images, etc.)
You can start from Android File
The appalling truth is that despite being asked nearly 10 years ago, no simple, elegant, roundly applauded method of determining whether an element in the array returned by AssetManager.list() is a file or a directory has been offered by any answer to date.
So, for example, if an asset directory contains a thousand elements, then seemingly a thousand I/O operations are necessary to isolate the directories.
Nor, for any element, does any native method exist for obtaining its parent directory - vital for something complex like an assets Browser / Picker - where you could end up looking at some seriously ugly code.
boolean isAssetDirectory = !elementName.contains(".");
The lateral approach that worked for me was to assume that any element without a dot (.) in its name was a directory. If the assumption is later proved wrong it can be easily rectified.
Asset files generally exist because you put them there. Deploy naming conventions that distinguish between directories and files.
I think a more general solution (in case you have subfolders etc.) would be something like this (based on the solution you linked to, I've added it there too):
...
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());
}
}
You can also try this, it works for me, since you cannot rely solely on .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;
}
}
}
I've discovered this variant:
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
}
It's a more faster as .list()