Showing posts with label StandardCopyOption. Show all posts
Showing posts with label StandardCopyOption. Show all posts

Monday, August 15, 2016

How to process text files through the console

In the example below, you are going to see a way of writing a code that processes text files in java and does the reading, copying, moving, deleting, listing or searching operations.

import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;

// implements a simplified version of "type" command provided in Windows given
// a text file name(s) as argument, it prints the content of the text file(s) on console 
class Type {
public static void main(String[] files) {
if (files.length == 0) {
System.err.println("pass the name of the file(s) as argument");
System.exit(-1);
}
// process each file passed as argument
for (String file : files) {
// try opening the file with FileReader
try (FileReader inputFile = new FileReader(file)) {
int ch = 0;
// while there are characters to fetch, read, and print the
// characters when EOF is reached, read() will return -1,
// terminating the loop
while ((ch = inputFile.read()) != -1) {
// ch is of type int - convert it back to char
// before printing
System.out.print((char) ch);
}
} catch (FileNotFoundException fnfe) {
// the passed file is not found …
System.err.printf("Cannot open the given file %s ", file);
} catch (IOException ioe) {
// some IO error occurred when reading the file …
System.err.printf("Error when processing file %s… skipping it", file);
}
// try-with-resources will automatically release FileReader object
}
}
}

Yet, a better way to do the same thing using streams:

import java.io.IOException;
import java.nio.file.Paths;
import java.nio.file.Files;
import java.util.Arrays;
import java.util.stream.Stream;

// implements a simplified version of "type" command provided in Windows; 
// given a text file name(s) as argument, it prints the content of the file(s) 

class Type {
private static void processFile(String file) {
try (Stream<String> lines = Files.lines(Paths.get(file))) {
lines.forEach(System.out::println);
} catch (IOException ioe) {
System.err.println("IOException occurred when reading the file... exiting");
System.exit(-1);
}
}

public static void main(String[] files) throws IOException {
if (files.length == 0) {
System.err.println("pass the name of the file(s) as argument");
System.exit(-1);
}
// process each file passed as argument
Arrays.stream(files).forEach(Type::processFile);
}
}

That is it, now, it suffices that you compile your code using the command: javac Type.java.
Then, execute the compiled file using the command: java Type [name of the files you want to read].

On the other hand, if you want to copy a text file into another destination you may make use of the code below:

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;

// implements a simplified version of "copy" command provided in Windows
// syntax: java Copy SrcFile DstFile 
// copies ScrFile to DstFile; over-writes the DstFile if it already exits 
class Copy {
public static void main(String[] files) {
if (files.length != 2) {
System.err.println("Incorrect syntax. Correct syntax: Copy SrcFile DstFile");
System.exit(-1);
}
String srcFile = files[0];
String dstFile = files[1];
// try opening the source and destination file
// with FileReader and FileWriter
try (BufferedReader inputFile = new BufferedReader(new FileReader(srcFile));
BufferedWriter outputFile = new BufferedWriter(new FileWriter(dstFile))) {
int ch = 0;
// while there are characters to fetch, read the characters from
// source stream and write them to the destination stream
while ((ch = inputFile.read()) != -1) {
// ch is of type int - convert it back to char before
// writing it
outputFile.write((char) ch);
}
// no need to call flush explicitly for outputFile - the close()
// method will first call flush before closing the outputFile stream
} catch (FileNotFoundException fnfe) {
// the passed file is not found …
System.err.println("Cannot open the file " + fnfe.getMessage());
} catch (IOException ioe) {
// some IO error occurred when reading the file …
System.err.printf("Error when processing file; exiting ... ");
}
// try-with-resources will automatically release FileReader object
}
}

Now, it suffices that you compile your code and execute it giving two arguments the source and the destination file. Yet, a better way to do the copying operation is by using the Paths utility as follows:

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

public class FileCopy {
    public static void main(String[] args) {
        if(args.length != 2){
            System.out.println("usage: FileCopy <source-path> <destination-path>");
            System.exit(1);
        }
        Path pathSource = Paths.get(args[0]);
        Path pathDestination = Paths.get(args[1]);
        try {
            Files.copy(pathSource, pathDestination);
            System.out.println("Source file copied successfully");                
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

Moreover, sometimes you might want to move a file to another destination rather than copying it. The following code represents a way to do so:

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;

public class FileMove {
public static void main(String[] args) {
if (args.length != 2) {
System.out.println("usage: FileMove <source-path> <destination-path>");
System.exit(-1);
}
Path pathSource = Paths.get(args[0]);
Path pathDestination = Paths.get(args[1]);
try {
Files.move(pathSource, pathDestination, StandardCopyOption.REPLACE_EXISTING);
System.out.println("Source file moved successfully");
} catch (IOException e) {
e.printStackTrace();
}
}
}

In order to remove a file, here is one way of proceding:

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

public class FileDelete {
public static void main(String[] args) {
if (args.length != 1) {
System.out.println("usage: FileDelete <source-path>");
System.exit(1);
}
Path pathSource = Paths.get(args[0]);
try {
Files.delete(pathSource);
System.out.println("File deleted successfully");
} catch (IOException e) {
e.printStackTrace();
}
}
}

In order to list files within the current directory, you might use the following code:

import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.io.IOException;
import java.util.stream.Stream;

class ListFiles {
public static void main(String[] args) throws IOException {
try (Stream<Path> entries = Files.list(Paths.get("."))) {
entries.forEach(System.out::println);
}
}
}

Another useful case is to find files with a specific extension within the current directory, here is a smart manner to look for .class files using streams:

import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.io.IOException;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.function.BiPredicate;
import java.util.stream.Stream;

class FindFiles {
public static void main(String[] args) throws IOException {
BiPredicate<Path, BasicFileAttributes> predicate = (path, attrs) -> attrs.isRegularFile()
&& path.toString().endsWith("class");
try (Stream<Path> entries = Files.find(Paths.get("."), 4, predicate)) {
entries.limit(100).forEach(System.out::println);
}
}
}