Monday 5 March 2018

How to write multiple input streams to a file

In this post, I am going to show you how to read the data from multiple input streams and write to a file. Let me explain an example with plain java code and later I am going to show you how can we simplify the same code using SequenceInputStream class provided by Java.

Below snippet reads the data from multiple input streams and write to the file.

byte[] buffer = new byte[BUFFER_SIZE];
int bytesRead;

try (OutputStream outputStream = new FileOutputStream(file)) {
         for (InputStream inputStream : inputStreams) {
                  if (inputStream == null) {
                           continue;
                  }
                  while ((bytesRead = inputStream.read(buffer)) != -1) {
                           outputStream.write(buffer, 0, bytesRead);
                  }
         }

}

Find the below working application.

FileUtil.java
package com.sample.util;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

public class FileUtil {

 private static final int BUFFER_SIZE = 4096;

 /**
  * Reads the data from multiple input streams and write to the file.
  * 
  * @param file
  * @param inputStreams
  * @throws IOException
  * @throws FileNotFoundException
  */
 public static void writeToFile(File file, InputStream... inputStreams) throws FileNotFoundException, IOException {
  if (file == null) {
   throw new IllegalArgumentException("file should not be null");
  }

  if (inputStreams == null) {
   throw new IllegalArgumentException("inputStreams can't be null");
  }

  byte[] buffer = new byte[BUFFER_SIZE];
  int noOfBytesRead;

  try (OutputStream outputStream = new FileOutputStream(file)) {
   for (InputStream inputStream : inputStreams) {
    if (inputStream == null) {
     continue;
    }
    while ((noOfBytesRead = inputStream.read(buffer)) != -1) {
     outputStream.write(buffer, 0, noOfBytesRead);
    }
   }

  } finally {
   for (InputStream inputStream : inputStreams) {
    if (inputStream == null) {
     continue;
    }

    inputStream.close();
   }
  }
 }

 public static void writeToFile(String filePath, InputStream... inputStreams)
   throws FileNotFoundException, IOException {
  writeToFile(new File(filePath), inputStreams);
 }
}

Test.java
package com.sample.test;

import java.io.FileInputStream;
import java.io.InputStream;

import com.sample.util.FileUtil;

public class Test {
 public static void main(String args[]) throws Exception {
  String destinationPath = "C:\\Users\\krishna\\dest.log";
  
  String logFile1 = "C:\\Users\\krishna\\app1.log";
  String logFile2 = "C:\\Users\\krishna\\app2.log";
  String logFile3 = "C:\\Users\\krishna\\app3.log";
  
  InputStream inputStream1 = new FileInputStream(logFile1);
  InputStream inputStream2 = new FileInputStream(logFile2);
  InputStream inputStream3 = new FileInputStream(logFile3);
  
  FileUtil.writeToFile(destinationPath, inputStream1, inputStream2, inputStream3);
  
 }
}

Java provides 'SequenceInputStream' class, this is used to process collection of input stream in one shot.

'SequenceInputStream' provides below constructors.
SequenceInputStream(Enumeration<? extends InputStream> e)
SequenceInputStream(InputStream s1, InputStream s2)

Step 1: Create a SequenceInputStream from enumeration of input streams
InputStream inputStream1 = new FileInputStream(logFile1);
InputStream inputStream2 = new FileInputStream(logFile2);
InputStream inputStream3 = new FileInputStream(logFile3);

List<InputStream> inputStreams = Arrays.asList(inputStream1, inputStream2, inputStream3);

Enumeration<InputStream> e = Collections.enumeration(inputStreams);

Step 2: Now write the content to the file using SequenceInputStream.

try (OutputStream outputStream = new FileOutputStream(file)) {
         while ((noOfBytesRead = sequenceInputStream.read(buffer)) != -1) {
                  outputStream.write(buffer, 0, noOfBytesRead);
         }
}

Find the below working example.


FileUtil.java
package com.sample.util;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.SequenceInputStream;

public class FileUtil {

 private static final int BUFFER_SIZE = 4096;

 /**
  * Reads the data from multiple input streams and write to the file.
  * 
  * @param file
  * @param inputStreams
  * @throws IOException
  * @throws FileNotFoundException
  */
 public static void writeToFile(File file, SequenceInputStream sequenceInputStream)
   throws FileNotFoundException, IOException {
  if (file == null) {
   throw new IllegalArgumentException("file should not be null");
  }

  if (sequenceInputStream == null) {
   throw new IllegalArgumentException("sequenceInputStream can't be null");
  }

  byte[] buffer = new byte[BUFFER_SIZE];
  int noOfBytesRead;

  try (OutputStream outputStream = new FileOutputStream(file)) {
   while ((noOfBytesRead = sequenceInputStream.read(buffer)) != -1) {
    outputStream.write(buffer, 0, noOfBytesRead);
   }
  } finally {
   sequenceInputStream.close();
  }
 }

 public static void writeToFile(String filePath, SequenceInputStream sequenceInputStream)
   throws FileNotFoundException, IOException {
  writeToFile(new File(filePath), sequenceInputStream);
 }
}

Test.java
package com.sample.test;

import java.io.FileInputStream;
import java.io.InputStream;
import java.io.SequenceInputStream;
import java.util.Arrays;
import java.util.Collections;
import java.util.Enumeration;
import java.util.List;

import com.sample.util.FileUtil;

public class Test {
 public static void main(String args[]) throws Exception {
  String destinationPath = "C:\\Users\\krishna\\dest.log";

  String logFile1 = "C:\\Users\\krishna\\app1.log";
  String logFile2 = "C:\\Users\\krishna\\app2.log";
  String logFile3 = "C:\\Users\\krishna\\app3.log";

  InputStream inputStream1 = new FileInputStream(logFile1);
  InputStream inputStream2 = new FileInputStream(logFile2);
  InputStream inputStream3 = new FileInputStream(logFile3);

  List<InputStream> inputStreams = Arrays.asList(inputStream1, inputStream2, inputStream3);

  Enumeration<InputStream> e = Collections.enumeration(inputStreams);
  SequenceInputStream sequenceInputStream = new SequenceInputStream(e);

  FileUtil.writeToFile(destinationPath, sequenceInputStream);

 }
}

No comments:

Post a Comment