Java input/output

From wikinotes

general notes

io vs nio

Most java classes built to handle files/filesystem are stored in io/nio.

java.io.* blocking operations (return after completion)
java.nio.* non-blocking operations (return immediately on start)

filesystem info

java.io.File (blocking-io)


java.io generally uses File to refer to filepaths.


import java.io.File;

File homedir = new File("/home/will");

Path Info

file.getName();    // basename of file/dir
file.getParent();  // parent dir-path of file/dir
file.list();       // list names of contained files/dirs
file.listFiles();  // list files only
file.isAbsolute();
file.isDirectory();

Create/Delete

file.delete();
file.renameTo("somefile.txt");
file.createNewFile();
file.makeDirs();

java.nio.file.Path (non-blocking io - returns ASAP)


java.nio.* generally uses Path to refer to filepaths. This package contains non-blocking filesystem operations.


From Paths

import java.nio.file.Paths;
import java.nio.file.Path;

Path path = Path.of("/home/will");
Path path = Paths.get("/home/will");
# NOTE: be careful not to use 'new'!

Path deals with the path itself, rather than a reference to a file. It is preferred in most of the java.nio classes.

Files.walk


Most of stream's methods return another stream. You can take advantage of using this just like piping in your shell. Gradually filtering your stream until only the results are left.

import java.nio.file.Paths;
import java.nio.file.Path;
import java.nio.file.Files;

public class App
{
    public static void main(String[] args)
        throws IOException
    {
        Path config_dir = Paths.get("/home/will/.config/qutebrowser");
        Path[] matching_files = Files.walk(config_dir)
            .filter(Files::isRegularFile)   // <-- method-reference
            .toArray(Path[]::new);          // <-- method-reference

        for (Path path: matching_files){
            System.out.println(path);
        }
    }
}

You should check out the rest of Files, it is almost entirely static-methods for operating on filepaths.


Files.walkFileTree (FileVisitor method)


An alternative to Files.walk is using walkFileTree, which uses the visitor pattern. Every time a file is found, a method on your visitor object will be called.

package com.willpittman.quickref;

import java.io.IOException;
import java.nio.file.Path;
import java.nio.file.FileSystems;
import java.nio.file.Files;

import java.nio.file.FileVisitor;
import java.nio.file.FileVisitResult;
import java.nio.file.attribute.BasicFileAttributes;

import java.util.ArrayList;


/** Custom FileVisitor
 */
class CollectSampleFilesVisitor implements FileVisitor<Path>
{
    ArrayList<String> sample_files;


    /** Constructor.
     * 
     * @param sample_files   list will be populated with files ending in '.sample' 
     */
    public CollectSampleFilesVisitor(ArrayList<String> sample_files)
    {
        this.sample_files = sample_files;
    }

    /** ignores exceptions */
    public FileVisitResult postVisitDirectory(Path dir, IOException exc)
    {
        return FileVisitResult.CONTINUE;
    }

    /** ignores exceptions */
    public FileVisitResult visitFileFailed(Path file, IOException exc) 
    { 
        return FileVisitResult.CONTINUE; 
    }

    public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) 
    { 
        return FileVisitResult.CONTINUE; 
    }


    /** Files ending in '.sample' get added to ArrayList
     */
    public FileVisitResult 
    visitFile(Path file, BasicFileAttributes attrs)
    {
        if (file.toString().endsWith(".sample")) {
            Path abspath = file.toAbsolutePath();
            this.sample_files.add(abspath.toString());
        }
        return FileVisitResult.CONTINUE;
    }
}



public class App 
{
    public static void main(String[] args)
        throws IOException  // <-- walkFileTree throws
    {
        Path path = FileSystems.getDefault().getPath("/home/will/.config/qutebrowser");
        ArrayList<String> python_files = new ArrayList<String>();
        CollectSampleFilesVisitor visitor = new CollectPythonFilesVisitor(python_files);

        Files.walkFileTree(path, visitor);
        System.out.println(visitor.sample_files);
    }
}


permissions

import java.io.File;

File file = new File('file.txt');

file.canWrite();    // writable as current user/group?
file.canRead();     // readable as current user/group?
file.canExecute();  // executable as current user/group?

read

Stream

import java.io.FileInputStream;

FileInputStream stream = new FileInputStream("/path/to/file.txt");
FileInputStream stream = new FileInputStream(new File("/path/to/file.txt"));

Scanner

import java.io.File; 
import java.util.Scanner;

File file = new File("filename.txt");
Scanner scanner = new Scanner(file); 
while (scanner.hasNextLine()) {
    String data = scanner.nextLine();
    System.out.println(data);
}
scanner.close();

write

import java.io.FileWriter;

FileWriter writer = new FileWriter("filename.txt");
writer.write("line1\nline2\n");
writer.close();

streams

stdout/stderr

System.out.println("stdout");
System.err.println("stderr");

stdin

import java.util.Scanner;
import java.util.IOException;


class StdinHandler()
{
    private Boolean stdin_available()
    {
        Boolean stdin_exists;
        try
        {
            stdin_exists = System.in.available() > 0;
            return stdin_exists;
        }
        catch(java.io.IOException e)
        {
            stdin_exists = false;
            return stdin_exists;
        }
    }
    
    public void print_stdin()
    {
        if (this.stdin_available())
        {
            Scanner scanner = new Scanner(System.in);
            System.out.println(scanner.next());
            while (scanner.hasNext())
            {
                System.out.println(scanner.next());
            }
            scanner.close();
        } else {
            System.out.println("No text on stdin");
        }
    }
}