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