How can i zip multiple pdf files in Primefaces? - java

I want to zip multiple pdf files which are selected in the data-table and let the user download them.
Here is XHTML;
<p:commandLink id="print_orders"
value="Print Selected Orders" ajax="false"
onclick="PrimeFaces.monitorDownload(startPrint, stopPrint);"
styleClass="button button--ujarak button--border-thin button--text-medium download"
style="text-align: center; float:none; margin: 0px auto 0px auto; padding: 0.05em 0.1em;" >
<p:fileDownload value="#{printOrdersManagedBeanSAP.printsAction()}" />
</p:commandLink>
Let me clarify managedbean side;
purchaseOrder object includes PO_NUMBER() I generate pdf document (pdfDoc) as ByteArrayOutputStream from SAP with PO_NUMBER(). With for loop I tried to produce zip file includes pdf documents as much as the selected column. By the way I'm not sure I did it right.
With "return (StreamedContent) output;" code block I tried to return zip file but I get "java.util.zip.ZipOutputStream cannot be cast to org.primefaces.model.StreamedContent" exception. I tried to convert ZipOutputStream to StreamedContent because of <p:fileDownload> Primefaces tag.
Can you help me with how to fix this problem?
public StreamedContent printsAction()
{
if(!termsAgreed)
RequestContext.getCurrentInstance().execute("PF('warningDialog').show();");
else
{
if (getSelectedPurchaseOrders() != null && !getSelectedPurchaseOrders().isEmpty()) {
try
{
FileOutputStream zipFile = new FileOutputStream(new File("PO_Reports.zip"));
ZipOutputStream output = new ZipOutputStream(zipFile);
for (PurchaseOrderSAP purchaseOrder : getSelectedPurchaseOrders()) {
ByteArrayOutputStream pdfDoc = purchaseOrderSAPService.printOrder(selectedPurchaseOrder.getPO_NUMBER());
ZipEntry zipEntry = new ZipEntry(purchaseOrder.getPO_NUMBER());
output.putNextEntry(zipEntry);
InputStream targetStream = new ByteArrayInputStream(pdfDoc.toByteArray());
IOUtils.copy(targetStream, output);
output.closeEntry();
}
output.finish();
output.close();
return (StreamedContent) output;
}
catch(Exception ex)
{
System.out.println("error when generating...");
ex.printStackTrace();
}
}
}
return null;
}

You cannot simply cast a ZipOutputStream to StreamedContent as they don't have a parent child relation. See How can I cast objects that don't inherit each other?.
You should convert your InputStream (not the output stream) to streamed content. See for example https://www.primefaces.org/showcase/ui/file/download.xhtml
So, you need to do something like:
DefaultStreamedContent.builder()
.name("PO_Reports.zip")
.contentType("application/zip")
.stream(() -> yourInputStream)
.build();

