Getting damaged file error after downloading a pdf - java

I followed this example to let the user download the pdf :
Vaadin Example
/** Copied from example */
#Override
protected void init(VaadinRequest request) {
Button downloadButton = new Button("Download image");
StreamResource myResource = createResource();
FileDownloader fileDownloader = new FileDownloader(myResource);
fileDownloader.extend(downloadButton);
setContent(downloadButton);
}
/** modified from example */
private StreamResource createResource() throws IOException {
return new StreamResource(new StreamSource() {
byte[] bytes =loadFile("/home/amira/Desktop/repTest.pdf"); //Get the file bytes here
InputStream is = new ByteArrayInputStream(bytes);
#Override
public InputStream getStream() {
return is ;
}
}, "report.pdf");
}
public static byte[] readFully(InputStream stream) throws IOException {
byte[] buffer = new byte[8192];
ByteArrayOutputStream baos = new ByteArrayOutputStream();
int bytesRead;
while ((bytesRead = stream.read(buffer)) != -1) {
baos.write(buffer, 0, bytesRead);
}
return baos.toByteArray();
}
public static byte[] loadFile(String sourcePath) throws IOException {
InputStream inputStream = null;
try {
inputStream = new FileInputStream(sourcePath);
return readFully(inputStream);
} finally {
if (inputStream != null) {
inputStream.close();
}
}
}
When I try to open the file , it says damaged file

See my working sample (tested for 20Mb PDFs):
private void downloadDocument()
{
final String retrievalName = "222.pdf";
class FileDownloadResource extends FileResource
{
public FileDownloadResource(File sourceFile, Application application)
{
super(sourceFile, application);
}
public DownloadStream getStream()
{
try
{
byte[] DocContent = null;
DocContent = getFileBytes("C:\\Temp\\222.pdf");
if (DocContent != null)
{
final DownloadStream ds = new DownloadStream(new ByteArrayInputStream(DocContent), "application/pdf", retrievalName);
ds.setCacheTime(getCacheTime());
String fileName = URLEncoder.encode(retrievalName, "UTF8");
// force download!
ds.setParameter("Content-Disposition", "attachment; filename*=\"utf-8'" + fileName + "\"");
return ds;
}
else
{
return null;
}
}
catch (Exception e1)
{
e1.printStackTrace();
return null;
}
}
}
getApplication().getMainWindow().open(new FileDownloadResource(new File(retrievalName), getApplication()));
}
/**
* getFileBytes
*
* #author NBochkarev
*
* #param fileOut
* #return
* #throws IOException
*/
public static byte[] getFileBytes(String fileName) throws IOException
{
ByteArrayOutputStream ous = null;
InputStream ios = null;
try
{
byte[] buffer = new byte[4096];
ous = new ByteArrayOutputStream();
ios = new FileInputStream(new File(fileName));
int read = 0;
while ((read = ios.read(buffer)) != -1)
ous.write(buffer, 0, read);
}
finally
{
try
{
if (ous != null)
ous.close();
}
catch (IOException e)
{
// swallow, since not that important
}
try
{
if (ios != null)
ios.close();
}
catch (IOException e)
{
// swallow, since not that important
}
}
return ous.toByteArray();
}

Related

How can i zip multiple pdf files in Primefaces?

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

Java PrintWriter printing multiple blank lines at the beginning of each file

