HiveBrain v1.2.0
Get Started
← Back to all entries
patternjavaMinor

Scanning a directory and listing contents in an HTML file

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
directoryfilecontentslistingandscanninghtml

Problem

My program simply accepts the name of a directory from the user, scans said directory and generates an HTML file that lists the contents.

Is there any way that this can be improved?

/*
    Basically, take the path of a directory, get a list of all files in the directory
    and output that list to an html document
*/
import java.util.Scanner;
import java.util.ArrayList;
import java.util.Arrays;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.BufferedWriter;
import java.nio.file.FileSystemException;

public class HTMLFileListGenerator{
    static void writeDirectoryFilesToHTML(File directory) throws IOException{
        ArrayList contents = new ArrayList(Arrays.asList(directory.list()));

        File output = new File("output.html");
        try(BufferedWriter writer = new BufferedWriter(new FileWriter(output))){
            writer.write("\n\t\n\t\tContents of " + directory.getCanonicalPath() + ":\n\t\t\n\t\t\t");

            for(int counter = 0; counter  " + contents.get(counter) + " \n");
            }
            writer.write("\t\t\n\t\n");
        }
    }
    public static void main(String[] args){
        try(Scanner userInput = new Scanner(System.in)){
            File testInput;
            do{
                System.out.print("Please enter the name of the directory: ");
                String input = userInput.next();
                testInput = new File(input);
            }
            while(!testInput.isDirectory());
            writeDirectoryFilesToHTML(testInput);
        }
        catch(IOException io_exc){
            System.out.println("An error occurred: " + io_exc.getMessage());
        }
    }
}

Solution

Files and Paths

Since Java 7, the recommended way of traversing a file system is to rely on the new Path class and associated Files and Paths helper classes.

Furthermore, since you are on Java 8, there is the Files.list(Path) method that lets you iterate through a given directory as a form of Stream, so that you can leverage on the stream-processing features.

For example, just to pad each entry in the given directory with
  • ..., the following snippet does something similar to your for-loop:



List contents;
try {
    // assuming directoryPath is validated as a directory already
    contents = Files.list(directoryPath)
                    .map(v -> "" + v + "")
                    .collect(Collectors.toList());
} catch (IOException e) {
    // handle accordingly
}


To write contents out to a file, there's also Files.write(Path, Iterable, OpenOption):

try {
    Files.write(outputPath, contents);
} catch (IOException e) {
    // handle accordingly
}


However, since you need to write the header and 'close' the end of the HTML document, you can rely on the forEach() terminal operation of a Stream:

private static void writeDirectoryFilesToHTML(Path directoryPath, 
                                                Path outputPath) throws IOException {
    try (FileWriter target = new FileWriter(outputPath.toFile());
            BufferedWriter buffered = new BufferedWriter(target);
            PrintWriter writer = new PrintWriter(buffered)) {
        writer.write("\n\t\n\t\tContents of "
                        + directoryPath.toRealPath() 
                        + ":\n\t\t\n");
        Files.list(directoryPath)
                .map(v -> "\t\t\t " + v + " ")
                .forEach(writer::println);
        writer.write("\t\t\n\t\n");
    }
}


Here, writer::println is used as a method reference.

HTML output and OS-dependent newlines

You can also consider using some sort of a HTML output library so that you do not have to manually specify "........." (for example).

You are currently hard-coding your newlines to be \n, so you may want to create a helper method that writes the OS-dependent newlines for you, after every call to write().

Other observations

As you can see from above, it's recommended that your method takes in the output path as well, instead of assuming "output.html".

Code Snippets

List<String> contents;
try {
    // assuming directoryPath is validated as a directory already
    contents = Files.list(directoryPath)
                    .map(v -> "<li>" + v + "</li>")
                    .collect(Collectors.toList());
} catch (IOException e) {
    // handle accordingly
}
try {
    Files.write(outputPath, contents);
} catch (IOException e) {
    // handle accordingly
}
private static void writeDirectoryFilesToHTML(Path directoryPath, 
                                                Path outputPath) throws IOException {
    try (FileWriter target = new FileWriter(outputPath.toFile());
            BufferedWriter buffered = new BufferedWriter(target);
            PrintWriter writer = new PrintWriter(buffered)) {
        writer.write("<html>\n\t<body>\n\t\t<h1>Contents of "
                        + directoryPath.toRealPath() 
                        + ":</h1>\n\t\t<ul>\n");
        Files.list(directoryPath)
                .map(v -> "\t\t\t<li> " + v + " </li>")
                .forEach(writer::println);
        writer.write("\t\t</ul>\n\t</body>\n</html>");
    }
}

Context

StackExchange Code Review Q#117451, answer score: 4

Revisions (0)

No revisions yet.