How
to avoid downloading same file again to your local machine from server by using
MD5 algorithm?
Note: do have a checksum file
on server with same extension of the files you are going
to download.
Eg. You are going to
download test.jar and Config.properties.
You should create hash/checksum of
these files on
Server with extension as
test.jar.sh and Config.properties.sh,
These file will have content as there
check sum.
Below class will perform
the checked download of the file you are going to download
from the server.
Means, if the same file is
already in your machine, it will compare the checksum
of the server file which
we will download at very first.
At a very first, if the
checksum files folder is empty, it will download all the files from
the server.
On second time, if there is
any change in the file on server, then the checksum
of that file will change
and we will download that zip folder and extract on put local machine.
Then we will compare the
local machine files checksum and newly downloaded
checksum file’s folder.
If
there is difference, it will download the fresh copy of the file else not.
---------------------------------------------------------------------------------
Code:
--------------------------------------------------------------------------------
|
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.nio.channels.Channels;
import java.nio.channels.FileChannel;
import java.nio.channels.ReadableByteChannel;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Enumeration;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
public class Test {
// server path
from where the files will download
static String serverSHFilesPath = "http://localhost:8080/examples/server/serverSH.zip";
// the file which
you want to download after checking checksum
static String serverDownloadFilesPath = "http://localhost:8080/examples/server/";
// location on
local machine where the files will get download after
// checksum or by
default
// on first time
static String destPath = "C:/Users/UserName/AppData/Roaming/download/";
// path where
server checksum files will get download
static String destPathServerSH = "C:/Users/UserName/AppData/Roaming/download/serverSH/";
static String destPathLocalSH = "C:/Users/UserName/AppData/Roaming/download/localSH/";
static String serverSHName = "serverSH.zip";
// name of the
file which will be downloading
static String downloadFile = "Config.properties";
public static void main(String[] args) throws
MalformedURLException,
NoSuchAlgorithmException,
IOException {
createFilesFolderPath(destPathServerSH);
downloadServerSHFiles(serverSHFilesPath,
Paths.get(destPathServerSH, serverSHName).toString());
downloadingFiles(serverDownloadFilesPath, destPath, downloadFile,
destPathServerSH);
}
private static void
downloadServerSHFiles(String serverPropsPath2,
String
destPathServerSH2) throws
MalformedURLException, IOException {
InputStream openStream = new URL(serverPropsPath2).openStream();
try
(ReadableByteChannel in = Channels.newChannel(openStream);
FileChannel
out = new FileOutputStream(destPathServerSH2)
.getChannel())
{
out.transferFrom(in, 0, Long.MAX_VALUE);
}
//unzip checksum folder on local
unzip(destPathServerSH2, destPath);
//delete after unzipping
deleteZipFolders(destPathServerSH2);
}
public static void
downloadingFiles(String serverDownloadFilesPath,
String
destPath, String downloadFile, String destPathServerSH)
throws
MalformedURLException, IOException, NoSuchAlgorithmException {
//
copyFile(createFilesFolderPath, serverPropsPath);
MessageDigest
md5 = null;
md5 = MessageDigest.getInstance("MD5");
InputStream openStream = new URL(serverDownloadFilesPath + downloadFile)
.openStream();
// careate
path on local where you have intend to download the files
createFilesFolderPath(destPath);
StringBuilder
sb = null;
// logic to check
the file you are going to download are already
// downloaded
and are not changed
File fLocal = new File(Paths.get(destPathLocalSH,
downloadFile + ".sh.txt").toString());
File fServer = new File(Paths.get(destPathServerSH,
downloadFile + ".sh.txt").toString());
// if the
checksum file exist on local machine then enter in if
// condition
if (fLocal.exists()) {
// sb =
calculateHash(destPath, downloadFile, md5);
String
localFileSH = new String(Files.readAllBytes(Paths.get(fLocal
.getAbsolutePath())));
String
serverFileSH = new String(Files.readAllBytes(Paths
.get(fServer.getAbsolutePath())));
System.out.println("Hash value
of file : " + downloadFile + " : "
+
localFileSH);
//same hashcode
then don’t download
if (serverFileSH.equals(localFileSH)) {
System.out
.println(" hash code
is same !!! no need to download the file ");
} else {
//different checksum, update local copy of checksum file and
download file as well
BufferedWriter
writer = new BufferedWriter(new FileWriter(fLocal));
writer.write(serverFileSH.toString());
writer.close();
try
(ReadableByteChannel in = Channels.newChannel(openStream);
FileChannel
out = new FileOutputStream(destPath
+
downloadFile).getChannel()) {
out.transferFrom(in, 0, Long.MAX_VALUE);
}
System.out
.println("Successfully
re-downloaded and verified
checksum!"
+
localFileSH);
}
} else {
// unzip
code
try
(ReadableByteChannel in = Channels.newChannel(openStream);
FileChannel
out = new FileOutputStream(destPath
+
downloadFile).getChannel()) {
out.transferFrom(in, 0, Long.MAX_VALUE);
}
sb = calculateHash(destPath, downloadFile, md5);
BufferedWriter
writer = new BufferedWriter(new FileWriter(fLocal));
writer.write(sb.toString());
writer.close();
String
contents = new String(Files.readAllBytes(Paths.get(fLocal
.getAbsolutePath())));
System.out
.println("Successfully
downloaded and verified
checksum!"
+
contents);
}
}
public static String
createFilesFolderPath(String zaraOpsLocalPath) {
File file = new File(zaraOpsLocalPath);
if (!file.exists()) {
if (file.mkdirs()) {
return zaraOpsLocalPath;
} else {
System.out.println("Failed to
create directory!");
}
}
return zaraOpsLocalPath;
}
private static void copyFiles(File source, File dest, String downloadFile,
String
destPath) throws IOException {
if (downloadFile.contains("ConfigProp.zip")) {
File propDel = new File(destPath + "Config.properties");
propDel.delete();
}
if (downloadFile.contains(".zip")) {
String
replace = downloadFile.replace(".zip", "");
File propDel = new File(destPath + replace);
boolean deleteDirectory = deleteDirectory(propDel);
if (deleteDirectory)
System.out.println(" file :
"
+ deleteDirectory + "
deleted.");
}
if (dest.exists())
dest.delete();
Files.copy(source.toPath(), dest.toPath());
}
public static boolean
deleteDirectory(File directory) {
if (directory.exists()) {
File[]
files = directory.listFiles();
if (null != files) {
for (int i = 0; i < files.length; i++) {
if (files[i].isDirectory()) {
deleteDirectory(files[i]);
}
else {
files[i].delete();
}
}
}
}
return (directory.delete());
}
private static StringBuilder
calculateHash(String destPath,
String
downloadFile, MessageDigest md5)
throws
FileNotFoundException, IOException {
StringBuilder
sb = new StringBuilder();
byte[] dataBytes = new byte[1024];
int nread = 0;
FileInputStream
fis = new FileInputStream(destPath + downloadFile);
while ((nread = fis.read(dataBytes)) != -1)
md5.update(dataBytes, 0, nread);
fis.close();
byte[] mdbytes = md5.digest();
for (int i = 0; i < mdbytes.length; i++)
sb.append(Integer.toString((mdbytes[i] & 0xff) +
0x100, 16)
.substring(1));
return sb;
}
private static void unzip(String zipFilePath, String destDir) {
if (zipFilePath.contains(".zip")) {
try {
File
dir = new File(destDir);
// create output
directory if it doesn't exist
if (!dir.exists())
dir.mkdirs();
// Open the zip
file
ZipFile
zipFile = new ZipFile(zipFilePath);
Enumeration<?>
enu = zipFile.entries();
while (enu.hasMoreElements())
{
ZipEntry
zipEntry = (ZipEntry) enu.nextElement();
String
fileName = zipEntry.getName();
// Do we need to
create a directory ?
File
file = new File(destDir + File.separator + fileName);
System.out.println("Unzipping
to : "
+
file.getAbsolutePath());
if (fileName.endsWith("/")) {
file.mkdirs();
continue;
}
File
parent = file.getParentFile();
if (parent != null) {
parent.mkdirs();
}
// Extract the
file
InputStream
is = zipFile.getInputStream(zipEntry);
FileOutputStream
fos = new FileOutputStream(file);
byte[] bytes = new byte[1024];
int length;
while ((length = is.read(bytes)) >= 0) {
fos.write(bytes, 0, length);
}
is.close();
fos.close();
}
zipFile.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
private static void
deleteZipFolders(String zipFilePath) {
// TODO Auto-generated
method stub
File file = new File(zipFilePath);
if (zipFilePath.contains(".zip")) {
file.delete();
System.out.println("deleted :
"
+ file.getName());
}
}
}
|
Output:
This hierarchy will get
generated after executing above code.
Inside localSH folder..
Inside serverSH… you can iterate all the files to download and
check checksum..
On server, this can be created by creating a web service which will
generate these files on server and stored as zip.
Content of these files will be something like below screen shot :
No comments:
Post a Comment