Friday, April 8, 2011

Create a Java File object (or equivalent) using a byte array in memory (without a physical file)

I want to create a Java File object in memory (without creating a physical file) and populate its content with a byte array.

Can this be done?

The idea is to pass it to a Spring InputStreamSource. I'm trying the method below, but it returns saying "the byte array does not contain a file name.".

MimeMessage message = mailSender.createMimeMessage();
MimeMessageHelper helper = new MimeMessageHelper(message);   
helper.setFrom("no-reply@xxx.com", "xyz");
helper.setTo(email);
helper.setText(body,true);
helper.setSubject(subject);
helper.addInline("cImage",
        new InputStreamResource(new ByteArrayInputStream(imageByteArr)));

mailSender.send(message);
From stackoverflow
  • Maybe you need to use the other constructor of InputStreamResource?

  • Can you paste the full stack trace? There is no such thing as an "in memory" file. Using a ByteArrayInputStream should be sufficient.


    You need to implement Resource#getFilename(). Try the following:

    helper.addInline("cImage", new ByteArrayResource(imageByteArr){
                @Override
                public String getFilename() {
                    return fileName;
                }
            });
    
    ninesided : also works perfectly with 'addAttachment'
  • Have you tried changing the resource you feed to addInline()? If you wanted the resource to be in memory, I would have tried a org.springframework.core.io.ByteArrayResource.

    Update: I think you might need to use the DataSource version of the addInline() method and then use a byte array bound data source object to feed the data into the helper class. I would try the following:

    MimeMessage message = mailSender.createMimeMessage();
    MimeMessageHelper helper = new MimeMessageHelper(message);              
    helper.setFrom("no-reply@xxx.com", "xyz");
    helper.setTo(email);
    helper.setText(body,true);
    helper.setSubject(subject);
    
    // use javax.mail.util.ByteArrayDataSource
    ByteArrayDataSource imgDS = new ByteArrayDataSource( imageByteArr, "image/png");
    helper.addInline("cImage", imgDS);
    
    mailSender.send(message);
    
    Dan : You might need to use the version of addInLine() that accepts a DataSource as your second parameter. There is a javax.util.mail.ByteArrayDataSource that implements the functionality of wrapping a byte array without a physical file.
  • Maybe its worth trying a different overload of the method:

    addInline(String contentId, 
              InputStreamSource inputStreamSource, 
              String contentType)
    

    I.e.:

    addInline("cImage", 
              new InputStreamSource () 
              {  
                 final private InputStream src = 
                                         new ByteArrayInputStream(imageByteArr);
                 public InputStream getInputStream() {return src;}
              },
              "image/jpeg"); // or whatever image type you use
    
  • It is important to create the MimeMessageHelper object correctly to support attachments and inline resources.

    Example: MimeMessageHelper helper = new MimeMessageHelper(message, true, "UTF-8");

    In this example since multipart is set to true MULTIPART_MODE_MIXED_RELATED will be used and attachments and inline resouces will be supported.

0 comments:

Post a Comment