Is it possible to create a File object from InputStream - java

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);
}
}

Related

Write multiple Zip files to an OutputStream using IOUtils.copy method

This question feels very difficult to explain to me but ill do my best.
Currently I have a method that returns an InputStream with a Zip file that i have to add to a main zip file. Problem is when I write something into the OutputStream it overwrites previous written data. I tried using ZipOutputStream with ZipEntries but this recompresses the file and does weird things, so its not a solution. Things that I'm required to use and are not negotiable are:
Retrieving the file with the method that returns an InputStream
Using IOUtils.copy() method to download the file (this may be optional if u have another solution that allows me to download the file through a browser)
This is the code so far:
OutputStream os = null;
InputStream is = null;
try {
os = response.getOutputStream();
for (int i = 0; i < splited.length; i += 6) {
String[] file= //an array with the data to retrieve the file
is = FileManager.downloadFile(args);
int read;
byte[] buffer = new byte[1024];
while (0 < (read = is.read(buffer))) {
os.write(buffer, 0, read);
}
}
} catch (Exception ex) {
//Exception captures
}
response.setHeader("Content-Disposition", "attachment; filename=FileName");
response.setContentType("application/zip");
IOUtils.copy(is, os);
os.close();
is.close();
return forward;
You can use ZipOutputStream wrapping the response's OutputStream but instead of close call finish, and do not call close on the ResponseOutputStream.
You must start with the HTTP headers.
response.setHeader("Content-Disposition", "attachment; filename=FileName");
response.setContentType("application/zip");
try {
ZipOutputStream os = new ZipOutputStream(response.getOutputStream());
for (int i = 0; i < splited.length - 5; i += 6) {
String[] file= //an array with the data to retrieve the file
try (InputStream is = FileManager.downloadFile(args)) {
os.putNextEntry(new ZipEntry(filePath));
is.TransferTo(os);
os.closeEntry();
}
}
os.finish();
} catch (Exception ex) {
//Exception captures
}
return forward;
Since java 9 transferTo copies Input/OutputStreams.
One can also copy a Path with Files.copy(Path, OutputStream) where Path is an URI based generalisation of File, so also URLs might immediately be copied.
Here try-with-resources ensures that every is is closed.

A java program that creates WAV files [duplicate]

