Thursday, November 18, 2010

How to Implement Groovy's File.eachLine in Java

One thing that I like from Groovy is that the closures concept. The method File.eachLine() in Groovy is indeed very useful and handy when reading a file line by line. Because of Java's lack of closures, there is a tendency to repeat the steps of reading each line of a file in every code. It is actually quite easy to implement Groovy's File.eachLine in Java.

FileFunction.java
public interface FileFunction {

    public void read(String line); 
}

M3UParserFileFunction.java
public class M3UParserFileFunction implements FileFunction {

    private List<File> mp3Files; 
    private File m3uFile; 
    
    public M3UParserFileFunction(File m3uFile, List<File> mp3Files) { 
        this.mp3Files = mp3Files; 
        this.m3uFile = m3uFile; 
    } 
    
    @Override 
    public void read(String line) { 
        if (!line.trim().startsWith("#")) { 
            if (line.trim().toLowerCase().endsWith(".mp3")) { 
                // Try relative path first, then absolute path. 
                File file = new File(m3uFile.getParentFile(), line.trim()); 
                if (file.exists()) { 
                    mp3Files.add(file); 
                } else if (!file.exists()) { // Use absolute path 
                    file = new File(line.trim()); 
                    if (file.exists()) { 
                        mp3Files.add(file); 
                    } 
                } 
            } 
        } 
    } 
}

FileUtils.java
public class FileUtils {

    private FileUtils() { 
    }

    public static void eachLine(File file, FileFunction fileFunction) throws IOException { 
        BufferedReader br = null; 
        try { 
            br = new BufferedReader(new FileReader(file)); 
            String line = ""; 
            while ((line = br.readLine()) != null) { 
                fileFunction.read(line); 
            } 
        } finally { 
            if (br != null) { 
                br.close(); 
            } 
        } 
    } 
}

List<File> files = new ArrayList<File>(); 
FileUtils.eachLine(m3uFile, new M3UParserFileFunction(m3uFile, files)); 
for (File file : files) { doWhatever(file); }

No comments:

Post a Comment