I found solutions to these problems. Maybe this solution will help someone else. I would be grateful for any contribution on the new solution.
public StreamedContent printsAction() {
ByteArrayInputStream bis = null;
InputStream stream = null;
if (!termsAgreed) {
RequestContext.getCurrentInstance().execute("PF('warningDialog').show();");
} else {
if (getSelectedPurchaseOrders() != null && !getSelectedPurchaseOrders().isEmpty()) {
try {
if (zipBytes() != null) {
bis = new ByteArrayInputStream(zipBytes()); // Firstly I zip every PDF doc with zipBytes() method
stream = bis;
file = new DefaultStreamedContent(stream, "application/zip", "PO_Reports.zip",StandardCharsets.UTF_8.name());
return file;
} else {
return null;
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (bis != null) {
bis.close();
}
if (stream != null) {
stream.close();
}
} catch (Exception e2) {
e2.printStackTrace();
}
}
} else {
return null;
}
}
return null;
}
private byte[] zipBytes() {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ByteArrayOutputStream pdfDoc = new ByteArrayOutputStream();
ZipOutputStream zos = new ZipOutputStream(baos);
DataInputStream pdfDocIs = null;
byte[] result = null;
try {
for(PurchaseOrderSAP purchaseOrder : getSelectedPurchaseOrders()) {
pdfDoc = purchaseOrderSAPService.printOrder(purchaseOrder.getPO_NUMBER()); // PDF document comes from SAP as ByteArrayOutputStream
pdfDocIs = new DataInputStream(new ByteArrayInputStream(pdfDoc.toByteArray()));
ZipEntry zipEntry = new ZipEntry("PO_Report_" + purchaseOrder.getPO_NUMBER() + ".pdf");
zos.putNextEntry(zipEntry);
zos.write(toByteArray(pdfDocIs)); // Secondly in order to zip PDF doc i convert it to Byte Array with toByteArray method
}
zos.close();
result = baos.toByteArray();
} catch (Exception e) {
e.printStackTrace();
}
finally {
try {
if (baos != null) {
baos.close();
}
if (pdfDoc != null) {
pdfDoc.close();
}
if (zos != null) {
zos.close();
}
if (pdfDocIs != null) {
pdfDocIs.close();
}
} catch (Exception e2) {
e2.printStackTrace();
}
}
return result;
}
public static byte[] toByteArray(InputStream in) {
ByteArrayOutputStream os = new ByteArrayOutputStream();
byte[] buffer = new byte[1024];
byte[] result = null;
int len;
// read bytes from the input stream and store them in buffer
try {
while ((len = in.read(buffer)) != -1) {
// write bytes from the buffer into output stream
os.write(buffer, 0, len);
}
result = os.toByteArray();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (os != null) {
os.close();
}
} catch (Exception e2) {
e2.printStackTrace();
}
}
return result;
}

Related

Create and edit a File object in java without physically writing to hard disc

I am trying to create and edit a text file object in java. But once I execute the code, it is physically writing the file in root folder from which the program being executed. How can I do the same without physically writing the text file to hard disc?
File file = new File("tempFile.txt"); // Now the file is not created physically
writeIntoFile(file, listOfString); // After this, the file is created in disc
private static void writeIntoFile(File file, List<String> contents) {
Writer output;
try {
output = new BufferedWriter(new FileWriter(file.getPath(), true));
for (String content : contents) {
output.append(content);
output.append("\r\n");
}
output.close();
} catch (Exception e) {
e.printStackTrace();
}
}
Thanks #Gerome Tahud. The below code did the trick!
private static byte[] writeIntoFile(List<String> contents) {
try {
if (null != contents && contents.size() > 0) {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
for (String content : contents) {
content = content + "\r\n";
InputStream inputStream = new ByteArrayInputStream(content.getBytes());
byte[] buffer = new byte[8192];
int bytesRead;
while ((bytesRead = inputStream.read(buffer)) != -1) {
baos.write(buffer, 0, bytesRead);
}
}
return baos.toByteArray();
}
} catch (IOException e) {
e.printStackTrace();
}
return null;
}

How to mix two audio files in Android and then save؟

