Showing posts with label InputStream. Show all posts
Showing posts with label InputStream. Show all posts

Sunday, 7 April 2024

Copy InputStream to OutputStream in Java

In Java, copying data from an InputStream to an OutputStream is a common task, especially when dealing with file operations, network communications, or handling HTTP requests. In this blog post, we'll explore efficient methods to perform this operation, discussing best practices and potential pitfalls along the way.

 

Below are several scenarios in which copying an InputStream to an OutputStream is common in Java:

 

1.   Data Forwarding: In situations where you need to transfer data from one stream to another, such as redirecting the output of one program to serve as input for another.

2.   File Persistence: When dealing with an InputStream sourced from a network request or another origin, you may want to replicate its content into a FileOutputStream to persist the data into a file.

3.   Temporary Data Storage: Utilizing a ByteArrayOutputStream, you can duplicate a stream's content into memory temporarily, facilitating subsequent processing operations.

 

Approach 1: Using plain core java InputStream and OutputStream classes.

 

IOStreamUtil1.java

package com.sample.app.util;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

public class IOStreamUtil1 {

	private IOStreamUtil1() {
		// Restrict to create an object to this
	}

	public static final int DEFAULT_BUFFER_SIZE = 8192;

	public static long copy(InputStream inputStream, OutputStream outputStream, boolean closeOutputStream)
			throws IOException {
		return copy(inputStream, outputStream, closeOutputStream, new byte[DEFAULT_BUFFER_SIZE]);
	}

	public static long copy(InputStream inputStream, OutputStream outputStream, boolean closeOutputStream,
			byte[] buffer) throws IOException {

		if (inputStream == null) {
			throw new IllegalArgumentException("inputStream is null");
		}

		if (outputStream == null) {
			throw new IllegalArgumentException("outputStream is null");
		}

		try (InputStream in = inputStream) {
			long total = 0;

			int res = -1;

			while ((res = in.read(buffer)) != -1) {
				total += res;
				if (outputStream != null) {
					outputStream.write(buffer, 0, res);
				}
			}

			if (closeOutputStream) {
				outputStream.close();
			} else {
				outputStream.flush();
			}

			return total;
		}
	}
	
	public static void main(String[] args) throws IOException {
		// Create sample input and output streams
        ByteArrayInputStream inputStream = new ByteArrayInputStream("Hello, World!".getBytes());
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();

        // Test the copy method
        long bytesCopied = copy(inputStream, outputStream, true);

        // Print the result
        System.out.println("Bytes copied: " + bytesCopied);
        System.out.println("Output stream content: " + outputStream.toString());
	}
}

 

Output

Bytes copied: 13
Output stream content: Hello, World!

Approach 2: Using InputStream#transferTo method.

 

public long transferTo(OutputStream out) throws IOException

This method is introduced in Java9. Reads all bytes from this input stream and writes the bytes to the given output stream in the order that they are read. On return, this input stream will be at end of stream. This method does not close either stream. If the total number of bytes transferred is greater than Long.MAX_VALUE, then Long.MAX_VALUE will be returned.

 


IOStreamUtil2.java

 

package com.sample.app.util;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

public class IOStreamUtil2 {

	public static long copy(InputStream inputStream, OutputStream outputStream) throws IOException {

		if (inputStream == null) {
			throw new IllegalArgumentException("inputStream is null");
		}

		if (outputStream == null) {
			throw new IllegalArgumentException("outputStream is null");
		}

		return inputStream.transferTo(outputStream);

	}

	public static void main(String[] args) throws IOException {
		// Create sample input and output streams
		ByteArrayInputStream inputStream = new ByteArrayInputStream("Hello, World!".getBytes());
		ByteArrayOutputStream outputStream = new ByteArrayOutputStream();

		// Test the copy method
		long bytesCopied = copy(inputStream, outputStream);

		// Print the result
		System.out.println("Bytes copied: " + bytesCopied);
		System.out.println("Output stream content: " + outputStream.toString());
	}
}

