I have a method like
public void put(#Nonnull final InputStream inputStream, #Nonnull final String uniqueId) throws PersistenceException {
// a.) create gzip of inputStream
final GZIPInputStream zipInputStream;
try {
zipInputStream = new GZIPInputStream(inputStream);
} catch (IOException e) {
e.printStackTrace();
throw new PersistenceException("Persistence Service could not received input stream to persist for " + uniqueId);
}
I wan to convert the inputStream into zipInputStream, what is the way to do that?
The above method is incorrect and throws Exception as "Not a Zip Format"
converting Java Streams to me are really confusing and I do not make them right
The GZIPInputStream is to be used to decompress an incoming InputStream. To compress an incoming InputStream using GZIP, you basically need to write it to a GZIPOutputStream.
You can get a new InputStream out of it if you use ByteArrayOutputStream to write gzipped content to a byte[] and ByteArrayInputStream to turn a byte[] into an InputStream.
So, basically:
public void put(#Nonnull final InputStream inputStream, #Nonnull final String uniqueId) throws PersistenceException {
final InputStream zipInputStream;
try {
ByteArrayOutputStream bytesOutput = new ByteArrayOutputStream();
GZIPOutputStream gzipOutput = new GZIPOutputStream(bytesOutput);
try {
byte[] buffer = new byte[10240];
for (int length = 0; (length = inputStream.read(buffer)) != -1;) {
gzipOutput.write(buffer, 0, length);
}
} finally {
try { inputStream.close(); } catch (IOException ignore) {}
try { gzipOutput.close(); } catch (IOException ignore) {}
}
zipInputStream = new ByteArrayInputStream(bytesOutput.toByteArray());
} catch (IOException e) {
e.printStackTrace();
throw new PersistenceException("Persistence Service could not received input stream to persist for " + uniqueId);
}
// ...
You can if necessary replace the ByteArrayOutputStream/ByteArrayInputStream by a FileOuputStream/FileInputStream on a temporary file as created by File#createTempFile(), especially if those streams can contain large data which might overflow machine's available memory when used concurrently.
GZIPInputStream is for reading gzip-encoding content.
If your goal is to take a regular input stream and compress it in the GZIP format, then you need to write those bytes to a GZIPOutputStream.
See also this answer to a related question.
Related
I have a String that is encoded in base64, I need to take this string, decode it and create a truststore file, but when I do that, the final file is not valid. Here is my code:
public static void buildFile() {
String exampleofencoded = "asdfasdfasdfadfa";
File file = new File("folder/file.jks");
try (FileOutputStream fos = new FileOutputStream(file);
BufferedOutputStream bos = new BufferedOutputStream(fos);
DataOutputStream dos = new DataOutputStream(bos))
{
Base64.Decoder decoder = Base64.getDecoder();
String decodedString =new String(decoder.decode(exampleofencoded).getBytes());
dos.writeBytes(decodedString);
}
catch (IOException e) {
System.out.println("Error creating file");
}
catch(NullPointerException e) {
System.out.println(e.getMessage();
}
}
The problem is two-fold.
You're converting a byte[] array to String, which is a lossy operation for actual binary data for most character sets (except maybe iso-8859-1).
You're using DataOutputStream, which is not a generic output stream, but intended for a specific serialization format of primitive types. And specifically its writeBytes method comes with an important caveat ("Each character in the string is written out, in sequence, by discarding its high eight bits."), which is one more reason why only using iso-8859-1 will likely work.
Instead, write the byte array directly to the file
public static void buildFile() {
String exampleofencoded = "asdfasdfasdfadfa";
File file = new File("folder/file.jks");
try (FileOutputStream fos = Files.newOutputStream(file.toPath()) {
Base64.Decoder decoder = Base64.getDecoder();
byte[] decodedbytes = decoder.decode(exampleofencoded);
fos.write(decodedbytes);
} catch (IOException e) {
System.out.println("Error creating file");
}
}
As an aside, you shouldn't catch NullPointerException in your code, it is almost always a problem that can be prevented by careful programming and/or validation of inputs. I would usually also advise against catch the IOException here and only printing it. It is probably better to propagate that exception as well, and let the caller handle it.
I need to read a binary file and save each byte into a byte array. I've read other stackoverflow posts on this topic, but cannot figure out why mine does not work. Here is what I have:
String fileOne = "file1.bin";
byte[] byteArray = new byte[1000];
try{
FileInputStream fileIS = new FileInputStream(fileOne);
ObjectInputStream is = new ObjectInputStream(fileIS);
is.read(byteArray);
is.close();
for(int i =0; i < byteArray.length; i++){
System.out.println(byteArray[i]);
}
}
catch (FileNotFoundException e){
e.toString();
System.exit(0);
}
catch (IOException io){
io.toString();
System.exit(0);
}
Here's a way to read the contents of a file into a byte array. FileInputStream is all you need – leave ObjectInputStream out of it (unless you are explicitly dealing with data that was created from an ObjectOutputStream, but that doesn't seem to be the case since you are calling println() on each byte).
public static void main(String[] args) {
String filename = "file1.bin";
try (FileInputStream fis = new FileInputStream(filename)) {
byte[] bytes = fis.readAllBytes();
for (byte b : bytes) {
System.out.print(b);
}
} catch (Exception e) {
e.printStackTrace();
}
}
A few things here:
omit using ObjectInputStream – not needed for reading byte data, and won't work unless the data was created by the corresponding output stream. From the Javadoc: "An ObjectInputStream deserializes primitive data and objects previously written using an ObjectOutputStream. "
use try with resources – it will close the associated stream for you
catch Exception – in the code you posted, you will only see info if FileNotFoundException or IOException is thrown. For anything else, your code doesn't handle them or print out any info.
This question already has answers here:
Convert InputStream to byte array in Java
(34 answers)
Closed 4 years ago.
I am trying to convert an InputStream into a byte array to write it in a file, to generate a PDF.
I have a File type with the url of a PDF, and with that, i have the inputStream of that.
File fichero_pdf = new File("C:/Users/agp2/Desktop/PDF_TRIAXE.pdf");
InputStream stream4 = new FileInputStream(fichero_pdf);
Until here everything is perfect, the problem appears when i try to transform this InputStream to a byte[] and write it in a new File.
I have these two methods:
to convert the Stream to a byte[]:
private static byte[] getArrayFromInputStream(InputStream is) {
BufferedReader br = null;
StringBuilder sb = new StringBuilder();
String line;
try {
br = new BufferedReader(new InputStreamReader(is));
while ((line = br.readLine()) != null) {
sb.append(line+"\n");
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (br != null) {
try {
br.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return sb.toString().getBytes();
}
To write the byte[] in the new file:
...
File file=new File(dto.getTitulo());
InputStream stream=dto.getContenido();
byte[] array=getStringFromInputStream(stream);
OutputStream salida=new FileOutputStream(file);
salida.write(array);
salida.close();
stream.close();
helper.addAttachment(file.getName(), file);
}
mailSender.send(message);
...
The Email is sent at perfection, but when i can't open the .pdf.
Also, i compare the code of the new pdf with the code of the first, and is a little bit different.
I need to create a valid pdf file from an inputStream.
You have 2 problems:
You are trying to read bytes as strings, but you don't have to do it. In your case you should use byte streams(FileInputStream, BufferedInputStream), not char streams(InputStreamReader, BufferedReader).
You loose data when you convert String to bytes here:
return sb.toString().getBytes();
I would like to suggest you to use java 7 try-with-resources instead of try-catch-finally.
You can read the whole file to a byte array using ByteArrayOutputStream.
Sample code does the following:
getArrayFromInputStream() - reads all file bytes to byte array
writeContent() - writes content to a new file, in my example pdf_sample2.pdf
Example:
public class ReadAllBytes {
// as example - write to resources folder
private static String DIR = "src\\main\\resources\\";
public static void main(String[] args) throws IOException {
try {
byte[] fileAsBytes = getArrayFromInputStream(new FileInputStream(new File(DIR + "pdf-sample.pdf")));
writeContent(fileAsBytes, DIR + "pdf_sample2.pdf");
} catch (Exception e){
e.printStackTrace();
}
}
private static byte[] getArrayFromInputStream(InputStream inputStream) throws IOException {
byte[] bytes;
byte[] buffer = new byte[1024];
try(BufferedInputStream is = new BufferedInputStream(inputStream)){
ByteArrayOutputStream bos = new ByteArrayOutputStream();
int length;
while ((length = is.read(buffer)) > -1 ) {
bos.write(buffer, 0, length);
}
bos.flush();
bytes = bos.toByteArray();
}
return bytes;
}
private static void writeContent(byte[] content, String fileToWriteTo) throws IOException {
File file = new File(fileToWriteTo);
try(BufferedOutputStream salida = new BufferedOutputStream(new FileOutputStream(file))){
salida.write(content);
salida.flush();
}
}
}
Is there a way I can get netty ByteBuf from a java File object? I am trying to use Custom Snappy class to validate checksum. Below is my code where I'd like to get File object in bytebuf variable.
import io.netty.buffer.ByteBuf;
File file = new File("boot.zip");
ByteBuf byteBuf = Unpooled.buffer(128);
byteBuf.writeBytes(new FileInputStream(file));
int expectedChecksum = Snappy.calculateChecksum(byteBuf);
logger.info("checksum = "+expectedChecksum);
boolean checksumValid = true;
try {
CustomSnappy.validateChecksum(expectedChecksum, byteBuf);
} catch(DecompressionException e) {
checksumValid = false;
e.printStackTrace();
logger.error("DecompressionException in checksum calculation " + e);
} catch(Exception e) {
checksumValid = false;
e.printStackTrace();
logger.error("Exception in checksum calculation " + e);
}
I used Unpooled.buffer(128) but it gives me No signature of method :io.netty.buffer.UnpooledHeapByteBuf.writeBytes() is applicable for argument types: (java.io.FileInputStream) values: [java.io.FileInputStream#28b6520b]
You can created a MappedByteBuf from a FileChannel and wrap it in ByteBuffer via Unpooled.wrappedBuffer(..).
Here is an example of how to "create a MappedByteBuf from a FileChannel and wrap it in ByteBuffer via Unpooled.wrappedBuffer(..)":
try {
File file = new File(filename);
FileInputStream fileInputStream = new FileInputStream(file);
FileChannel fileChannel = fileInputStream.getChannel();
MappedByteBuffer mappedByteBuffer = fileChannel.map(FileChannel.MapMode.READ_ONLY, 0, file.length());
ByteBuf byteBuf = Unpooled.wrappedBuffer(mappedByteBuffer);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
You can use the method ByteBuf#writeBytes(InputStream). This should work, but I did not test it.
ByteBuf buffer = // see http://stackoverflow.com/a/15088238/834
buffer.writeBytes(new FileInputStream(file), file.length());
See http://netty.io/4.0/api/io/netty/buffer/ByteBuf.html#writeBytes(java.io.InputStream,%20int)
The documentation shows how to create a new ByteBuf: http://netty.io/4.0/api/io/netty/buffer/Unpooled.html
If you are using JDK 1.7, the class of java.nio.file.Files could make it easy with amount of static methods.
ByteBuf buffer = Unpooled.copiedBuffer(Files.readAllBytes(new File(this.getClass().getResource("/requests/overPackageRequest").getFile()).toPath()));
Is there any way to create a java.io.File object from an java.io.InputStream ?
My requirement is reading the File from a RAR . I am not trying to write a temporary File, I have a file inside RAR archive which I am trying to read.
You need to create new file and copy contents from InputStream to that file:
File file = //...
try(OutputStream outputStream = new FileOutputStream(file)){
IOUtils.copy(inputStream, outputStream);
} catch (FileNotFoundException e) {
// handle exception here
} catch (IOException e) {
// handle exception here
}
I am using convenient IOUtils.copy() to avoid manual copying of streams. Also it has built-in buffering.
In one line :
FileUtils.copyInputStreamToFile(inputStream, file);
(org.apache.commons.io)
Since Java 7, you can do it in one line even without using any external libraries:
Files.copy(inputStream, outputPath, StandardCopyOption.REPLACE_EXISTING);
See the API docs.
Create a temp file first using org.apache.commons.io.
File tempFile = File.createTempFile(prefix, suffix);
tempFile.deleteOnExit();
FileOutputStream out = new FileOutputStream(tempFile);
IOUtils.copy(in, out);
return tempFile;
Easy Java 9 solution with try with resources block
public static void copyInputStreamToFile(InputStream input, File file) {
try (OutputStream output = new FileOutputStream(file)) {
input.transferTo(output);
} catch (IOException ioException) {
ioException.printStackTrace();
}
}
java.io.InputStream#transferTo is available since Java 9.
If you do not want to use other libraries, here is a simple function to copy data from an InputStream to an OutputStream.
public static void copyStream(InputStream in, OutputStream out) throws IOException {
byte[] buffer = new byte[1024];
int read;
while ((read = in.read(buffer)) != -1) {
out.write(buffer, 0, read);
}
}
Now, you can easily write an Inputstream into a file by using FileOutputStream-
FileOutputStream out = new FileOutputStream(outFile);
copyStream (inputStream, out);
out.close();
If you are using Java version 7 or higher, you can use try-with-resources to properly close the FileOutputStream. The following code use IOUtils.copy() from commons-io.
public void copyToFile(InputStream inputStream, File file) throws IOException {
try(OutputStream outputStream = new FileOutputStream(file)) {
IOUtils.copy(inputStream, outputStream);
}
}