writing a string to a zip file using ZipOutputStream - java

Ultimately the goal is just to zip a string and have that as a string in java
public void zip() {
try {
String myTestString = "a zip file test and another test";
InputStream in = new ByteArrayInputStream(myTestString.getBytes());
OutputStream out = new ByteArrayOutputStream();
ZipOutputStream zipOut = new ZipOutputStream(out);
ZipEntry zipEntry = new ZipEntry("wtf.txt");
zipOut.putNextEntry(zipEntry);
zipOut.write(myTestString.getBytes(),0,myTestString.getBytes().length);
zipOut.close();
myTestString = out.toString();
out.close();
System.out.println(myTestString);
// just a test if I can read the file
in = new ByteArrayInputStream(myTestString.getBytes());
out = new FileOutputStream("c:\\t\\string.zip");
byte[] allBytes = new byte[(int) myTestString.getBytes().length];
in.read(allBytes);
out.write(allBytes);
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
I have found I can write a string to a zipfile using
public void zipStringToFile2() {
try {
FileOutputStream fos = new FileOutputStream("c:/t/compressed.zip");
ZipOutputStream zipOut = new ZipOutputStream(fos);
String myTestString = "a zip file test and another test";
int buffer = myTestString.getBytes().length;
// byte[] myBytes = myTestString.getBytes();
ByteArrayOutputStream out = new ByteArrayOutputStream(buffer);
ZipEntry zipEntry = new ZipEntry("wtf.txt");
zipOut.putNextEntry(zipEntry);
zipOut.write(myTestString.getBytes(),0,buffer);
zipOut.close();
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
but I cannot get the output of zipOut to write to a string and then have the string write to a file and then via the OS open the zipfile. How can that be done?

myTestString = out.toString();
This doesn't do what you want. bytes aren't strings. toString() doesn't give useful information (it is a debugging tool). Keep the byte array (.toByteArray()).
out.close();
close the stream after you retrieved the data? Don't do that. Close first. (not that it matters, here. ByteArrayXStream's close() doesn't do anything at all. The point is, it either does nothing in which case you should remove it, or if it does have an effect, your code would be broken).
myTestString.getBytes()
No, don't ever call that method. It gives you the bytes by decoding the characters into bytes using 'platform default encoding'. Who knows what that is.
} catch (IOException e) {
e.printStackTrace();
}
The correct 'I dunno' exception handler is throw new RuntimeException("unhandled", e);, not e.printStackTrace();. You get more info, and you get fewer WTFs (because yours will continue execution even though things are clearly wrong, which is a very bad idea).
but I cannot get the output of zipOut to write to a string
Yup. Strings aren't bytes, what you want is not possible at all. In any language. Some languages make it look like you can - those are bad languages, that conflate strings and byte arrays. Python decided to crash and burn and invent a whole new python (python2k -> python3k) to try to fix this, which goes to show. Boy that was a ton of pain and they suffered it to fix this oversight.
but I cannot get the output of zipOut to write to a string and then have the string write to a file and then via the OS open the zipfile. How can that be done?
So, replace all occurences of 'string' in that sentence with 'byte array' and all is peachy fine!

this is really what I was looking for:
public void zip() {
try {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ZipOutputStream zipOut = new ZipOutputStream(baos);
ByteArrayInputStream bais = new ByteArrayInputStream(testString.getBytes());
System.out.println("testString " + testString + " testString.getBytes() " + testString.getBytes());
ZipEntry zipEntry = new ZipEntry("Results.xml");
zipOut.putNextEntry(zipEntry);
byte[] bytes = new byte[1024];
int length;
while((length = bais.read(bytes)) >= 0 ) {
zipOut.write(bytes, 0, length);
}
zipOut.close();
bais.close();
baos.close();
byte[] zipBytes = baos.toByteArray();
// just a test to see if can be opened in the operating system
OutputStream os = new FileOutputStream(new File("c:/t/again.zip"));
os.write(zipBytes);
os.close();
} catch(IOException e) {
e.printStackTrace();
}
}

Related

Convert mp4 to bytes and bytes to mp4 in java for android [duplicate]

I've found many ways of converting a file to a byte array and writing byte array to a file on storage.
What I want is to convert java.io.File to a byte array and then convert a byte array back to a java.io.File.
I don't want to write it out to storage like the following:
//convert array of bytes into file
FileOutputStream fileOuputStream = new FileOutputStream("C:\\testing2.txt");
fileOuputStream.write(bFile);
fileOuputStream.close();
I want to somehow do the following:
File myFile = ConvertfromByteArray(bytes);
Otherwise Try this :
Converting File To Bytes
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
public class Temp {
public static void main(String[] args) {
File file = new File("c:/EventItemBroker.java");
byte[] b = new byte[(int) file.length()];
try {
FileInputStream fileInputStream = new FileInputStream(file);
fileInputStream.read(b);
for (int i = 0; i < b.length; i++) {
System.out.print((char)b[i]);
}
} catch (FileNotFoundException e) {
System.out.println("File Not Found.");
e.printStackTrace();
}
catch (IOException e1) {
System.out.println("Error Reading The File.");
e1.printStackTrace();
}
}
}
Converting Bytes to File
public class WriteByteArrayToFile {
public static void main(String[] args) {
String strFilePath = "Your path";
try {
FileOutputStream fos = new FileOutputStream(strFilePath);
String strContent = "Write File using Java ";
fos.write(strContent.getBytes());
fos.close();
}
catch(FileNotFoundException ex) {
System.out.println("FileNotFoundException : " + ex);
}
catch(IOException ioe) {
System.out.println("IOException : " + ioe);
}
}
}
I think you misunderstood what the java.io.File class really represents. It is just a representation of the file on your system, i.e. its name, its path etc.
Did you even look at the Javadoc for the java.io.File class? Have a look here
If you check the fields it has or the methods or constructor arguments, you immediately get the hint that all it is, is a representation of the URL/path.
Oracle provides quite an extensive tutorial in their Java File I/O tutorial, with the latest NIO.2 functionality too.
With NIO.2 you can read it in one line using java.nio.file.Files.readAllBytes().
Similarly you can use java.nio.file.Files.write() to write all bytes in your byte array.
UPDATE
Since the question is tagged Android, the more conventional way is to wrap the FileInputStream in a BufferedInputStream and then wrap that in a ByteArrayInputStream.
That will allow you to read the contents in a byte[]. Similarly the counterparts to them exist for the OutputStream.
You can't do this. A File is just an abstract way to refer to a file in the file system. It doesn't contain any of the file contents itself.
If you're trying to create an in-memory file that can be referred to using a File object, you aren't going to be able to do that, either, as explained in this thread, this thread, and many other places..
Apache FileUtil gives very handy methods to do the conversion
try {
File file = new File(imagefilePath);
byte[] byteArray = new byte[file.length()]();
byteArray = FileUtils.readFileToByteArray(file);
}catch(Exception e){
e.printStackTrace();
}
There is no such functionality but you can use a temporary file by File.createTempFile().
File temp = File.createTempFile(prefix, suffix);
// tell system to delete it when vm terminates.
temp.deleteOnExit();
You cannot do it for File, which is primarily an intelligent file path. Can you refactor your code so that it declares the variables, and passes around arguments, with type OutputStream instead of FileOutputStream? If so, see classes java.io.ByteArrayOutputStream and java.io.ByteArrayInputStream
OutputStream outStream = new ByteArrayOutputStream();
outStream.write(whatever);
outStream.close();
byte[] data = outStream.toByteArray();
InputStream inStream = new ByteArrayInputStream(data);
...
1- Traditional way
The traditional conversion way is through using read() method of InputStream as the following:
public static byte[] convertUsingTraditionalWay(File file)
{
byte[] fileBytes = new byte[(int) file.length()];
try(FileInputStream inputStream = new FileInputStream(file))
{
inputStream.read(fileBytes);
}
catch (Exception ex)
{
ex.printStackTrace();
}
return fileBytes;
}
2- Java NIO
With Java 7, you can do the conversion using Files utility class of nio package:
public static byte[] convertUsingJavaNIO(File file)
{
byte[] fileBytes = null;
try
{
fileBytes = Files.readAllBytes(file.toPath());
}
catch (Exception ex)
{
ex.printStackTrace();
}
return fileBytes;
}
3- Apache Commons IO
Besides JDK, you can do the conversion using Apache Commons IO library in 2 ways:
3.1. IOUtils.toByteArray()
public static byte[] convertUsingIOUtils(File file)
{
byte[] fileBytes = null;
try(FileInputStream inputStream = new FileInputStream(file))
{
fileBytes = IOUtils.toByteArray(inputStream);
}
catch (Exception ex)
{
ex.printStackTrace();
}
return fileBytes;
}
3.2. FileUtils.readFileToByteArray()
public static byte[] convertUsingFileUtils(File file)
{
byte[] fileBytes = null;
try
{
fileBytes = FileUtils.readFileToByteArray(file);
}
catch(Exception ex)
{
ex.printStackTrace();
}
return fileBytes;
}
Server side
#RequestMapping("/download")
public byte[] download() throws Exception {
File f = new File("C:\\WorkSpace\\Text\\myDoc.txt");
byte[] byteArray = new byte[(int) f.length()];
byteArray = FileUtils.readFileToByteArray(f);
return byteArray;
}
Client side
private ResponseEntity<byte[]> getDownload(){
URI end = URI.create(your url which server has exposed i.e. bla
bla/download);
return rest.getForEntity(end,byte[].class);
}
public static void main(String[] args) throws Exception {
byte[] byteArray = new TestClient().getDownload().getBody();
FileOutputStream fos = new
FileOutputStream("C:\\WorkSpace\\testClient\\abc.txt");
fos.write(byteArray);
fos.close();
System.out.println("file written successfully..");
}
//The file that you wanna convert into byte[]
File file=new File("/storage/0CE2-EA3D/DCIM/Camera/VID_20190822_205931.mp4");
FileInputStream fileInputStream=new FileInputStream(file);
byte[] data=new byte[(int) file.length()];
BufferedInputStream bufferedInputStream=new BufferedInputStream(fileInputStream);
bufferedInputStream.read(data,0,data.length);
//Now the bytes of the file are contain in the "byte[] data"
/*If you want to convert these bytes into a file, you have to write these bytes to a
certain location, then it will make a new file at that location if same named file is
not available at that location*/
FileOutputStream fileOutputStream =new FileOutputStream(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS).toString()+"/Video.mp4");
fileOutputStream.write(data);
/* It will write or make a new file named Video.mp4 in the "Download" directory of
the External Storage */

Java ObjectOutputStream Not Writing to ZipEntry

I am trying to serialize an object into a ZipEntry using an ObjectOutputStream, however it doesn't appear to be writing anything because when I print the byte array produced, it shows null. I tried writing a string with the ZipOutputStream, and upon printing the resulting byte array got a sizeable result. SO my question is: why is the objectoutput stream not correctly writing into the ZipEntry. (ConfigEntry does implement Serializable).
String s = "Tired, Exhausted";
ConfigEntry con = new ConfigEntry("rand", "random", 3);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
try {
ZipOutputStream zos = new ZipOutputStream(baos);
ZipEntry entry = new ZipEntry("test.txt");
ObjectOutputStream obs = new ObjectOutputStream(zos);
zos.putNextEntry(entry);
obs.writeObject(con);
obs.close();
zos.closeEntry();
zos.close();
} catch(IOException ioe) {
ioe.printStackTrace();
}
os = bs.getOutputStream();
byte[] result = baos.toByteArray();
String test = new String(result, "UTF-8");
Log.v("Mac Address", test);
Log.v("Mac Address", Arrays.toString(result));
ByteArrayOutputStream baos = new ByteArrayOutputStream();
This baos goes out of scope after the try block. You are writing to one baos and you are looking into another baos declared in an outer scope, probably an instance member of the class.

Read first bytes of a file

I need a very simple function that allows me to read the first 1k bytes of a file through FTP. I want to use it in MATLAB to read the first lines and, according to some parameters, to download only files I really need eventually. I found some examples online that unfortunately do not work. Here I'm proposing the sample code where I'm trying to download one single file (I'm using the Apache libraries).
FTPClient client = new FTPClient();
FileOutputStream fos = null;
try {
client.connect("data.site.org");
// filename to be downloaded.
String filename = "filename.Z";
fos = new FileOutputStream(filename);
// Download file from FTP server
InputStream stream = client.retrieveFileStream("/pub/obs/2008/021/ab120210.08d.Z");
byte[] b = new byte[1024];
stream.read(b);
fos.write(b);
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (fos != null) {
fos.close();
}
client.disconnect();
} catch (IOException e) {
e.printStackTrace();
}
}
the error is in stream which is returned empty. I know I'm passing the folder name in a wrong way, but I cannot understand how I have to do. I've tried in many way.
I've also tried with the URL's Java classes as:
URL url;
url = new URL("ftp://data.site.org/pub/obs/2008/021/ab120210.08d.Z");
URLConnection con = url.openConnection();
BufferedInputStream in =
new BufferedInputStream(con.getInputStream());
FileOutputStream out =
new FileOutputStream("C:\\filename.Z");
int i;
byte[] bytesIn = new byte[1024];
if ((i = in.read(bytesIn)) >= 0) {
out.write(bytesIn);
}
out.close();
in.close();
but it is giving an error when I'm closing the InputStream in!
I'm definitely stuck. Some comments about would be very useful!
Try this test
InputStream is = new URL("ftp://test:test#ftp.secureftp-test.com/bookstore.xml").openStream();
byte[] a = new byte[1000];
int n = is.read(a);
is.close();
System.out.println(new String(a, 0, n));
it definitely works
From my experience when you read bytes from a stream acquired from ftpClient.retrieveFileStream, for the first run it is not guarantied that you get your byte buffer filled up. However, either you should read the return value of stream.read(b); surrounded with a cycle based on it or use an advanced library to fill up the 1024 length byte[] buffer:
InputStream stream = null;
try {
// Download file from FTP server
stream = client.retrieveFileStream("/pub/obs/2008/021/ab120210.08d.Z");
byte[] b = new byte[1024];
IOUtils.read(stream, b); // will call periodically stream.read() until it fills up your buffer or reaches end-of-file
fos.write(b);
} catch (IOException e) {
e.printStackTrace();
} finally {
IOUtils.closeQuietly(inputStream);
}
I cannot understand why it doesn't work. I found this link where they used the Apache library to read 4096 bytes each time. I read the first 1024 bytes and it works eventually, the only thing is that if completePendingCommand() is used, the program is held for ever. Thus I've removed it and everything works fine.

How can I write a byte array to a file in Java?

How to write a byte array to a file in Java?
As Sebastian Redl points out the most straight forward now java.nio.file.Files.write. Details for this can be found in the Reading, Writing, and Creating Files tutorial.
Old answer:
FileOutputStream.write(byte[]) would be the most straight forward. What is the data you want to write?
The tutorials for Java IO system may be of some use to you.
You can use IOUtils.write(byte[] data, OutputStream output) from Apache Commons IO.
KeyGenerator kgen = KeyGenerator.getInstance("AES");
kgen.init(128);
SecretKey key = kgen.generateKey();
byte[] encoded = key.getEncoded();
FileOutputStream output = new FileOutputStream(new File("target-file"));
IOUtils.write(encoded, output);
As of Java 1.7, there's a new way: java.nio.file.Files.write
import java.nio.file.Files;
import java.nio.file.Paths;
KeyGenerator kgen = KeyGenerator.getInstance("AES");
kgen.init(128);
SecretKey key = kgen.generateKey();
byte[] encoded = key.getEncoded();
Files.write(Paths.get("target-file"), encoded);
Java 1.7 also resolves the embarrassment that Kevin describes: reading a file is now:
byte[] data = Files.readAllBytes(Paths.get("source-file"));
A commenter asked "why use a third-party library for this?" The answer is that it's way too much of a pain to do it yourself. Here's an example of how to properly do the inverse operation of reading a byte array from a file (sorry, this is just the code I had readily available, and it's not like I want the asker to actually paste and use this code anyway):
public static byte[] toByteArray(File file) throws IOException {
ByteArrayOutputStream out = new ByteArrayOutputStream();
boolean threw = true;
InputStream in = new FileInputStream(file);
try {
byte[] buf = new byte[BUF_SIZE];
long total = 0;
while (true) {
int r = in.read(buf);
if (r == -1) {
break;
}
out.write(buf, 0, r);
}
threw = false;
} finally {
try {
in.close();
} catch (IOException e) {
if (threw) {
log.warn("IOException thrown while closing", e);
} else {
throw e;
}
}
}
return out.toByteArray();
}
Everyone ought to be thoroughly appalled by what a pain that is.
Use Good Libraries. I, unsurprisingly, recommend Guava's Files.write(byte[], File).
To write a byte array to a file use the method
public void write(byte[] b) throws IOException
from BufferedOutputStream class.
java.io.BufferedOutputStream implements a buffered output stream. By setting up such an output stream, an application can write bytes to the underlying output stream without necessarily causing a call to the underlying system for each byte written.
For your example you need something like:
String filename= "C:/SO/SOBufferedOutputStreamAnswer";
BufferedOutputStream bos = null;
try {
//create an object of FileOutputStream
FileOutputStream fos = new FileOutputStream(new File(filename));
//create an object of BufferedOutputStream
bos = new BufferedOutputStream(fos);
KeyGenerator kgen = KeyGenerator.getInstance("AES");
kgen.init(128);
SecretKey key = kgen.generateKey();
byte[] encoded = key.getEncoded();
bos.write(encoded);
}
// catch and handle exceptions...
Apache Commons IO Utils has a FileUtils.writeByteArrayToFile() method. Note that if you're doing any file/IO work then the Apache Commons IO library will do a lot of work for you.
No need for external libs to bloat things - especially when working with Android. Here is a native solution that does the trick. This is a pice of code from an app that stores a byte array as an image file.
// Byte array with image data.
final byte[] imageData = params[0];
// Write bytes to tmp file.
final File tmpImageFile = new File(ApplicationContext.getInstance().getCacheDir(), "scan.jpg");
FileOutputStream tmpOutputStream = null;
try {
tmpOutputStream = new FileOutputStream(tmpImageFile);
tmpOutputStream.write(imageData);
Log.d(TAG, "File successfully written to tmp file");
}
catch (FileNotFoundException e) {
Log.e(TAG, "FileNotFoundException: " + e);
return null;
}
catch (IOException e) {
Log.e(TAG, "IOException: " + e);
return null;
}
finally {
if(tmpOutputStream != null)
try {
tmpOutputStream.close();
} catch (IOException e) {
Log.e(TAG, "IOException: " + e);
}
}
File file = ...
byte[] data = ...
try{
FileOutputStream fos = FileOutputStream(file);
fos.write(data);
fos.flush();
fos.close();
}catch(Exception e){
}
but if the bytes array length is more than 1024 you should use loop to write the data.

Java: Need to create PDF from byte-Array

From a DB2 table I've got blob which I'm converting to a byte array so I can work with it. I need to take the byte array and create a PDF out of it.
This is what I have:
static void byteArrayToFile(byte[] bArray) {
try {
// Create file
FileWriter fstream = new FileWriter("out.pdf");
BufferedWriter out = new BufferedWriter(fstream);
for (Byte b: bArray) {
out.write(b);
}
out.close();
} catch (Exception e) {
System.err.println("Error: " + e.getMessage());
}
}
But the PDF it creates is not right, it has a bunch of black lines running from top to bottom on it.
I was actually able to create the correct PDF by writing a web application using essentially the same process. The primary difference between the web application and the code about was this line:
response.setContentType("application/pdf");
So I know the byte array is a PDF and it can be done, but my code in byteArrayToFile won't create a clean PDF.
Any ideas on how I can make it work?
Sending your output through a FileWriter is corrupting it because the data is bytes, and FileWriters are for writing characters. All you need is:
OutputStream out = new FileOutputStream("out.pdf");
out.write(bArray);
out.close();
One can utilize the autoclosable interface that was introduced in java 7.
try (OutputStream out = new FileOutputStream("out.pdf")) {
out.write(bArray);
}
Read from file or string to bytearray.
byte[] filedata = null;
String content = new String(bytearray);
content = content.replace("\r", "").replace("\uf8ff", "").replace("'", "").replace("\"", "").replace("`", "");
String[] arrOfStr = content.split("\n");
PDDocument document = new PDDocument();
PDPage page = new PDPage();
document.addPage(page);
try (PDPageContentStream cs = new PDPageContentStream(document, page)) {
// setting font family and font size
cs.beginText();
cs.setFont(PDType1Font.HELVETICA, 14);
cs.setNonStrokingColor(Color.BLACK);
cs.newLineAtOffset(20, 750);
for (String str: arrOfStr) {
cs.newLineAtOffset(0, -15);
cs.showText(str);
}
cs.newLine();
cs.endText();
}
document.save(znaFile);
document.close();
public static String getPDF() throws IOException {
File file = new File("give complete path of file which must be read");
FileInputStream stream = new FileInputStream(file);
byte[] buffer = new byte[8192];
ByteArrayOutputStream baos = new ByteArrayOutputStream();
int bytesRead;enter code here
while ((bytesRead = stream.read(buffer)) != -1) {
baos.write(buffer, 0, bytesRead);
}
System.out.println("it came back"+baos);
byte[] buffer1= baos.toByteArray();
String fileName = "give your filename with location";
//stream.close();
FileOutputStream outputStream =
new FileOutputStream(fileName);
outputStream.write(buffer1);
return fileName;
}

Categories

Resources