Approach 3: Using Apache commons IOUtils.copy method.

 

Apache Commons IO library provides utility methods for working with streams, including copying streams efficiently. Using this library simplifies the code and makes it more readable.

 

public static int copy(final InputStream inputStream, final OutputStream outputStream) throws IOException

Copies bytes from an InputStream to an OutputStream. Large streams (over 2GB) will return a bytes copied value of -1 after the copy has completed since the correct number of bytes cannot be returned as an int. For large streams use the copyLarge(InputStream, OutputStream) method.

 

IOStreamUtil3.java

package com.sample.app.util;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

import org.apache.commons.io.IOUtils;

public class IOStreamUtil2 {

	public static int copy(InputStream inputStream, OutputStream outputStream) throws IOException {

		if (inputStream == null) {
			throw new IllegalArgumentException("inputStream is null");
		}

		if (outputStream == null) {
			throw new IllegalArgumentException("outputStream is null");
		}

		int noOfBytesopied = IOUtils.copy(inputStream, outputStream);
		return noOfBytesopied;
	}

	public static void main(String[] args) throws IOException {
		// Create sample input and output streams
		ByteArrayInputStream inputStream = new ByteArrayInputStream("Hello, World!".getBytes());
		ByteArrayOutputStream outputStream = new ByteArrayOutputStream();

		// Test the copy method
		long bytesCopied = copy(inputStream, outputStream);

		// Print the result
		System.out.println("Bytes copied: " + bytesCopied);
		System.out.println("Output stream content: " + outputStream.toString());
	}
}

Approach 4: Using IOUtils.copyLarge method.

public static long copyLarge(final InputStream inputStream, final OutputStream outputStream) throws IOException

public static long copyLarge(final InputStream inputStream, final OutputStream outputStream, final byte[] buffer)

Copies bytes from a large (over 2GB) InputStream to an OutputStream This method buffers the input internally, so there is no need to use a BufferedInputStream. Default buffer size is 8192 bytes.

 

IOStreamUtil4.java

package com.sample.app.util;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

import org.apache.commons.io.IOUtils;

public class IOStreamUtil3 {

	public static long copy(InputStream inputStream, OutputStream outputStream) throws IOException {

		if (inputStream == null) {
			throw new IllegalArgumentException("inputStream is null");
		}

		if (outputStream == null) {
			throw new IllegalArgumentException("outputStream is null");
		}

		long noOfBytesopied = IOUtils.copyLarge(inputStream, outputStream);
		return noOfBytesopied;
	}

	public static void main(String[] args) throws IOException {
		// Create sample input and output streams
		ByteArrayInputStream inputStream = new ByteArrayInputStream("Hello, World!".getBytes());
		ByteArrayOutputStream outputStream = new ByteArrayOutputStream();

		// Test the copy method
		long bytesCopied = copy(inputStream, outputStream);

		// Print the result
		System.out.println("Bytes copied: " + bytesCopied);
		System.out.println("Output stream content: " + outputStream.toString());
	}
}

Approach 5: Using Java NIO

Java NIO offers a non-blocking I/O API that can also be used for efficient stream copying. This approach is particularly useful when dealing with large files or when performance is critical.

 

IOStreamUtil5.java

package com.sample.app.util;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.ByteBuffer;
import java.nio.channels.Channels;
import java.nio.channels.ReadableByteChannel;
import java.nio.channels.WritableByteChannel;

public class IOStreamUtil4 {

	public static void copy(InputStream inputStream, OutputStream outputStream, boolean closeOutputStream)
			throws IOException {

		if (inputStream == null) {
			throw new IllegalArgumentException("inputStream is null");
		}

		if (outputStream == null) {
			throw new IllegalArgumentException("outputStream is null");
		}

		try (InputStream inp = inputStream;
				ReadableByteChannel inChannel = Channels.newChannel(inp);
				WritableByteChannel outChannel = Channels.newChannel(outputStream)) {
			ByteBuffer buffer = ByteBuffer.allocateDirect(8192); // 8KB buffer size
			while (inChannel.read(buffer) != -1) {
				buffer.flip();
				outChannel.write(buffer);
				buffer.clear();
			}
		}

		if (closeOutputStream) {
			outputStream.close();
		} else {
			outputStream.flush();
		}

	}