I have used PrintWriter for long time and I have never encounted with this problem. See below
When I open the csv file using excel the first element of the headerline disapeared.
To further investigate, I found a couple of blank lines inserted at the beginning when opening it using text file.
below is my code:
print header line:
public void printHubInboundHeader() {
try {
StringBuilder sb = new StringBuilder();
String headingPart1 = "Inbound_Hub, Date, Time,";
String headingPart2 = "Weight";
sb.append(headingPart1+headingPart2);
System.out.println(sb);
FileWriter.writeFile(sb.toString(),"filepath");
}
catch(Exception e) {
System.out.println("Something wrong when writting headerline");
e.printStackTrace();
}
}
print actual data:
public void printHubSummary(Hub hub, String filePath) {
try {
StringBuilder sb = new StringBuilder();
String h = hub.getHub_code();
String date = Integer.toString(hub.getGs().getDate());
String time = hub.getGs().getHHMMFromMinute(hub.getGs().getClock());
String wgt = Double.toString(hub.getIb_wgt());
sb.append(h+","+date+","+time+","+wgt);
// System.out.println("truck print line: " + sb);
FileWriter.writeFile(sb.toString(),filePath);
}
catch (Exception e) {
System.out.println("Something wrong when outputing truck summary file!");
e.printStackTrace();
}
}
the file writer code:
public class FileWriter {
private static String filenameTemp;
public static boolean creatFile(String name) throws IOException {
boolean flag = false;
filenameTemp = name + "";
System.out.println("write to file: "+filenameTemp);
File filename = new File(filenameTemp);
if (!filename.exists()) {
filename.createNewFile();
flag = true;
}
else {
filename.delete();
filename.createNewFile();
flag = true;
}
return flag;
}
public static boolean writeFile(String newStr, String filename) throws IOException {
boolean flag = false;
String filein = newStr + "\r\n";
String temp = "";
FileInputStream fis = null;
InputStreamReader isr = null;
BufferedReader br = null;
FileOutputStream fos = null;
PrintWriter pw = null;
try {
File file = new File(filename);
fis = new FileInputStream(file);
isr = new InputStreamReader(fis);
br = new BufferedReader(isr);
StringBuffer buf = new StringBuffer();
for (int j = 1; (temp = br.readLine()) != null; j++) {
buf = buf.append(temp);
buf = buf.append(System.getProperty("line.separator"));
}
buf.append(filein);
fos = new FileOutputStream(file);
byte[] unicode = {(byte)0xEF, (byte)0xBB, (byte)0xBF};
fos.write(unicode);
pw = new PrintWriter(fos);
pw.write(buf.toString().toCharArray());
pw.flush();
flag = true;
} catch (IOException e1) {
throw e1;
} finally {
if (pw != null) {
pw.close();
}
if (fos != null) {
fos.close();
}
if (br != null) {
br.close();
}
if (isr != null) {
isr.close();
}
if (fis != null) {
fis.close();
}
}
return flag;
}
public static void setFileName(String fileName){
filenameTemp = fileName;
}
}
I don't know if this is the only problem with your code, but every call to your FileWriter.writeFile adds a new Byte Order Marker to the file. This means you end up with several markers in the file, and this may confuse some tools.
To remove the extra BOM in FileWriter.writeFile, you can use the deleteCharAt method:
...
buf = buf.append(System.getProperty("line.separator"));
}
if (buf.length() > 0 && buf.charAt(0) == '\uFEFF') {
buf.deleteCharAt(0);
}
buf.append(filein);

Closing GZIPOutputStream after ByteStream copy in finally block break zip

