Deleting PDF file after printing in Java - java

I'm trying to delete a PDF file after printing. The PDF is generated using JAVA code and needs to be deleted after the printing process is carried out. However, I am facing an issue while deleting the file. I can't seem to figure out what the problem is.
The error shown while trying to delete the file from its folder is:
"File in Use: The Action can't be completed because the file is open in Java(TM) Platform SE Binary."
The code I've used is as follows:
public String actionPrintReport() {
try {
// Creates a new document object
Document document = new Document(PageSize.LETTER);
File file = new File(fileLocation.concat("\\".concat(fileName)));
FileOutputStream fo = new FileOutputStream(file);
// Creates a pdfWriter object for the FILE
PdfWriter pdfWriter = PdfWriter.getInstance(document, fo);
// Open the document
document.open();
// Add meta data...
// Insert Data...
// Close the document
document.close();
// Create a PDFFile from a File reference
FileInputStream fis = new FileInputStream(file);
FileChannel fc = fis.getChannel();
ByteBuffer bb = fc.map(FileChannel.MapMode.READ_ONLY, 0, fc.size());
PDFFile pdfFile = new PDFFile(bb);
// Create PDF Print Page
PDFPrintPage pages = new PDFPrintPage(pdfFile);
// Create Print Job...
// Close
fo.flush();
fo.close();
fis.close();
if (file.exists()) {
if (file.delete()) {
String check = "yes";
} else {
String check = "no";
}
}
// Send print job to default printer
pjob.print();
actionMsg = "success";
return SUCCESS;
} catch (Exception e) {
e.printStackTrace();
}
return ERROR;
}

why not put the deletion in a finally block?
} catch (Exception e) {
e.printStackTrace();
} finally {
if (file.exists()) {
file.delete();
}
}
After discussion with the OP, an approach was investigated to use Apache FileCleaningTracker whereby the File is tracked and then deleted after a Monitored Object has been GC'd.

Related

JAVA Apache POI wrong document write output

I'm reading a file, adding some data to paragraphs, and then writing out a document another file.
The problem I'm facing is that the output file is unreadable, I can't open it, and if a binary open it I can see that it don't have the correct format.
Every character has a ? character at the left side.
Can you give me some advice about what is happening?
Wrong output
Correct output
EDIT: Code Save function
FileOutputStream out = null;
try {
// Add true to make the data append possible in output stream.
out = new FileOutputStream(filePath, true);
doc.write(out);
out.flush();
} catch (Exception ex) {
ex.printStackTrace();
} finally {
out.close();
}
Edit file:
File file = new File("muestra.doc");
FileInputStream fis = new FileInputStream(file.getAbsolutePath());
POIFSFileSystem fs = new POIFSFileSystem(fis);
HWPFDocument document = new HWPFDocument(fs);
Range range = document.getRange();
for (int i = 0; i < document.getParagraphTable().getParagraphs().size(); i++) {
Paragraph p = range.getParagraph(i);
p.insertBefore("£");
}

Return as ByteArrayOutputStream instead of FileOutputStream

I have a requirement to generate PDF file from JSON Objects and am able to produce PDF document using Apache FOP and Java. But i want to return the PDF file as ByteArrayOutputStream and then i have to encode like this Base64.getEncoder().encodeToString(baos.toByteArray()).
Please find the below code where am able to generate PDF file, instead of FileOutputStream i want to return as ByteArrayOutputStream.
ByteArrayOutputStream outStream = new ByteArrayOutputStream();
Transformer xslfoTransformer;
try
{
xslfoTransformer = getTransformer(transformSource);
Fop fop;
try
{
fop = fopFactory.newFop
(MimeConstants.MIME_PDF, outStream);
Result res = new SAXResult(fop.getDefaultHandler());
ITextRenderer renderer = new ITextRenderer();
try
{
xslfoTransformer.transform(source, res);
File pdffile = new File("Result.pdf");
OutputStream out = new java.io.FileOutputStream(pdffile);
out = new java.io.BufferedOutputStream(out);
FileOutputStream str = new FileOutputStream(pdffile);
str.write(outStream.toByteArray());
str.close();
out.close();
}
catch (TransformerException e) {
throw e;
}
}
catch (FOPException e) {
throw e;
}
}
catch (TransformerConfigurationException e)
{
throw e;
}
catch (TransformerFactoryConfigurationError e)
{
throw e;
}
I am slightly confused to what you are asking.
I have not used Apache Fop, but will try answer this question.
If you want to read PDF file as byte array use input streams instead.
But if you want to use ByteArrayOutputStream that is writing bytes you basically answered your own question, try using existing BAOS that you created initially and you are using in FileOutputStream, that's assuming the byte array output stream is reading bytes via some InputStream or some other source. Second assumption is that BAOS and FOS were able to properly write PDF file you were talking about.
You can simply do:
byte[] b = outStream.toByteArray();
String str = Base64.getEncoder().encodeToString(b);