	public static void main(String[] args) throws IOException {
		// Create sample input and output streams
		ByteArrayInputStream inputStream = new ByteArrayInputStream("Hello, World!".getBytes());
		ByteArrayOutputStream outputStream = new ByteArrayOutputStream();

		// Test the copy method
		copy(inputStream, outputStream, true);

		System.out.println("Output stream content: " + outputStream.toString());
	}
}

Copying data from an InputStream to an OutputStream is a fundamental operation in Java programming. By using buffered streams, leveraging third-party libraries like Apache Commons IO, or utilizing the Java NIO package, you can perform this task efficiently and effectively. Consider your specific requirements, such as performance, resource usage, and code readability, when choosing the appropriate method for copying streams in your Java applications.


 

You may like

file and stream programs in Java

Write InputStream to a file in Java

File separator, separatorChar, pathSeparator, pathSeparatorChar in Java

Implement an Output stream that writes the data to two output streams

Check whether directory can be accessed and has read and write privileges in Java

Get the hash or message digest of a file in Java

Saturday, 11 February 2023

Write InputStream to a file in Java

In this post, I am going to explain how to write the content of an InputStream to a file.

 


 

 

Approach 1: Using InputStream read method.

public static void writeInputStreamToAFile1(final InputStream inputStream, final String filePath)
        throws IOException {
    checkInput(inputStream, filePath);

    File newFile = new File(filePath);

    // create parent dirs if necessary
    newFile.getParentFile().mkdirs();
    newFile.createNewFile();

    try (FileOutputStream outputStream = new FileOutputStream(newFile, false)) {
        int read;
        byte[] bytes = new byte[65535];
        while ((read = inputStream.read(bytes)) != -1) {
            outputStream.write(bytes, 0, read);
        }
    }

}

Approach 2: Using Files.copy() method.

public static void writeInputStreamToAFile2(final InputStream inputStream, final String filePath)
        throws IOException {
    checkInput(inputStream, filePath);

    File newFile = new File(filePath);

    // create parent dirs if necessary
    newFile.getParentFile().mkdirs();
    newFile.createNewFile();
    Files.copy(inputStream, newFile.toPath(), StandardCopyOption.REPLACE_EXISTING);
}

Approach 3: Using InputStream#transferTo method. This method is introduced in Java9.

public static void writeInputStreamToAFile3(final InputStream inputStream, final String filePath)
        throws IOException {
    checkInput(inputStream, filePath);

    File newFile = new File(filePath);

    // create parent dirs if necessary
    newFile.getParentFile().mkdirs();
    newFile.createNewFile();
    try (OutputStream output = new FileOutputStream(newFile, false)) {
        inputStream.transferTo(output);
    }
}

Find the below working application.

 

InputStreamToAFile.java

package com.sample.app;

import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.file.Files;
import java.nio.file.StandardCopyOption;

public class InputStreamToAFile {

    private static void checkInput(InputStream inputStream, String filePath) {
        if (inputStream == null) {
            throw new IllegalArgumentException("inputStream is null");
        }

        if (filePath == null) {
            throw new IllegalArgumentException("filePath is null");
        }
    }

    public static void writeInputStreamToAFile1(final InputStream inputStream, final String filePath)
            throws IOException {
        checkInput(inputStream, filePath);

        File newFile = new File(filePath);

        // create parent dirs if necessary
        newFile.getParentFile().mkdirs();
        newFile.createNewFile();

        try (FileOutputStream outputStream = new FileOutputStream(newFile, false)) {
            int read;
            byte[] bytes = new byte[65535];
            while ((read = inputStream.read(bytes)) != -1) {
                outputStream.write(bytes, 0, read);
            }
        }

    }

