1

I have created a program which prints Directory tree, with file-folder sizes.

Here is my code:

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Optional;

public class FileTreeImpl implements App.FileTree {

@Override
public Optional<String> tree(Path path)
{
    if(path !=null){
        if(isDir(path)){
            File folder = new File(path.toString());
            try {
                return Optional.of(renderFolder(folder, 0, new StringBuilder(), false).toString());
            } catch (IOException e) {

            }
        }else{
            try {
                long size = Files.size(path);
                int lastIndex = 0;
                for (int i = 0; i < path.toString().length(); i++) {
                    if(path.toString().charAt(i)=='\\'){
                        lastIndex=i;
                    }
                }
                String result = path.toString().substring(lastIndex+1) + " " + size + " bytes";
                return Optional.of(result);
            } catch (IOException e) {

            }
        }
    }
    return Optional.empty();
}

static Boolean isDir(Path path) {
    if (path == null || !Files.exists(path)) return false;
    else return Files.isDirectory(path);
}

private static StringBuilder renderFolder(File folder, int level, StringBuilder sb, boolean isLast) throws IOException {

    long size = Files.walk(folder.toPath()).mapToLong( p -> p.toFile().length() ).sum();

    indent(sb, level, isLast).append(" ").append(folder.getName()).append(" " + size + " bytes").append("\n");

    File[] objects = folder.listFiles();

    for (int i = 0; i < objects.length; i++)
    {
        boolean last = ((i + 1) == objects.length);

        if (objects[i].isDirectory())
        {
            renderFolder(objects[i], level + 1, sb, last);
        }
        else
        {
            renderFile(objects[i], level + 1, sb, last);
        }
    }

    return sb;
}

private static StringBuilder renderFile(File file, int level, StringBuilder sb, boolean isLast)
{
    return indent(sb, level, isLast).append(" ").append(file.getName()).append(" " + file.length() + " bytes").append("\n");
}

private static StringBuilder indent(StringBuilder sb, int level, boolean isLast)
{
    for (int i = 1; i < level; i++)
    {
        sb.append("│  ");
    }
    if (level > 0)
    {
        sb.append(isLast
                ? "└─"
                : "├─");
    }
    return sb;
}}

So the program works for few cases, however for some of them it is quite buggy.

For example The correct output should be:

enter image description here

However my output is:

enter image description here

Another example of correct output:

enter image description here

My output:

enter image description here

So, how can I fix this bug? where does the problem Occure here?

P.S this topic print directory tree helped me a lot, however i was still unable to do it right.

  • 1
    It’s just sorting things differently to how you’re sorting them. – Boris the Spider Aug 08 '21 at 06:50
  • Yes but i am not doing it correctly and i dont understand how can i fix it. I have tried lot of thing https://stackoverflow.com/questions/10655085/print-directory-tree this topic helped me alot however i was still not able to do it correctly –  Aug 08 '21 at 06:51

1 Answers1

0

Your statement

for (int i = 1; i < level; i++)
{
    sb.append("│  ");
}

prints a vertical bar for every level. But after you printed "└─" on a given level, you must not print any vertical bars on that level in subsequent lines, until after a new folder or file name has been printed on that level.

Heiko Theißen
  • 12,807
  • 2
  • 7
  • 31
  • Tried, however unsuccessful, don't really understand how can i fix it in this case. –  Aug 08 '21 at 07:19