I am trying to save bytes[] data in a pdf and zip it up. Everytime I try, I get a blank pdf. Below is the code. Can anyone guide me what am I doing wrong?
byte[] decodedBytes = Base64.decodeBase64(contents);
ZipOutputStream zos = new ZipOutputStream(new BufferedOutputStream(new FileOutputStream("c:\\output\\asdwd.zip")));
//now create the entry in zip file
ZipEntry entry = new ZipEntry("asd.pdf");
zos.putNextEntry(entry);
zos.write(decodedBytes);
zos.close();
This is what I am following
To obtain the actual PDF document, you must decode the Base64-encoded string, save it as a binary file with a “.zip” extension, and then extract the PDF file from the ZIP file.
You don’t actually need to create a zip file. The instructions are telling you that the base64 data represents a zipped PDF, so you can unzip it in code and write the PDF file itself:
Path pdfFile = Files.createTempFile(null, ".pdf");
try (ZipInputStream zip = new ZipInputStream(
new ByteArrayInputStream(
Base64.getDecoder().decode(contents)))) {
ZipEntry entry;
while ((entry = zip.getNextEntry()) != null) {
String name = entry.getName();
if (name.endsWith(".pdf") || name.endsWith(".PDF")) {
Files.copy(zip, pdfFile, StandardCopyOption.REPLACE_EXISTING);
break;
}
}
}
Related
There are already many similar questions and tutorials available about this topic still I didn't found what I wanted to do.
I want to make an API, though which I can upload the zip file, that zip is containing xml files I am reading those files and sending the content as response.
The only problem here is currently I am storing the file inside of my project directory, but I don't want that I want to read the file directly without storing it in an directory.
So basically user will hit my API, upload the file and in response he will get the data present inside of files in that zip.
My Code:
#RequestMapping(value ="/upload", method = RequestMethod.POST, consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
public ResponseEntity<Object> uploadFile(#RequestParam("file")MultipartFile file) throws IOException {
System.out.println(file.getOriginalFilename());
File converFile = new File("src/main/"+file.getOriginalFilename());
converFile.createNewFile();
FileOutputStream fout = new FileOutputStream(converFile);
fout.write(file.getBytes());
//unzipping file and reading data;
String zipFileName = "src/main/"+file.getOriginalFilename();
List<String> str = new ArrayList<String>();
byte[] buffer = new byte[1024];
ZipInputStream zis = new ZipInputStream(new FileInputStream(zipFileName));
ZipEntry zipEntry;
int read;
while ((zipEntry = zis.getNextEntry())!= null) {
while ((read = zis.read(buffer, 0, 1024)) >= 0) {
str.add(new String(buffer,0,read));
}
}
while (zipEntry != null){
zipEntry = zis.getNextEntry();
}
zis.closeEntry();
zis.close();
System.out.println("Unzip complete");
System.out.println("--------------------------------");
System.out.println("List"+ str);
fout.close();
return new ResponseEntity<>(str, HttpStatus.OK);
}
This code is working fine uploading file saving it in project directory (src/main) and reading file data and giving the data as response.
How can I eliminate the saving part and do all these in code only.
You can use ByteArrayInputStream instead of FileInputStream, like this:
ZipInputStream zis = new ZipInputStream(new ByteArrayInputStream(file.getBytes()));
I am trying to get the shipment label from amazon merchant fulfillment as per the instructions mentioned on the Amazon pages.
"To obtain the actual PDF document, you must decode the Base64-encoded string, save it as a binary file with a “.zip” extension, and then extract the PDF file from the ZIP file."
Has any one got it to work. I have tried couple of things but every time i get blank pdf.
Here is my code. Can please some body guide me if I am doing it correctly
byte[] decodedBytes = Base64.decodeBase64(contents);
ZipOutputStream zos = new ZipOutputStream(new BufferedOutputStream(new FileOutputStream("c:\\output\\asdwd.zip")));
//now create the entry in zip file
ZipEntry entry = new ZipEntry("asd.pdf");
zos.putNextEntry(entry);
zos.write(decodedBytes);
zos.close();
The instructions say to save the bytes as a binary file with the extension .zip.
What you are actually doing is creating a ZIP file with the contents of the byte array as an entry.
According to my reading of the instructions, your code should do this:
byte[] decodedBytes = Base64.decodeBase64(contents);
FileOutputStream fos = new FileOutputStream("c:\\output\\asdwd.zip");
fos.write(decodedBytes);
fos.close();
Or better still:
byte[] decodedBytes = Base64.decodeBase64(contents);
try (FileOutputStream fos = new FileOutputStream("c:\\output\\asdwd.zip")) {
fos.write(decodedBytes);
}
Then using a ZIP tool or a web browser, open asdwd.zip, find the entry containing the PDF, and extract it or print it.
Here is the code to generate a shipping label in case somebody needs it.
byte[] decoded = Base64.decodeBase64(contents);
try (FileOutputStream fos = new FileOutputStream(zipFilePath + amazonOrderId + zipFileName)) {
fos.write(decoded);
fos.close();
}
file = new File(destDirectory + amazonOrderId + pngFile);
if (file.exists()) {
file.delete();
}
try (OutputStream out = new FileOutputStream(destDirectory + amazonOrderId + pngFile)) {
try (InputStream in = new GZIPInputStream(
new FileInputStream(zipFilePath + amazonOrderId + zipFileName))) {
byte[] buffer = new byte[65536];
int noRead;
while ((noRead = in.read(buffer)) != -1) {
out.write(buffer, 0, noRead);
}
}
}
I need to write a code to convert a byte array to ZIP file and make it download in Spring MVC.
Byte array is coming from a webservice which is a ZIP file originally. ZIP file has a folder and the folder contains 2 files. I have written the below code to convert to byte array to ZipInputStream. But I am not able to convert into ZIP file. Please help me in this.
Here is my code.
ZipInputStream zipStream = new ZipInputStream(new ByteArrayInputStream(bytes));
ZipEntry entry = null;
while ((entry = zipStream.getNextEntry()) != null) {
String entryName = entry.getName();
FileOutputStream out = new FileOutputStream(entryName);
byte[] byteBuff = new byte[4096];
int bytesRead = 0;
while ((bytesRead = zipStream.read(byteBuff)) != -1)
{
out.write(byteBuff, 0, bytesRead);
}
out.close();
zipStream.closeEntry();
}
zipStream.close();
I am presuming here that you want to write a byte array to a ZIP file. As the data sent is also a ZIP file and to be saved is also ZIP file, shouldn't be a problem.
Two steps are needed: save it on disk and return the file.
1) Save on disk part:
File file = new File(/path/to/directory/save.zip);
if (file.exists() && file.isDirectory()) {
try {
OutputStream outputStream = new FileOutputStream(new File(/path/to/directory/save.zip));
outputStream.write(bytes);
outputStream.close();
} catch (IOException ignored) {
}
} else {
// create directory and call same code
}
}
2) Now to get it back and download it, you need a controller :
#RequestMapping(value = "/download/attachment/", method = RequestMethod.GET)
public void getAttachmentFromDatabase(HttpServletResponse response) {
response.setContentType("application/octet-stream");
response.setHeader("Content-Disposition", "attachment; filename=\"" + file.getFileName() + "\"");
response.setContentLength(file.length);
FileCopyUtils.copy(file as byte-array, response.getOutputStream());
response.flushBuffer();
}
I have edited the code I have, so you will have to make some changes before it suits you 100%. Let me know if this is what you were looking for. If not, I will delete my answer. Enjoy.
I have file with names like ex.zip. In this example, the Zip file contains only one file with the same name(ie. `ex.txt'), which is quite large. I don't want to extract the zip file every time.Hence I need to read the content of the file(ex.txt) without extracting the zip file. I tried some code like below But i can only read the name of the file in the variable.
How do I read the content of the file and stores it in the variable?
Thank you in Advance
fis=new FileInputStream("C:/Documents and Settings/satheesh/Desktop/ex.zip");
ZipInputStream zis = new ZipInputStream(new BufferedInputStream(fis));
ZipEntry entry;
while((entry = zis.getNextEntry()) != null) {
i=i+1;
System.out.println(entry);
System.out.println(i);
//read from zis until available
}
Your idea is to read the zip file as it is into a byte array and store it in a variable.
Later when you need the zip you extract it on demand, saving memory:
First read the content of the Zip file in a byte array zipFileBytes
If you have Java 1.7:
Path path = Paths.get("path/to/file");
byte[] zipFileBytes= Files.readAllBytes(path);
otherwise use Appache.commons lib
byte[] zipFileBytes;
zipFileBytes = IOUtils.toByteArray(InputStream input);
Now your Zip file is stored in a variable zipFileBytes, still in compressed form.
Then when you need to extract something use
ByteArrayInputStream bis = new ByteArrayInputStream(zipFileBytes));
ZipInputStream zis = new ZipInputStream(bis);
Try this:
String zipFile = "ex.zip";
try (ZipFile zip = new ZipFile(zipFile)) {
int i = 0;
for (Enumeration<? extends ZipEntry> e = zip.entries(); e.hasMoreElements(); ) {
ZipEntry entry = (ZipEntry) e.nextElement();
System.out.println(entry);
System.out.println(i);
InputStream in = zip.getInputStream(entry);
}
}
For example, if the file contains text, and you want to print it as a String, you can read the InputStream like this: How do I read / convert an InputStream into a String in Java?
I think that in your case the fact that a zipfile is a container that can hold many files (and thus forces you to navigate to the right contained file each time you open it) seriously complicates things, as you state that each zipfile only contains one textfile. Maybe it's a lot easier to just gzip the text file (gzip is not a container, just a compressed version of your data). And it's very simple to use:
GZIPInputStream gis = new GZIPInputStream(new FileInputStream("file.txt.gz"));
// and a BufferedReader on top to comfortably read the file
BufferedReader in = new BufferedReader(new InputStreamReader(gis) );
Producing them is equally simple:
GZIPOutputStream gos = new GZIPOutputStream(new FileOutputStream("file.txt.gz"));
I would like to unzip a file uploaded to a servlet, and store all decompressed files to the DataStore as byte[]. Since there is no file system in GAE, I have to put everything in memory. Suppose I have byte[] allzipdata to store the original zip file data. How do I unzip the file and especially how to get inputstream from each zipentry which are in memory?
ZipInputStream zis = new ZipInputStream(new ByteArrayInputStream(allzipdata));
ZipEntry ze = zis.getNextEntry();
while(ze!=null){
}
So what's in the while loop?
Also, if I upload a file, I know the contentType using item.getContentType(); in which item is a FileItemStream. So for a zipentry, is there a way to know the contentType?
To read image data from the ZipInputStream I'd recommend to use the Apache Commons-IO library. It converts the ZIP entry of the input stream to a byte array:
ZipInputStream zis = new ZipInputStream(new ByteArrayInputStream(allzipdata));
ZipEntry ze = null;
while ((ze = zis.getNextEntry()) != null) {
// write your code to use zip entry e.g. below:
String filename = ze.getName();
System.out.println("File Name of Entry file="+fileName);
byte[] data = IOUtils.toByteArray(zis);
// now work with the image `data`
}