    public static void writeInputStreamToAFile2(final InputStream inputStream, final String filePath)
            throws IOException {
        checkInput(inputStream, filePath);

        File newFile = new File(filePath);

        // create parent dirs if necessary
        newFile.getParentFile().mkdirs();
        newFile.createNewFile();
        Files.copy(inputStream, newFile.toPath(), StandardCopyOption.REPLACE_EXISTING);
    }

    public static void writeInputStreamToAFile3(final InputStream inputStream, final String filePath)
            throws IOException {
        checkInput(inputStream, filePath);

        File newFile = new File(filePath);

        // create parent dirs if necessary
        newFile.getParentFile().mkdirs();
        newFile.createNewFile();
        try (OutputStream output = new FileOutputStream(newFile, false)) {
            inputStream.transferTo(output);
        }
    }

    public static void main(String[] args) throws IOException {
        ByteArrayInputStream bios1 = new ByteArrayInputStream(new String("Hello World").getBytes());
        ByteArrayInputStream bios2 = new ByteArrayInputStream(new String("Hello World").getBytes());
        ByteArrayInputStream bios3 = new ByteArrayInputStream(new String("Hello World").getBytes());

        String file1 = "/Users/Shared/files/file1.txt";
        String file2 = "/Users/Shared/files/file2.txt";
        String file3 = "/Users/Shared/files/file3.txt";

        writeInputStreamToAFile1(bios1, file1);
        writeInputStreamToAFile1(bios2, file2);
        writeInputStreamToAFile1(bios3, file3);
    }

}

Run above application, you can confirm that three files file1, file2 and file3 created with the content of inputstream.



 

You may like

file and stream programs in Java

check whether a file is executable or not in Java

Check whether a directory has some files or not

Check given path is a file and not a symbolic link in Java

Check given path is a directory and not a symbolic link in Java

Convert InputStream to string

Saturday, 9 July 2022

How to download a binary file in Java?

Approach 1: Using InputStream, we can read the data from the given url and OutputStream can be used to write the binary data to disk.

 


 

Find the below working application.

 

BinaryDownloaderDemo.java

package com.sample.app;

import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URL;
import java.net.URLConnection;

public class BinaryDownloaderDemo {

	private static void downloadFile(final String urlToDownload, final String filePath) {
		
		// Create parent folders if not exists
		final File file = new File(filePath);
		file.getParentFile().mkdirs();

		try {
			final URL url = new URL(urlToDownload);
			final URLConnection urlConnection = url.openConnection();

			try (final InputStream inputStream = urlConnection.getInputStream();
					final OutputStream outputStream = new FileOutputStream(filePath);) {
				byte[] buffer = new byte[65535];
				int bytesRead;
				while ((bytesRead = inputStream.read(buffer)) != -1) {
					outputStream.write(buffer, 0, bytesRead);
				}

			}
		} catch (Exception e) {
			e.printStackTrace();
		}

	}

	public static void main(String[] args) {
		final String urlToDownlaod =  "https://dlcdn.apache.org/maven/maven-3/3.8.6/binaries/apache-maven-3.8.6-bin.zip";
		
		downloadFile(urlToDownlaod, "/Users/Shared/softwares/maven/apache-maven-3.8.6-bin.zip");
		
	}

}

 

Approach 2: Using nio FileChannel# transferFrom method.

 

BinaryDownloaderDemo2.java

package com.sample.app;

import java.io.File;
import java.io.FileOutputStream;
import java.net.URL;
import java.nio.channels.Channels;
import java.nio.channels.ReadableByteChannel;

public class BinaryDownloaderDemo2 {

	private static void downloadFile(final String urlToDownload, final String filePath) {

		// Create parent folders if not exists
		final File file = new File(filePath);
		file.getParentFile().mkdirs();

		try {
			URL website = new URL(urlToDownload);

			try (ReadableByteChannel rbc = Channels.newChannel(website.openStream());
					FileOutputStream fos = new FileOutputStream(filePath);) {
				fos.getChannel().transferFrom(rbc, 0, Long.MAX_VALUE);
			}

		} catch (Exception e) {
			e.printStackTrace();
		}

	}