I have code which Zip and Unzip Text. I'm facing weird behavior - only when I close the GZIPOutputStream in certain place, the code works but when I try to place the GZIPOutputStream close in the finally block, it breaks and does not work. If you place the : gzipoutputstream.close() in the czip function where comment is placed, it will work. However if you keep it only in finally block, it will break. Why?
the ByteStreams.copy function is from com.google.common.io guava
public class Main {
public static byte[] dzip(byte[] s) throws IOException {
ByteArrayInputStream sStream = null;
ByteArrayOutputStream oStream = null;
InputStream gzipoutputStream = null;
ByteBuffer arrReturn = null;
try {
sStream = new ByteArrayInputStream(s);
oStream = new ByteArrayOutputStream();
gzipoutputStream = new GZIPInputStream(sStream, 1024);
ByteStreams.copy(gzipoutputStream, oStream);
arrReturn = ByteBuffer.wrap(oStream.toByteArray());
}
catch (Exception e) {
return null;
} finally {
if (gzipoutputStream != null) {
gzipoutputStream.close();
}
if (oStream != null) {
oStream.close();
}
if (sStream != null) {
sStream.close();
}
}
return arrReturn.array();
}
public static byte[] czip(byte[] s) throws IOException {
ByteArrayInputStream sStream =null;
ByteArrayOutputStream oStream =null;
OutputStream gzipoutputstream = null;
byte[] returnValue = null;
try {
sStream = new ByteArrayInputStream(s);
oStream = new ByteArrayOutputStream(s.length / 2);
gzipoutputstream = new GZIPOutputStream(oStream, 1024);
ByteStreams.copy(sStream, gzipoutputstream);
//////////// ------------------------------------ \\\\\\\\\\\\
//gzipoutputstream.close(); // < --- Works only when placed here
//////////// ------------------------------------ \\\\\\\\\\\\
returnValue = oStream.toByteArray(); // Here the zip is 000
}catch(Exception e) {
return null;
} finally {
if (gzipoutputstream != null) {
gzipoutputstream.close();
}
if (oStream != null) {
oStream.close();
}
if (sStream != null) {
sStream.close();
}
}
return returnValue;
}
public static void main(String[] args) throws IOException {
String s = "12313dsfafafafaf";
byte[] source = (byte[]) s.getBytes();
byte[] returnZipByteArr = czip(source);
byte[] dd = dzip(returnZipByteArr);
String ss = new String(dd);
System.out.println(ss);
}
}
That's expected. The javadoc of close() says:
Writes remaining compressed data to the output stream and closes the underlying stream.
So if you try to access the bytes in the ByteArrayOutputStream() before close() has been called, the gzip compression hasn't been finished yet: the GZIP stream needs to know that nothing will never be written again to properly write the remaining data.
You could call finish() to have the same effect but without closing the stream (and thus still close it in the finally block).

automatically unzip file while downloading that zip file

