package org.jchecksum;

import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.ByteChannel;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

/**
 * This class allows to calculate checksum of a file.
 */
public class JChecksum {
    public static void main(String[] args) {
        try {
            System.out.println(new JChecksum().getChecksum(args[0], Integer.valueOf(args[1])));
        } catch (IOException e) {
            e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
        }
    }

    public String getChecksum(String filePath, int size) throws IOException, NoSuchAlgorithmException {
        final Path path = Paths.get(filePath);
        final ByteBuffer buffer = ByteBuffer.allocate(size);
        MessageDigest messageDigest = MessageDigest.getInstance("MD5");

        try (ByteChannel byteChannel = Files.newByteChannel(path, StandardOpenOption.READ)) {
            int read = 0;
            while ((read = byteChannel.read(buffer)) > 0) {
                buffer.limit(read);
                messageDigest.update(buffer);
                buffer.clear();
            }
        }

        final StringBuilder stringBuilder = new StringBuilder();
        for (final byte b : messageDigest.digest()) {
            stringBuilder.append(String.format("%xd", b));
        }

        return stringBuilder.toString();
    }
}

@@ -415,21 +415,22 @@
    p
-ublic
+rivate
  static 
 void
@@ -429,451 +429,695 @@
 tic 
-void main(String%5B%5D args) %7B%0A        try %7B%0A            System.out.println(new JChecksum().getChecksum(args%5B0%5D, Integer.valueOf(args%5B1%5D)));
+final int BUFFER_SIZE = 256 * 1024;%0A%0A    /**%0A     * Indicates the size of the buffer to use when reading files. You may override this method in case the default%0A     * buffer size (256K) doesn't suit you.
 %0A     
+*%0A
    
-%7D catch (IOException e) %7B%0A   
+  * @return the size of the buffer.%0A
      
+*/%0A
     
-e.printStackTrace();  //To change body of catch statement use File %7C Settings %7C File Templates.%0A        %7D catch (NoSuchAlgorithmException e) %7B%0A            e.printStackTrace();  //To change body of catch statement use File %7C Settings %7C File Templates.%0A        %7D
+public int withBufferSizeOf() %7B%0A        return BUFFER_SIZE;%0A    %7D%0A%0A    private MessageDigest getMessageDigest(String algorithm) %7B%0A        try %7B%0A            return MessageDigest.getInstance(algorithm);%0A        %7D catch (NoSuchAlgorithmException e) %7B%0A            throw new RuntimeException(e);%0A        %7D%0A    %7D%0A%0A    public final String sha1(String file) throws IOException %7B%0A        return hash(file, getMessageDigest(%22SHA-1%22));
 %0A   
@@ -1135,26 +1135,25 @@
 lic 
+final 
 String 
-getChecksum
+hash
 (Str
@@ -1164,59 +1164,48 @@
 file
-Path, int size) throws IOException, NoSuchAlgorithm
+, MessageDigest messageDigest) throws IO
 Exce
@@ -1252,20 +1252,16 @@
 get(file
-Path
 );%0A     
@@ -1312,85 +1312,33 @@
 cate
-(size);%0A        MessageDigest messageDigest = MessageDigest.getInstance(%22MD5%22
+Direct(withBufferSizeOf()
 );%0A%0A
@@ -1350,16 +1350,22 @@
    try (
+final 
 ByteChan
@@ -1461,12 +1461,8 @@
 read
- = 0
 ;%0A  

add ideal buffer size after intensive benchmarks.