Saturday, February 9, 2019

Read ZipEntry form ZipInputStream as InputStream

To read ZipEntry from ZipInputStream

public class ZipEntityDemo {
public InputStream extract(ZipInputStream zis, String entityName) throws Exception {
ByteArrayOutputStream out = new ByteArrayOutputStream();
ZipEntry ze = null;
do {
ze = zis.getNextEntry();
if (ze != null && ze.getName().equalsIgnoreCase(entityName)) {
byte[] buffer = new byte[1];
while (zis.available() == 1) {
zis.read(buffer);
out.write(buffer, 0, 1);
}
out.close();
return new ByteArrayInputStream(out.toByteArray());
}
} while (ze != null);
return null;
}
}
Here zis.getNextEntry() will return us the beginning of an entry. If the name of the entry match to our desired name we can start reading. Here we are reading byte by byte in a loop till last byte. We could have improved by using ze.getSize(), and we could read multiple bytes till the size. But the getSize() methods some time returns  -1 for some zipfiles. So it wouldn't be reliable. With out knowing the entry size only way is to read byte by byte till last.

Sunday, January 13, 2019

How to Unzip in Java

Here is a quick java program to unzip or explode a zip file. We will read the zip file with the help of java.util.ZipFile, then we will process each entries inside this. We will read the entries as stream and write to a buffer and eventually to a file output stream.  So at the end we will extract all the elements in the zip, and maintain the same hierarchical structure of directories .Please refer the below example.

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Enumeration;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
public class UnZipDemo {
public static void main(String args[]) throws IOException
{
String zipFileName = "D:\\demo.zip";
ZipFile zipFile = new ZipFile(zipFileName);
String extractedPath = "D:\\demo";
byte[] buffer = new byte[1024];
Enumeration enm = zipFile.entries();
ZipEntry ze = null;
InputStream fis = null;
while (enm.hasMoreElements()) {
ze = (ZipEntry) enm.nextElement();
System.out.println("processing = "+ze.getName());
File newFile = new File(extractedPath + File.separator + ze.getName());
// create all non exists folders
new File(newFile.getParent()).mkdirs();
FileOutputStream fos = new FileOutputStream(newFile);
int len;
fis = zipFile.getInputStream(ze);
while ((len = fis.read(buffer)) > 0) {
fos.write(buffer, 0, len);
}
fos.close();
fis.close();
}
}
}

Thursday, January 3, 2019

Zip files in Java

To create or read zip files in Java, we can use java.util.ZipFile. This allow to read an zip file and read the entries inside it. We can create a zip file by using ZipOutputStream.

package demo.zipfile;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Enumeration;
import java.util.Scanner;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import java.util.zip.ZipOutputStream;
public class ZipFileDemo {
public static void main(String args[]) throws IOException {
// create a zip file
String zipFileName = "D:\\demo.zip";
ZipOutputStream zipos = new ZipOutputStream(new FileOutputStream(zipFileName));
// In Zip Output Stream we can create file.
ZipEntry ze1 = new ZipEntry("file1.txt");
zipos.putNextEntry(ze1);
zipos.write("Hello World".getBytes());
zipos.closeEntry();
// Now lets create another file in a directory
zipos.putNextEntry(new ZipEntry("etc\\file2.txt"));
zipos.write("Hello Again".getBytes());
zipos.closeEntry();
zipos.close();
// To Read Zip file
ZipFile zipFile = new ZipFile(zipFileName);
// for specific entry
ZipEntry ze2 = zipFile.getEntry("file1.txt");
InputStream is = zipFile.getInputStream(ze2);
Scanner scan = new Scanner(is);
while (scan.hasNextLine()){
System.out.println(scan.nextLine());
}
scan.close();
Enumeration enm = zipFile.entries();
while(enm.hasMoreElements()) {
ZipEntry ze = (ZipEntry) enm.nextElement();
System.out.println(ze.getName());
}
}
}

Sunday, December 30, 2018

Java 8 at a glance

In Java  8 following are the major enhancement.

- Lambda Expression
- Method Reference for Lambda Expression
- Java Streams
- Improved Interface

    a) Now we can have concrete methods in an interface. It can be either static or default. Default methods can be overridden in implemented class. If a class implement two or more interface and there is a collision of default method then it is mandatory to override.
    b) Functional interface. For lambda expression we can define an interface as function it will have only one abstract method.
Here is an good article explaining in details # https://www.journaldev.com/2752/java-8-interface-changes-static-method-default-method

- Enhancement to Annotation
More details # https://www.javatpoint.com/java-8-type-annotations-and-repeating-annotations

- Parallel Array Sorting
    java.util.Arrays support sorting in parallel which will be faster.
- Hash Map performance improvement in case of Key collision
- Removed JDBC-ODBC bridge


More details on Java 8 features
http://www.oracle.com/technetwork/java/javase/8-whats-new-2157071.html

Friday, December 28, 2018

Java Streams

Streams are very popular feature in Java 8. Its another step in the direction of supporting functional programming in Java.
Streams are a way of accessing data from various data source. Data source can be an array, any java collection objects, I/O channel (like files, socket etc) or a generator function. One important thing is Streams are not data structure it doesn't store data, it just convey the data from data source.

Streams facilitate various computational operations like fetch, filter, sort, aggregate, search etc. in a efficient way. But all these operations produces a result while not changing its source.
Stream operations are of two types,  intermediate or terminal .Filter and map are examples of intermediate operation For each and reduce are terminal operation. Intermediate operation doesn't get executed instantly ,it creates a new stream. Only after terminal operation it get evaluated.

Intermediate operations are further divided into stateless or stateful. In case of stateless like filter or map no state of previous element is required. But in case of sateful eg: sort or distinct to process new element previous element details are necessary.

By default streams are executed sequential, Streams support parallelism also. So that the elements can be processed in parallel manner.  

Lets see some code.

package demo.streams;

import java.util.Arrays;
import java.util.List;
import java.util.stream.Stream;

public class StreamDemo {

public static void main (String args[])
{
String[] arr = {"python", "perl", "java", "java script", "c", "c++", "html", "sql"};
List<String> strList =  Arrays.asList(arr);
// steam creation
Stream<String> stream  = strList.stream();
// sort the elements
stream.sorted().forEach(System.out::println);
// find first element starts with j
Stream<String> filteredStream = strList.stream().filter(string-> string.startsWith("j"));
System.out.println(filteredStream.findFirst().get());
// in first 4 element how many elements start with p
System.out.println(strList.stream().limit(4).filter(str->str.startsWith("p")).count());
// map
// prepend hello begin of each string
strList.stream().map(str->"Hello "+str).forEach(System.out::println);
// close
filteredStream.close();
stream.close();
// parallel Stream, count the number of letters
strList.parallelStream().map(str->str + "="+ str.length()).forEach(System.out::println);
}
}