Can't delete file after calling FontFactory.getFont() method

437 views Asked by At

I am using iTextPdf 5.5.3 to create PDF/A documents, I want the user to select custom fonts by uploading the .ttf file of the font, and becuase FontFactory.getFont() method only takes the font name as a string I have to write the uploaded file to the user's drive (I KNOW, I ASKED MY CUSTOMER FOR PERMISSION TO WRITE TO THE DRIVE) and then pass the path of the uploaded file to the getFont() method, after everything is finished I want to delete the uploaded files from the drive. Here is my code:

File fontFile = new File("d:/temp/testFont.ttf");
try {
    FileOutputStream outStream = new FileOutputStream(fontFile);
    outStream.write(the bytes of the uploaded font file);

    outStream.flush();
    outStream.close();                          
} catch (FileNotFoundException e) {
    e.printStackTrace();
} catch (IOException e) {
    e.printStackTrace();
}


Font font = FontFactory.getFont(fontFile.getAbsolutePath(), BaseFont.CP1250 , BaseFont.EMBEDDED);

fontFile.delete();

This code is not working, somehow the getFont() method is locking the font file and therefore the file is not being deleted. I tried lots of ways to do this, like: fontFile.deleteOnExit(); or FileDeleteStrategy.FORCE.delete("file path"); but nothing is working for me. Please advise. Thanks

1

There are 1 answers

2
Bruno Lowagie On BEST ANSWER

I am not going to answer the question mentioned in the title of your post (because it is a secondary). Instead I am going to answer the question in the body (which is the essential question).

You claim that FontFactory.getFont() requires a font file on the file system. That is not incorrect. However, that doesn't mean you can't create a font from a byte[].

You are trying to solve your problem by saving a ttf on disk (which is forbidden by your customer), but that isn't necessary. In a way, your customer is right: it's not a good idea to save the TTF as a temporary file on disk (which is why I'm ignoring your secondary question).

Take a look at the following createFont() method:

public static BaseFont createFont(String name,
        String encoding,
        boolean embedded,
        boolean cached,
        byte[] ttfAfm,
        byte[] pfb)
    throws DocumentException,
        IOException

This is how you should interpret the parameters in your case:

  • name - the name of the font (not the location)
  • encoding - the encoding to be applied to this font
  • embedded - true if the font is to be embedded in the PDF
  • cached - probably false in your case, as you won't be reusing the font in the JVM
  • ttfAfm - the bytes of the .ttf file
  • pfb - in your case, this value will benull (it only makes sense in the context of Type1 fonts).

Now you can meet the requirements of your customer and you do not need to introduce a suboptimal workaround.

Note: you are using iText 5.5.3 which is available under the AGPL. Please be aware that your customer will need to purchase a commercial license with iText Software as soon as he starts using iText in a web service, in a product,...