update IFile content in eclipse plugin - java

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.

Related

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

Deleting PDF file after printing in 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.

Read file path from utf-8 text file?

I have a UTF-8 text file example.txt that contains:
c:/temp/file.txt
I read the file content using this method:
public static String fileToString(final File file, final String charset) throws AppServerException
{
final byte[] buffer = new byte[(int) file.length()];
FileInputStream fileInputStream = null;
try
{
fileInputStream = new FileInputStream(file);
fileInputStream.read(buffer);
}
catch (final FileNotFoundException e)
{
throw new AppServerException(e.getMessage());
}
catch (final IOException e)
{
throw new AppServerException(e.getMessage());
}
finally
{
FileHelper.close(fileInputStream);
}
try
{
return new String(buffer,charset);
}
catch (UnsupportedEncodingException e)
{
throw new AppServerException(e.getMessage());
}
}
Then I want to check if the file c:/temp/file.txt exists:
String content = fileToString("example.txt","UTF8");
File file = new File(content );
System.out.println(file.exists());
The exits() return false but the file actually exists.
If I change the encoding of example.txt to ANSI using notepad++, the exists() return true.
I already tried using:
"c:\temp\file.txt",
"c:\\temp\\file.txt",
"c:\\\\temp\\\\file.txt",
but without success.
I really need to use the file as UTF8. Do you have tips so the method exists() returns true?
Notepad++ probably puts a Byte Order Mark in front of the file. This is unnecessary for UTF-8 and Java does not interpret this sequence of three characters.
Either use an editor that does not use a Byte Order Mark or write the string in ANSI if your filename does not contain any non-ASCII characters.
Perhaps the file is not actually encoded as UTF-8. Can you print the actual byte values of the "\" characters in the file?
While you are at it: InputStream.read(byte[] b) is not guaranteed to read b.length bytes from the stream. You should be reading in a loop and checking the return value of the read() method in order to see how many bytes were actually read in each call.

How to update content of the file in Alfresco?

My java-backed webscript copies file in a repository to a temp folder and edits it for my needs. During its work a new content is generated and it must be written to a created temporary file.
But there is a problem: the first nor the second code below does not updates file's content.
ContentWriter contentWriter = this.contentService.getWriter(tempFile,
ContentModel.PROP_CONTENT, true);
contentWriter.putContent(content);
And the second:
`
WritableByteChannel byteChannel = contentWriter.getWritableChannel();
ByteBuffer buffer = ByteBuffer.wrap(content.getBytes());
byteChannel.write(buffer);
byteChannel.close();
`
How to update file's content?
This works for me:
ContentWriter contentWriter = contentService.getWriter(noderef, ContentModel.PROP_CONTENT, true);
contentWriter.setMimetype("text/csv");
FileChannel fileChannel = contentWriter.getFileChannel(false);
ByteBuffer bf = ByteBuffer.wrap(logLine.getBytes());
try {
fileChannel.position(contentWriter.getSize());
fileChannel.write(bf);
fileChannel.force(false);
fileChannel.close();
} catch (IOException e){
e.printStackTrace();
}
I'm appending a line to an existing file, so logLine is the appending string.

Java: PDF converter works in Mac but in Windows, produce empty PDF file

I need a little help here with my PDF converter program.
So, I'm doing this mobile agent PDF converter using JADE framework. But, the problem that I am facing is more related to the way I convert a text file into PDF, send it across network as binary and restore PDF file back.
The program that I've written works properly on my MacBook.
But, on a Windows, it restores my PDF file as an empty PDF.
Here is my code that I use for sending the PDF file across.
private void sendPDF(File f, String recipient) {
String content = "";
if(f != null) {
try {
FileInputStream fis = new FileInputStream(f);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
int noBytesRead = 0;
byte[] buffer = new byte[1024];
while((noBytesRead = fis.read(buffer)) != -1) {
baos.write(buffer, 0, noBytesRead);
}
content = baos.toString();
fis.close();
baos.close();
System.out.println("Successful PDF-to-byte conversion.");
} catch (Exception e) {
System.out.println("Exception while converting PDF-to-byte.");
content = "failed";
e.printStackTrace();
}
} else {
System.out.println("PDF-to-file conversion failed.");
content = "failed";
}
ACLMessage message = new ACLMessage(ACLMessage.INFORM);
message.addReceiver(new AID(recipient, AID.ISLOCALNAME));
message.setContent(content);
myAgent.send(message);
System.out.println("PDF document has been sent to requesting client.");
}
And, here is the code that I use to restore the PDF back.
private File restorePDF(String content) {
String dirPDF = dirBuffer + "/" + new Date().getTime() + ".pdf";
File f = new File(dirPDF);
try {
if(!f.exists()) f.createNewFile();
byte[] buffer = new byte[1024];
ByteArrayInputStream bais = new ByteArrayInputStream(content.getBytes());
FileOutputStream fos = new FileOutputStream(f);
int noBytesRead = 0;
while((noBytesRead = bais.read(buffer)) != -1) {
fos.write(buffer, 0, noBytesRead);
}
fos.flush();
fos.close();
bais.close();
} catch (Exception e) {
e.printStackTrace();
f = null;
}
return f;
}
Any help on this would be much appreciated! :)
Question is a little bit confusing, since there is nothing specific about PDF content.
I am supposing you actually want to send bytes, actually send a string, and the string encoding is different on the client and server.
This is usually where troubles happen:
content = baos.toString();
and:
content.getBytes()
A PDF file is a binary file format with lookup tables and lots of binary data blocks to making it a String will break it. If you want to know about the insides of a PDF file, I have written a whole load of blog posts about it (http://www.jpedal.org/PDFblog/2010/09/understanding-the-pdf-file-format-series/)
One issue is that you're using the wrong separator char. Java has a built in function that will return the correct char for the correct os. See separator char.
Your code will look something like this
String dirPDF = dirBuffer + File.separatorChar + new Date().getTime() + ".pdf";
For reference:
separatorChar
The system-dependent default name-separator character. This field is
initialized to contain the first character of the value of the system
property file.separator. On UNIX systems the value of this field is
'/'; on Microsoft Windows systems it is '\'.

Categories