With Java:
I have a byte[] that represents a file.
How do I write this to a file (ie. C:\myfile.pdf)
I know it's done with InputStream, but I can't seem to work it out.
Use Apache Commons IO
FileUtils.writeByteArrayToFile(new File("pathname"), myByteArray)
Or, if you insist on making work for yourself...
try (FileOutputStream fos = new FileOutputStream("pathname")) {
fos.write(myByteArray);
//fos.close(); There is no more need for this line since you had created the instance of "fos" inside the try. And this will automatically close the OutputStream
}
Without any libraries:
try (FileOutputStream stream = new FileOutputStream(path)) {
stream.write(bytes);
}
With Google Guava:
Files.write(bytes, new File(path));
With Apache Commons:
FileUtils.writeByteArrayToFile(new File(path), bytes);
All of these strategies require that you catch an IOException at some point too.
Another solution using java.nio.file:
byte[] bytes = ...;
Path path = Paths.get("C:\\myfile.pdf");
Files.write(path, bytes);
Also since Java 7, one line with java.nio.file.Files:
Files.write(new File(filePath).toPath(), data);
Where data is your byte[] and filePath is a String. You can also add multiple file open options with the StandardOpenOptions class. Add throws or surround with try/catch.
From Java 7 onward you can use the try-with-resources statement to avoid leaking resources and make your code easier to read. More on that here.
To write your byteArray to a file you would do:
try (FileOutputStream fos = new FileOutputStream("fullPathToFile")) {
fos.write(byteArray);
} catch (IOException ioe) {
ioe.printStackTrace();
}
Try an OutputStream or more specifically FileOutputStream
Basic example:
String fileName = "file.test";
BufferedOutputStream bs = null;
try {
FileOutputStream fs = new FileOutputStream(new File(fileName));
bs = new BufferedOutputStream(fs);
bs.write(byte_array);
bs.close();
bs = null;
} catch (Exception e) {
e.printStackTrace()
}
if (bs != null) try { bs.close(); } catch (Exception e) {}
File f = new File(fileName);
byte[] fileContent = msg.getByteSequenceContent();
Path path = Paths.get(f.getAbsolutePath());
try {
Files.write(path, fileContent);
} catch (IOException ex) {
Logger.getLogger(Agent2.class.getName()).log(Level.SEVERE, null, ex);
}
////////////////////////// 1] File to Byte [] ///////////////////
Path path = Paths.get(p);
byte[] data = null;
try {
data = Files.readAllBytes(path);
} catch (IOException ex) {
Logger.getLogger(Agent1.class.getName()).log(Level.SEVERE, null, ex);
}
/////////////////////// 2] Byte [] to File ///////////////////////////
File f = new File(fileName);
byte[] fileContent = msg.getByteSequenceContent();
Path path = Paths.get(f.getAbsolutePath());
try {
Files.write(path, fileContent);
} catch (IOException ex) {
Logger.getLogger(Agent2.class.getName()).log(Level.SEVERE, null, ex);
}
I know it's done with InputStream
Actually, you'd be writing to a file output...
This is a program where we are reading and printing array of bytes offset and length using String Builder and Writing the array of bytes offset length to the new file.
`Enter code here
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
//*This is a program where we are reading and printing array of bytes offset and length using StringBuilder and Writing the array of bytes offset length to the new file*//
public class ReadandWriteAByte {
public void readandWriteBytesToFile(){
File file = new File("count.char"); //(abcdefghijk)
File bfile = new File("bytefile.txt");//(New File)
byte[] b;
FileInputStream fis = null;
FileOutputStream fos = null;
try{
fis = new FileInputStream (file);
fos = new FileOutputStream (bfile);
b = new byte [1024];
int i;
StringBuilder sb = new StringBuilder();
while ((i = fis.read(b))!=-1){
sb.append(new String(b,5,5));
fos.write(b, 2, 5);
}
System.out.println(sb.toString());
}catch (IOException e) {
e.printStackTrace();
}finally {
try {
if(fis != null);
fis.close(); //This helps to close the stream
}catch (IOException e){
e.printStackTrace();
}
}
}
public static void main (String args[]){
ReadandWriteAByte rb = new ReadandWriteAByte();
rb.readandWriteBytesToFile();
}
}
O/P in console : fghij
O/P in new file :cdefg
You can try Cactoos:
new LengthOf(new TeeInput(array, new File("a.txt"))).value();
More details: http://www.yegor256.com/2017/06/22/object-oriented-input-output-in-cactoos.html

Java write exe file

is it possible to write/create an exe file in Java?
I can successfully read it but writing the exact same data that has been read to a new file seems to create some trouble because Windows tell's me it's not supported for my pc anymore.
This is the code I'm using to read the file where path is a String given with the actual path (it's in the .jar itself that's why I'm using ResourceAsStream()):
try {
InputStream inputStream = FileIO.class.getResourceAsStream(path);
BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
ArrayList<String> _final = new ArrayList<String>();
String line;
while ((line = reader.readLine()) != null) {
_final.add(line);
}
inputStream.close();
return _final.toArray(new String[_final.size()]);
}catch(Exception e) {
return null;
}
This is the code I'm using to write the file:
public static void writeFileArray(String path, String[] data) {
String filename = path;
try{
FileWriter fileWriter = new FileWriter(filename);
BufferedWriter bufferedWriter = new BufferedWriter(fileWriter);
for(String d : data) {
bufferedWriter.write(d + "\n");
}
bufferedWriter.close();
}
catch(IOException ex){
System.out.println("FileIO failed to write file, IO exception");
}
}
So it doesn't give me any error's or something and the file size of the original .exe and the 'transferred' .exe stays the same, but it doesn't work anymore. Am I just doing it wrong? Did I forget something? Can u even do this with Java?
Btw I'm not that experienced with reading/writing files..
Thanks for considering my request.
I'm going to guess that you're using a Reader when you should be using a raw input stream. Use BufferedInputStream instead of BufferedReader.
BufferedInputStream in = new BufferedInputStream( inputStream );
The problem is that Reader interprets the binary as your local character set instead of the data you want.
Edit: if you need a bigger hint start with this. I just noticed you're using a BufferedWriter too, that won't work either.
try {
InputStream inputStream = FileIO.class.getResourceAsStream(path);
BufferedInputStream in = new BufferedInputStream( inputStream );
ByteArrayOutputStream bos = new ByteArrayOutputStream();
byte[] bytes = new byte[ 1024 ];
for( int length; ( length = ins.read( bytes ) ) != -1; )
bos.write( bytes, 0, length );
}
inputStream.close();
return bos;
When you are using Java 7 or newer, you should copy a resource to a file using
public static void copyResourceToFile(String resourcePath, String filePath) {
try(InputStream inputStream = FileIO.class.getResourceAsStream(resourcePath)) {
Files.copy(inputStream, Paths.get(filePath));
}
catch(IOException ex){
System.out.println("Copying failed. "+ex.getMessage());
}
}
This construct ensures correct closing of the resources even in the exceptional case and the JRE method ensures correct and efficient copying of the data.
It accepts additional options, e.g. to specify that the target file should be overwritten in case it already exists, you would use
public static void copyResourceToFile(String resourcePath, String filePath) {
try(InputStream inputStream = FileIO.class.getResourceAsStream(resourcePath)) {
Files.copy(inputStream, Paths.get(filePath), StandardCopyOption.REPLACE_EXISTING);
}
catch(IOException ex){
System.out.println("Copying failed. "+ex.getMessage());
}
}
You are using InputStreams for strings, .exe files are bytes!
Try using a ByteArrayInputStream and ByteArrayOutputStream.
Edit: completing with markspace's answer:
new BufferedInputStream(new ByteArrayInputStream( ... ) )

Java: How do I convert InputStream to GZIPInputStream?

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.

How to unzip a 7zip archive in Android?

I have a 7zip archive which contains some hundred files separated into different directories. The target is to download it from a FTP server and then extract it on the phone.
My problem is that the 7zip SDK doesn't contain a lot. I am looking for examples, tutorials and snippets regarding the decompression of 7z files.
(Decompression via Intent is only a secondary option)
Go here:
LZMA SDK just provides the encoder and decoder for encoding/decoding the raw data, but 7z archive is a complex format for storing multiple files.
i found this page that provides an alternative that works like a charm. You only have to add compile 'org.apache.commons:commons-compress:1.8'
to your build gradle script and use the feature you desire. For this issue i did the following :
AssetManager am = getAssets();
InputStream inputStream = null;
try {
inputStream = am.open("a7ZipedFile.7z");
File file1 = createFileFromInputStream(inputStream);
} catch (IOException e) {
e.printStackTrace();
}
SevenZFile sevenZFile = null;
try{
File f = new File(this.getFilesDir(), "a7ZipedFile.7z");
OutputStream outputStream = new FileOutputStream(f);
byte buffer[] = new byte[1024];
int length = 0;
while((length=inputStream.read(buffer)) > 0) {
outputStream.write(buffer,0,length);
}
try {
sevenZFile = new SevenZFile(f);
SevenZArchiveEntry entry = sevenZFile.getNextEntry();
while (entry != null) {
System.out.println(entry.getName());
FileOutputStream out = openFileOutput(entry.getName(), Context.MODE_PRIVATE);
byte[] content = new byte[(int) entry.getSize()];
sevenZFile.read(content, 0, content.length);
out.write(content);
out.close();
entry = sevenZFile.getNextEntry();
}
sevenZFile.close();
outputStream.close();
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}catch (IOException e) {
//Logging exception
e.printStackTrace();
}
The only draw back is approximately 200k for the imported library. Other than that it is really easy to use.

Categories