How to recursively list all text files in a directory?

In this example you’ll learn how to use the Files.walkFileTree() to walk through file tree. This method requires two parameters. The first parameter is the starting file, in this example we’ll start from drive F:/Temp. And the second parameter is the file visitor to invoke for each file. Here we’ll create a file visitor call FindTextFilesVisitor which extend the java.nio.file.SimpleFileVisitor.

To get all the text files (files end with .txt) we override the visitFile() defined by the SimpleFileVisitor. In this method we check if the file ends with .txt extension and print the file name when the extension matches. And we continue to walk the file tree by returning FileVisitResult.CONTINUE.

package org.kodejava.io;

import java.io.IOException;
import java.nio.file.*;
import java.nio.file.attribute.BasicFileAttributes;

public class WalkFileTree {
    public static void main(String[] args) {
        try {
            Path startDir = Paths.get("F:/Temp");
            Files.walkFileTree(startDir, new FindTextFilesVisitor());
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * FindTextFilesVisitor.
     */
    static class FindTextFilesVisitor extends SimpleFileVisitor<Path> {
        @Override
        public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
            if (file.toString().endsWith(".txt")) {
                System.out.println(file.getFileName());
            }
            return FileVisitResult.CONTINUE;
        }
    }
}

Instead of listing files, you can modify the code snippet above for instance use it to delete all the files that ends with .bak. Simply change the extension and replace the print-out statement with a file delete statement in the visitFile() method.

How to remove non ASCII characters from a string?

The code snippet below remove the characters from a string that is not inside the range of x20 and x7E ASCII code. The regex below strips non-printable and control characters. But it also keeps the linefeed character n (x0A) and the carriage return r (x0D) characters.

package org.kodejava.regex;

public class ReplaceNonAscii {
    public static void main(String[] args) {
        String str = "Thè quïck brøwn føx jumps over the lãzy dôg.";
        System.out.println("str = " + str);

        // Replace all non ascii chars in the string.
        str = str.replaceAll("[^\\x0A\\x0D\\x20-\\x7E]", "");
        System.out.println("str = " + str);
    }
}

Snippet output:

str = Thè quïck brøwn føx jumps over the lãzy dôg.
str = Th quck brwn fx jumps over the lzy dg.

How to verify digital signature of a signed data?

In this example we will learn how to verify the digital signature of the previously signed data. To sign the data you can see the previous example on this post How to create a digital signature and sign data?.

Here the code snippet:

package org.kodejava.security;

import java.nio.file.Files;
import java.nio.file.Paths;
import java.security.KeyFactory;
import java.security.PublicKey;
import java.security.Signature;
import java.security.spec.X509EncodedKeySpec;

public class VerifyDigitalSignature {
    public static void main(String[] args) {
        try {
            byte[] publicKeyEncoded = Files.readAllBytes(Paths.get("publickey"));
            byte[] digitalSignature = Files.readAllBytes(Paths.get("signature"));

            X509EncodedKeySpec publicKeySpec = new X509EncodedKeySpec(publicKeyEncoded);
            KeyFactory keyFactory = KeyFactory.getInstance("DSA", "SUN");

            PublicKey publicKey = keyFactory.generatePublic(publicKeySpec);
            Signature signature = Signature.getInstance("SHA1withDSA", "SUN");
            signature.initVerify(publicKey);

            byte[] bytes = Files.readAllBytes(Paths.get("README.md"));
            signature.update(bytes);

            boolean verified = signature.verify(digitalSignature);
            if (verified) {
                System.out.println("Data verified.");
            } else {
                System.out.println("Cannot verify data.");
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

How to split a string by a number of characters?

The following code snippet will show you how to split a string by numbers of characters. We create a method called splitToNChars() that takes two arguments. The first arguments is the string to be split and the second arguments is the split size.

This splitToNChars() method will split the string in a for loop. First we’ll create a List object that will store parts of the split string. Next we do a loop and get the substring for the defined size from the text and store it into the List. After the entire string is read we convert the List object into an array of String by using the List‘s toArray() method.

Let’s see the code snippet below:

package org.kodejava.lang;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class SplitStringForEveryNChar {
    public static void main(String[] args) {
        String text = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";

        System.out.println(Arrays.toString(splitToNChar(text, 3)));
        System.out.println(Arrays.toString(splitToNChar(text, 4)));
        System.out.println(Arrays.toString(splitToNChar(text, 5)));
    }

    /**
     * Split text into n number of characters.
     *
     * @param text the text to be split.
     * @param size the split size.
     * @return an array of the split text.
     */
    private static String[] splitToNChar(String text, int size) {
        List<String> parts = new ArrayList<>();

        int length = text.length();
        for (int i = 0; i < length; i += size) {
            parts.add(text.substring(i, Math.min(length, i + size)));
        }
        return parts.toArray(new String[0]);
    }
}

When run the code snippet will output:

[ABC, DEF, GHI, JKL, MNO, PQR, STU, VWX, YZ]
[ABCD, EFGH, IJKL, MNOP, QRST, UVWX, YZ]
[ABCDE, FGHIJ, KLMNO, PQRST, UVWXY, Z]

How to create a digital signature and sign data?

In the following code snippet you will learn how to generate a digital signature to sign a data or file. To create a signature we will need a key pair of public and private key. But for the signing process we’ll only use the private key, while the public key will be used to verify the signature.

To create a digital signature we need an instance of java.security.Signature. To get one we can call the Signature.getInstance() method and pass the algorithm and the provider arguments. In this code snippet we’ll use SHA1withDSA and SUN for the algorithm and provider.

But before we can use the Signature object we have to initialize it first with a PrivateKey. You can also see how to get a private key in the code snippet below. To initialize call the Signature‘s initSign() method.

And finally to generate the digital signature we need to update the Signature using the data that we are going to sign. To do this we read the file into byte[] using the helps of Files.readAllBytes() and supply the bytes into the Signature object using the update() method. To get the signature we call the sign() method which will return us a byte array of the signature.

And here is the complete code snippet:

package org.kodejava.security;

import java.nio.file.Files;
import java.nio.file.Paths;
import java.security.*;

public class GenerateDigitalSignature {
    public static void main(String[] args) {
        try {
            // Get instance and initialize a KeyPairGenerator object.
            KeyPairGenerator keyGen = KeyPairGenerator.getInstance("DSA", "SUN");
            SecureRandom random = SecureRandom.getInstance("SHA1PRNG", "SUN");
            keyGen.initialize(1024, random);

            // Get a PrivateKey from the generated key pair.
            KeyPair keyPair = keyGen.generateKeyPair();
            PrivateKey privateKey = keyPair.getPrivate();

            // Get an instance of Signature object and initialize it.
            Signature signature = Signature.getInstance("SHA1withDSA", "SUN");
            signature.initSign(privateKey);

            // Supply the data to be signed to the Signature object
            // using the update() method and generate the digital
            // signature.
            byte[] bytes = Files.readAllBytes(Paths.get("README.md"));
            signature.update(bytes);
            byte[] digitalSignature = signature.sign();

            // Save digital signature and the public key to a file.
            Files.write(Paths.get("signature"), digitalSignature);
            Files.write(Paths.get("publickey"), keyPair.getPublic().getEncoded());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

On the next examples we are going to verify the digital signature. To verify the digital signature is to make sure that the data was sent by the original creator without any modification. To verify we’ll need the digital signature and the public key of the key pair. To get these in the code snippet above we have saved both the digital signature and the public key to files.