1

How can I get a local directory listing as a Json?

So If I provide a folder, I want to see all its subfolders and files in a json tree type object.

Please note: I don't want just the list with file paths.
Thank you!

ᴛʜᴇᴘᴀᴛᴇʟ
  • 4,466
  • 5
  • 39
  • 73

2 Answers2

4

So @CommonsWare put me in the right direction and I was able to do this.

This will create a FileStructure.json file in ExternalStorageDirectory (/sdcard)

Here's how:

/**
 * Creates a json of all files and directories within the given file
 * @param file the root directory to list
 * @return true if success, else false
 */
public static boolean getStructure(Context context, File file) {

    boolean result = false;

    JsonWriter writer;
    try {
        writer = new JsonWriter(new FileWriter(new File(context.getApplicationContext().getExternalFilesDir(null), "FileStructure.json")));
        writer.setIndent("    ");
    } catch (Exception e) {
        Log.e(TAG, e.toString());
        return result;
    }

    try {
        if(file.exists()) {
            result = writeRootDir(writer, file);
        } else {
            result = false;
        }

        writer.close();
    } catch (Exception e) {
        Log.e(TAG, e.toString());
        return result;
    }

    return true;
}

/**
 * writing root directory array and object
 * @param writer the JsonWriter
 * @param dir the root dir
 * @return true if success, else false
 */
private static boolean writeRootDir(JsonWriter writer, File dir) {
    boolean result = false;

    if(!dir.exists() || !dir.isDirectory()) {
        return result;
    }

    try {
        writer.beginArray();
        writer.beginObject();

        writer.name(dir.getPath());
        result = writeDirectory(writer, dir);

        writer.endObject();
        writer.endArray();
    } catch (Exception e) {
        Log.e(TAG, e.toString());
        return result;
    }

    return result;
}


/**
 * for each directory and file within the root directory
 * @param writer the JsonWriter
 * @param dir sub-directory
 * @return true if success, else false
 */
private static boolean writeDirectory(JsonWriter writer, File dir) {
    if(!dir.exists() || !dir.isDirectory()) {
        return false;
    }

    File[] allFiles = dir.listFiles();
    List<File> directories = new ArrayList<>();
    List<File> files = new ArrayList<>();

    for (File subFile : allFiles) {
        if(!subFile.getName().startsWith(".") && !subFile.getName().startsWith("_") && subFile.isDirectory()) {
            directories.add(subFile);
        }
    }

    for(File subFile : allFiles) {
        if(!subFile.getName().startsWith(".") && !subFile.getName().startsWith("_") && !subFile.isDirectory()) {
            files.add(subFile);
        }
    }

    Collections.sort(directories);
    Collections.sort(files);

    try {
        writer.beginArray();
        writer.beginObject();

        if(directories.size() > 0) {
            for(File file : directories) {
                writer.name(file.getName());
                writeDirectory(writer, file);
            }
        }

        writer.endObject();

        if(files.size() > 0) {
            for(File file : files) {
                writer.value(file.getName());
            }
        }

        writer.endArray();
    } catch (Exception e) {
        Log.e(TAG, e.toString());
        return false;
    }

    return true;
}
Naveed Ahmad
  • 6,627
  • 2
  • 58
  • 83
ᴛʜᴇᴘᴀᴛᴇʟ
  • 4,466
  • 5
  • 39
  • 73
0

Another option, which is a bit simpler and should be faster:

long getDirectoryListing(File dir, StringBuilder sb)
{
    sb.append("{\"name\":\"");
    sb.append(dir.getName());
    sb.append('"');
    
    long totalSize = 0;
    if (dir.isDirectory())
    {
        sb.append(",\"files\":[");
        File[] files = dir.listFiles();
        for (int i = 0; i < files.length; i++) 
        {
            totalSize += getDirectoryListing(files[i], sb);
            if (i < files.length - 1)
            {
                sb.append(',');
            }
        }
        sb.append(']');
    }
    else
    {
        totalSize = dir.length();
    }

    sb.append(",\"lastModified\":");
    sb.append(dir.lastModified());
    sb.append(",\"size\":");
    sb.append(totalSize);
    sb.append('}');
    
    return totalSize;
}

It can be called like:

public static void main(String ...args)
{
    StringBuilder sb = new StringBuilder(100);
    File exampleFile = new File(System.getProperty("user.dir"));
    getDirectoryListing(exampleFile, sb);
    System.out.println(sb.toString());
}
egerardus
  • 11,316
  • 12
  • 80
  • 123