	public static void main(String[] args) {
		final String urlToDownlaod = "https://dlcdn.apache.org/maven/maven-3/3.8.6/binaries/apache-maven-3.8.6-bin.zip";

		downloadFile(urlToDownlaod, "/Users/Shared/softwares/maven/apache-maven-3.8.6-bin.zip");

	}

}

 

 

 

You may like

File programs in Java

Count number of lines in a file

Download file from Internet using Java

Get the content of resource file as string

Copy the content of file to other location

Write byte array to a file

Saturday, 2 May 2020

Javassist: Get CtClass object from InputStream

Step 1: Create InputStream to the class file
String classFilePath = "....";
File classFile = new File(classFilePath);
InputStream inputStream = new FileInputStream(classFile);

Step 2: Get CtClass instance from input stream
ClassPool classPool = ClassPool.getDefault();
CtClass ctClass = classPool.makeClass(inputStream);

App.java
package com.sample.app;

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

import javassist.ClassPool;
import javassist.CtClass;

public class App {

 public static void main(String args[]) throws Exception {

  String classFilePath = "...."; // Add class file path here
  File classFile = new File(classFilePath);
  InputStream inputStream = new FileInputStream(classFile);

  ClassPool classPool = ClassPool.getDefault();
  CtClass ctClass = classPool.makeClass(inputStream);

  System.out.println(ctClass.getName());

 }
}


Previous                                                    Next                                                    Home

Friday, 7 June 2019

Java: Convert InputStream to ByteArray


Approach 1: Read entire input stream to ByteArrayOutputStream.
public static byte[] getByteArray(InputStream inputStream) throws IOException {
         ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();

         int nRead;
         byte[] data = new byte[16384];

         try {
                  while ((nRead = inputStream.read(data, 0, data.length)) != -1) {
                           byteArrayOutputStream.write(data, 0, nRead);
                  }
         } catch (IOException e) {
                  e.printStackTrace();
                  if (inputStream != null) {
                           inputStream.close();
                  }
         }

         return byteArrayOutputStream.toByteArray();
}

App.java
package com.sample.app;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;

public class App {

 public static byte[] getByteArray(InputStream inputStream) throws IOException {
  ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();

  int nRead;
  byte[] data = new byte[16384];

  try {
   while ((nRead = inputStream.read(data, 0, data.length)) != -1) {
    byteArrayOutputStream.write(data, 0, nRead);
   }
  } catch (IOException e) {
   e.printStackTrace();
   if (inputStream != null) {
    inputStream.close();
   }
  }

  return byteArrayOutputStream.toByteArray();
 }

 public static void main(String args[]) throws IOException {
  FileInputStream fis = new FileInputStream(new File("/Users/krishna/Desktop/TODO.txt"));
  byte[] data = getByteArray(fis);
  
  System.out.println(new String(data));
 }
}

Approach 2: From Java9 onwards, inputstream class provides ‘readAllBytes’ method to get byte array from input stream.
public byte[] readAllBytes()
public int readNBytes(byte[] b, int off, int len)

Approach 3: Using DataInputStream.
byte[] bytes = new byte[(int) file.length()];

try (DataInputStream dataInputStream = new DataInputStream(new FileInputStream(file));) {
         dataInputStream.readFully(bytes);
         return bytes;
}


App.java
package com.sample.app;

import java.io.DataInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;

public class App {

 public static byte[] getByteArray(File file) throws IOException {

  byte[] bytes = new byte[(int) file.length()];
  
  try (DataInputStream dataInputStream = new DataInputStream(new FileInputStream(file));) {
   dataInputStream.readFully(bytes);
   return bytes;
  }

 }

 public static void main(String args[]) throws IOException {
  byte[] data = getByteArray(new File("/Users/krishna/Desktop/TODO.txt"));

  System.out.println(new String(data));
 }
}


You may like