Return Zip File from ZipOutputStream in Java

I have a function which creates a Zip file from a list of files. Is it possible to return the Zip file without it being saved on the disk? I need the file as I have to use the zip file as a parameter for another function. I am not sure of the ByteStream would be an option for me.
public File compressFileList(List<File> fileList,String fileName) {
FileOutputStream fileOutputStream=null;
ZipOutputStream zipOutputStream=null;
FileInputStream fileInputStream=null;
String compressedFileName=fileName +".zip";
if(fileList.isEmpty())
return null;
try
{
fileOutputStream = new FileOutputStream(compressedFileName);
zipOutputStream = new ZipOutputStream(new BufferedOutputStream(fileOutputStream));
for (File file: fileList) {
fileInputStream = new FileInputStream(file);
ZipEntry zipEntry = new ZipEntry(file.getName());
zipOutputStream.putNextEntry(zipEntry);
byte[] tmp = new byte[4*1024];
int size = 0;
while((size = fileInputStream.read(tmp)) != -1){
zipOutputStream.write(tmp, 0, size);
}
zipOutputStream.flush();
fileInputStream.close();
}
zipOutputStream.close();
return compressedFile; //This is what I am missing
}
catch (FileNotFoundException e)
{
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
EDIT : adding the use case
The idea is to create a zip file and use the CreateClassifierOptions method of VisualRecognition Service of Watson.
classifierOptions = new CreateClassifierOptions.Builder()
.classifierName("Santa")
.addClass("Santa", new File("C:\\app\\GitRepo\\images\\beagle.zip"))
.negativeExamples(new File("C:\\app\\GitRepo\\images\\nosport.zip"))
.build();
The builder accepts the zip file as the parameter.
Understanding
Based on the explanation from Alexandre Dupriez, I think it is better to store the file at some place on the hard disk.
You should be able to use a ByteArrayOutputStream instead of a FileOutputStream:
zipOutputStream = new ZipOutputStream(new ByteArrayOutputStream());
The difficulty here is to provide a File to the method consuming the zip file. The java.io.File does not provide an abstraction which allows you to manipulate in-memory files.
The java.io.File abstraction and java.io.FileInputStream implementation
To simplify, if we had to boil down what the File abstraction is, we would see it as a URI. And therefore, to be able to build an in-memory File, or at least mimic it, we would need to provide an URI which would then be used by the consumer of the File to read its content.
If we look at the FileInputStream which the consumer is likely to use, we can see that it always ends up with a native call which gives us to possibility whatsoever to abstract a FileSystem for in-memory files:
// class java.io.FileInputStream
/**
* Opens the specified file for reading.
* #param name the name of the file
*/
private native void open0(String name) throws FileNotFoundException;
It would be easier if there was a possibility to adapt the consumer to accept an InputStream, but from your problem statement I guess this is not possible.
API call
Your requirement is to provide a File to the Watson Visual API.
Could you please provide the API method you need to call?
public void compressFileList(List<File> fileList, OutputStream outputStream)
throws IOException {
try (ZipOutputStream zipOutputStream =
new ZipOutputStream(new BufferedOutputStream(outputStream));
for (File file: fileList) {
try (FileInputStream fileInputStream = new FileInputStream(file)) {
ZipEntry zipEntry = new ZipEntry(file.getName());
zipOutputStream.putNextEntry(zipEntry);
byte[] tmp = new byte[4*1024];
int size = 0;
while((size = fileInputStream.read(tmp)) != -1){
zipOutputStream.write(tmp, 0, size);
}
zipOutputStream.flush();
} catch (FileNotFoundException e) { // Maybe skip not found files.
Logger.log(Level.INFO, "File not found {}", file.getPath());
}
}
}
}
Usage:
if (fileList.isEmpty()) {
...
return;
}
try {
compressFileList(fileList, servletRequest.getOutputStream())) {
} catch (FileNotFoundException e) {
...
} catch (IOException e) {
...
}

update IFile content in eclipse plugin

I have a File that I would like to update based on some user menu selection.
My code gets the IFile
if it does not exist it's been created (with the user's content),and if it exists it should be updated.
My current code is:
String userString= "original String"; //This will be set by the user
byte[] bytes = userString.getBytes();
InputStream source = new ByteArrayInputStream(bytes);
try {
if( !file.exists()){
file.create(source, IResource.NONE, null);
}
else{
InputStream content = file.getContents();
//TODO augment content
file.setContents(content, 1, null);
}
} catch (CoreException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
IDE.openEditor(page, file);
My problem is that even though I get the original content and set the file's content, I am getting an empty file upon update , i.e., the entire content is being deleted.
What am I doing wrong?
This version of the code in your comment works for me:
InputStream inputStream = file.getContents();
StringWriter writer = new StringWriter();
// Copy to string, use the file's encoding
IOUtils.copy(inputStream, writer, file.getCharset());
// Done with input
inputStream.close();
String theString = writer.toString();
theString = theString + " added";
// Get bytes using the file's encoding
byte[] bytes = theString.getBytes(file.getCharset());
InputStream source = new ByteArrayInputStream(bytes);
file.setContents(source, IResource.FORCE, null);
Note the close of the original input stream and the use of file.getCharset() to use the correct encoding.

Creating a file dynamically through jsp

I have a block of jsp code like this. Here blockerdata, criticaldata, majordata and minordata are stringbuilder strings and their value is appended through a loop and value is assigned dynamically. Now I'm tryong to write them into an xml file like this.
<%
System.out.println(blockerdata);
System.out.println(criticaldata);
System.out.println(majordata);
System.out.println(minordata);
try
{
File file1 = new File("WebContent/criticaldata.xml");
File file2 = new File("WebContent/majordata.xml");
File file3 = new File("WebContent/minordata.xml");
File file4 = new File("WebContent/blockerdata.xml");
FileOutputStream fop1 = new FileOutputStream(file1);
FileOutputStream fop2 = new FileOutputStream(file2);
FileOutputStream fop3 = new FileOutputStream(file3);
FileOutputStream fop4 = new FileOutputStream(file4);
// if file doesnt exists, then create it
if (!file1.exists()) {
file1.createNewFile();
}
if (!file2.exists()) {
file2.createNewFile();
}
if (!file3.exists()) {
file3.createNewFile();
}
if (!file4.exists()) {
file4.createNewFile();
}
// get the content in bytes
byte[] contentInBytes1= criticaldata.toString().getBytes();
byte[] contentInBytes2= majordata.toString().getBytes();
byte[] contentInBytes3= minordata.toString().getBytes();
byte[] contentInBytes4= blockerdata.toString().getBytes();
fop1.write(contentInBytes1);
fop2.write(contentInBytes1);
fop3.write(contentInBytes1);
fop4.write(contentInBytes1);
fop1.flush();
fop2.flush();
fop3.flush();
fop4.flush();
fop1.close();
fop2.close();
fop3.close();
fop4.close();
}
catch ( IOException e)
{
}
%>
Problem is, the code doesn't seem to be working. I tried to do it using printwriter also but
the files are not being generated. Also I want to rewrite the file if it already exists. Can somebody please help me on how to do this ?

Categories