I have a download button in my webpage where when i click it, it downloads a zip file. now i want to have a function like, when i click the download button the zip file should automatically extract and save in a user defined folder.
i have an idea that if we can create a exe file and add it to the download button then it should automatically extract the zip file and save in folder
%>
<td align="center">
<img onclick="pullReport('<%=reportPath.toString()%>');" title="Click to download this Report" src="./images/down-bt.gif"/>
</td>
</tr>
<%} %>
this is the method that creates zip file
public ActionForward pullReport(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response)throws SQLException{
Connection connection=null;
boolean cont=false;
failureList.clear();
logger.info("dispatch = pullReport");
String filePaths=null;
String filePath = null;
String fileName = null;
String srcFileName = null;
String directory = null;
try{
Properties props = Application.getProperties();
String basePath = props.getProperty("std.report_location");
logger.info(" basepath " + basePath);
connection=ConnectionManager.getConnection();
StandardReportsForm standardReportsForm=(StandardReportsForm)form;
filePaths=standardReportsForm.getFilePath();
logger.info("filepaths " + filePaths);
ServletOutputStream fos = null;
InputStream is = null;
String [] filePathArr = filePaths.split(",");
FileIO fio = null;
FileIO srcFio = null;
if (filePathArr.length > 1) {
filePath = filePathArr[0].substring(0,filePathArr[0].lastIndexOf("."))+".zip";
logger.info(filePath + " creating zip file ......");
directory = basePath+filePath.substring(0,filePath.lastIndexOf('/'));
logger.info( " Direcory Name :" +directory);
fileName = filePath.substring(filePath.lastIndexOf('/')+1);
logger.info( " File Name :" +fileName);
fio = new FileIO(directory,fileName);
fio.mkDir();
byte[] buffer = new byte[1024];
OutputStream fosForZip = fio.createOutputStream();
ZipOutputStream zos = new ZipOutputStream(fosForZip);
InputStream fis = null;
for (int i=0; i < filePathArr.length; i++) {
srcFileName = filePathArr[i].substring(filePathArr[i].lastIndexOf('/')+1);
srcFio = new FileIO(directory,srcFileName);
if (srcFio.isFileExist()) {
cont=true;
logger.info(" adding into zip file " +srcFileName);
fis = srcFio.createInputStream();
BufferedInputStream bis = new BufferedInputStream(fis);
zos.putNextEntry(new ZipEntry(srcFileName));
int length;
while ((length = bis.read(buffer)) != -1) {
zos.write(buffer, 0, length);
}
zos.closeEntry();
// close the InputStream
bis.close();
srcFio.closeInputStream(fis);
} else {
logger.info(srcFileName + " file does not exist on shared drive");
cont =false;
break;
}
}
FileIO.closeOutputStream(zos);
if (!cont){
standardReportsForm.setMissingFileName(srcFileName);
request.getSession().getAttribute("fetchReports");
standardReportsForm.setFetchedReports((List<ReportDetails>)request.getSession().getAttribute("fetchReports"));
return mapping.findForward("fetchReport");
}
} else {
filePath = filePathArr[0];
fileName = filePath.substring(filePath.lastIndexOf('/')+1);
}
if (basePath.startsWith("smb")) {
SmbFile smbFile = new SmbFile(basePath+filePath,SMBHelper.getInstance().createAuthFromSmbLocation(basePath));
if(smbFile.exists())
{
is = new SmbFileInputStream(smbFile);
cont=true;
}
} else {
File file=new File(basePath+filePath);
if(file.exists())
{
is = new FileInputStream(file);
cont=true;
}
}
if(cont)
{
fos=response.getOutputStream();
setContentType(response, fileName);
//fos.write (baos.toByteArray());
ByteArrayOutputStream bos = new ByteArrayOutputStream();
byte[] buf = new byte[1024];
for (int readNum; (readNum = is.read(buf)) != -1;) {
bos.write(buf, 0, readNum);
}
byte[] bytes = bos.toByteArray();
fos.write(bytes);
fos.flush();
fos.close();
} else {
standardReportsForm.setMissingFileName(fileName);
request.getSession().getAttribute("fetchReports");
standardReportsForm.setFetchedReports((List<ReportDetails>)request.getSession().getAttribute("fetchReports"));
return mapping.findForward("fetchReport");
}
}catch(SQLException sx) {
logger.error(" error log SQLException " ,sx);
failureList.add(new UROCException(UROCMessages.getMessage("ERR_CONN_EXEC"), sx));
} catch(NamingException ne) {
logger.info("RMI error is "+ne);
failureList.add(new UROCException(UROCMessages.getMessage("ERR_NAMING_EXEC"), ne));
} catch(Exception e) {
logger.error(" error log Exception " ,e);
failureList.add(new UROCException(UROCMessages.getMessage("ERR_GEN_EXEC", new String[] {"General Exception"}), e));
} finally {
SQLHelper.closeConnection(connection, failureList, logger);
}
return null;
}
yah you can use java code to unzip the file.here is the example
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
public class UnzipUtility {
public String zipFilePath= "D:/javatut/corejava/src/zipfile.zip";
public String destDir = "D:/javatut/corejava";
private static final int BUFFER_SIZE = 4096;
/**
* #param args
* #throws IOException
*/
public static void main(String[] args) throws IOException {
UnzipUtility uu = new UnzipUtility();
uu.unzip(uu.zipFilePath, uu.destDir);
}
public void unzip(String zipFilePath,String destDir)throws IOException{
File destDirectory = new File(destDir);
if(!destDirectory.exists()){
destDirectory.mkdir();
}
ZipInputStream zipIn = new ZipInputStream(new FileInputStream(zipFilePath));
ZipEntry zipEntry = zipIn.getNextEntry();
while(zipEntry!=null){
String filePath=destDir+File.separator+zipEntry.getName();
if(!zipEntry.isDirectory()){
extractFile(zipIn,filePath);
}
else{
File dir = new File(filePath);
dir.mkdir();
}
zipIn.closeEntry();
zipEntry = zipIn.getNextEntry();
}
zipIn.close();
}
private void extractFile(ZipInputStream zipIn, String filePath) throws FileNotFoundException {
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(filePath));
byte[] bytesIn = new byte[BUFFER_SIZE];
int read = 0;
try {
while ((read = zipIn.read(bytesIn)) != -1) {
bos.write(bytesIn, 0, read);
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
bos.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
thank you.......
please follow this path and (clear) automatic files viewer
chrome://settings/onStartup/Advanced/Downloads/automatic file viewer (clear)

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