I have two audio files in MP3 format inside the user's phone
How can I mix these two sounds?
That is, I put these two sounds on top of each other and mix them, and then save the final sound in the user's phone
I looked everywhere but found nothing
this is my code:
private void mergeSongs(File mergedFile,File...mp3Files){
FileInputStream fisToFinal = null;
FileOutputStream fos = null;
try {
fos = new FileOutputStream(mergedFile);
fisToFinal = new FileInputStream(mergedFile);
for(File mp3File:mp3Files){
if(!mp3File.exists())
continue;
FileInputStream fisSong = new FileInputStream(mp3File);
SequenceInputStream sis = new SequenceInputStream(fisToFinal, fisSong);
byte[] buf = new byte[1024];
try {
for (int readNum; (readNum = fisSong.read(buf)) != -1;)
fos.write(buf, 0, readNum);
} finally {
if(fisSong!=null){
fisSong.close();
}
if(sis!=null){
sis.close();
}
}
}
} catch (IOException e) {
e.printStackTrace();
}finally{
try {
if(fos!=null){
fos.flush();
fos.close();
}
if(fisToFinal!=null){
fisToFinal.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
I have to finish the project today......help me!
You could use SequenceInputStream.
https://docs.oracle.com/javase/8/docs/api/java/io/SequenceInputStream.html
FileInputStream fileInputStream1 = new FileInputStream("/sdcard/mp3/sound1.mp3");
FileInputStream fileInputStream2 = new FileInputStream("/sdcard/mp3/sound2.mp3");
SequenceInputStream sequenceInputStream = new SequenceInputStream(fileInputStream1, fileInputStream2);

Java FileOutputStream Created file Not unlocking

Currently am facing a problem with FileOutputStream in my code used FileOutputStream for creating file in my disk .Once file created there is no way for opening , deleting or moving file from its location ,getting error message already locked by other user When stopped web server it working properly .how can i solve this issue.
private void writeToFile(InputStream uploadedInputStream,
String uploadedFileLocation) {
try {
OutputStream out = new FileOutputStream(new File(
uploadedFileLocation));
int read = 0;
byte[] bytes = new byte[1024];
out = new FileOutputStream(new File(uploadedFileLocation));
while ((read = uploadedInputStream.read(bytes)) != -1) {
out.write(bytes, 0, read);
}
out.flush();
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
You are creating two instances of FileOutputStream and assigning both to out, but only closing one.
Remove the second out = new FileOutputStream(new File(uploadedFileLocation));.
Also, you should consider using a try-with-resources block
private void writeToFile(InputStream uploadedInputStream,
String uploadedFileLocation) {
try (OutputStream out = new FileOutputStream(new File(uploadedFileLocation))) {
int read = 0;
byte[] bytes = new byte[1024];
while ((read = uploadedInputStream.read(bytes)) != -1) {
out.write(bytes, 0, read);
}
} catch (IOException e) {
e.printStackTrace();
}
}
or finally block to ensure that the streams are closed
private void writeToFile(InputStream uploadedInputStream,
String uploadedFileLocation) {
OutputStream out = null;
try {
out = new FileOutputStream(new File(uploadedFileLocation))
int read = 0;
byte[] bytes = new byte[1024];
while ((read = uploadedInputStream.read(bytes)) != -1) {
out.write(bytes, 0, read);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (out != null) {
try {
out.close();
} catch (IOException exp) {
}
}
}
}
See The try-with-resources Statement for more details

reading deflated data from the stream using inflater and InflaterInputStream

I'm trying to send a deflated string over http, when I use compression and decompression on the server side, without using streams, it's ok but when I write it to stream like this:
byte[] deflatedData = mtext.getByte();
try {
t.sendResponseHeaders(200,deflatedData.length);
} catch (IOException e1) {
display(e1);
e1.printStackTrace();
if(closeafter){
t.close();
}
return;
}
DeflaterOutputStream os = new DeflaterOutputStream(t.getResponseBody());
try {
os.write(deflatedData ,0,deflatedData .length);
} catch (IOException e1) {
mByte = null;
display(e1);
if(closeafter){
t.close();
}
return;
}
os.flush();
os.close();
and read from client side like this:
InflaterInputStream ini = new
InflaterInputStream(response.body().byteStream());
ByteArrayOutputStream bout =new ByteArrayOutputStream(512);
int b;
while ((b = ini.read()) != -1) {
bout.write(b);
}
ini.close();
bout.close();
String s=new String(bout.toByteArray());
android decompresses like this:
public static byte[] decompress(byte[] data) throws IOException, DataFormatException{
Inflater inflater = new Inflater();
inflater.setInput(data);
ByteArrayOutputStream outputStream = new ByteArrayOutputStream(data.length);
byte[] buffer = new byte[1024];
while (!inflater.finished()) {
int count = inflater.inflate(buffer);
outputStream.write(buffer, 0, count);
}
byte[] output = outputStream.toByteArray();
outputStream.close();
inflater.end();
return output;
}
so I get the following exception:
java.util.zip.DataFormatException: data error
Where am I going wrong?
The sending part was totally ok , The answer was to Use InflaterInputStream Directly from the input stream , like this:
public static String ReadDeflatedData(InputStream input){
InflaterInputStream in = new InflaterInputStream(input, new Inflater());
int bytesRead=0;
StringBuilder sb = new StringBuilder();
byte[] contents = null;
try {
contents = new byte[in.available()];
} catch (IOException e2) {
// TODO Auto-generated catch block
e2.printStackTrace();
}
try {
while( (bytesRead = in.read(contents)) != -1){
sb.append(new String(contents, 0, bytesRead));
}
} catch (IOException e) {
System.out.println(e.toString());
e.printStackTrace();
}
try {
return new String(sb.toString().getBytes(),"UTF-8");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}

Downloaded jar file corrupted

I've got this code that downloads a .jar file from a specific URL and places it into a specific folder. The jar file downloaded is a mod for a game, meaning that it has to be downloaded and run correctly without being corrupted.
The problem is, each time I try downloading the file, it ends up being corrupted in some way and causing errors when it is loaded.
This is my download code:
final static int size=1024;
public static void downloadFile(String fAddress, String localFileName, String destinationDir, String modID) {
OutputStream outStream = null;
URLConnection uCon = null;
InputStream is = null;
try {
URL Url;
byte[] buf;
int ByteRead,ByteWritten=0;
Url= new URL(fAddress);
outStream = new BufferedOutputStream(new
FileOutputStream(destinationDir+"/"+localFileName));
uCon = Url.openConnection();
is = uCon.getInputStream();
buf = new byte[size];
while ((ByteRead = is.read(buf)) != -1) {
outStream.write(buf, 0, ByteRead);
ByteWritten += ByteRead;
}
System.out.println("Downloaded Successfully.");
System.out.println("File name:\""+localFileName+ "\"\nNo ofbytes :" + ByteWritten);
System.out.println("Writing info file");
WriteInfo.createInfoFile(localFileName, modID);
}catch (Exception e) {
e.printStackTrace();
}
finally {
try {
is.close();
outStream.close();
}
catch (IOException e) {
e.printStackTrace();
}
}
}
Any ideas what is wrong with this code?
Not sure if this will solve your problem but you should flush your buffer at the end.
outStream.flush();
your code look like quite right; try this
public static void downloadFromUrl(String srcAddress, String userAgent, String destDir, String destFileName, boolean overwrite) throws Exception
{
InputStream is = null;
FileOutputStream fos = null;
try
{
File destFile = new File(destDir, destFileName);
if(overwrite && destFile.exists())
{
boolean deleted = destFile.delete();
if (!deleted)
{
throw new Exception(String.format("d'ho, an immortal file %s", destFile.getAbsolutePath()));
}
}
URL url = new URL(srcAddress);
URLConnection urlConnection = url.openConnection();
if(userAgent != null)
{
urlConnection.setRequestProperty("User-Agent", userAgent);
}
is = urlConnection.getInputStream();
fos = new FileOutputStream(destFile);
byte[] buffer = new byte[4096];
int len, totBytes = 0;
while((len = is.read(buffer)) > 0)
{
totBytes += len;
fos.write(buffer, 0, len);
}
System.out.println("Downloaded successfully");
System.out.println(String.format("File name: %s - No of bytes: %,d", destFile.getAbsolutePath(), totBytes));
}
finally
{
try
{
if(is != null) is.close();
}
finally
{
if(fos != null) fos.close();
}
}
}

Categories