Read an Outlook MSG file

When Outlook Express saves an email, it uses the EML format which is a good thing because the format is a standard.

But Outlook (not the Express but the one with Office) can only save an email with the MSG format which is Microsoft specific.

1. Apache POI HSMF

http://poi.apache.org/hsmf/

HSMF is the POI Project’s pure Java implementation of the Outlook MSG format.

This example takes an MSG file and extracts the attachment(s).

POI 3.6:

import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.util.Iterator;
import java.util.Map;

import org.apache.poi.hsmf.MAPIMessage;
import org.apache.poi.hsmf.datatypes.AttachmentChunks;
import org.apache.poi.hsmf.exceptions.ChunkNotFoundException;

// You need poi-scratchpad-3.6  and poi-3.6 ( http://poi.apache.org/ )

public class DetectMSGAttachment {
  public static void main (String ... args) throws IOException {
    String msgfile = "c:/temp/messagewithattachment.msg";
    MAPIMessage msg = new MAPIMessage(msgfile);
    Map attachmentMap = msg.getAttachmentFiles();
    if(attachmentMap.size() > 0) {
      for (Iterator ii = attachmentMap.entrySet().iterator(); ii.hasNext();) {
        Map.Entry entry = (Map.Entry)ii.next();
        String attachmentfilename = entry.getKey().toString();
        System.out.println(attachmentfilename);

        // extract attachment
        ByteArrayInputStream fileIn = (ByteArrayInputStream)entry.getValue();
        File f = new File("c:/temp", attachmentfilename); // output
        OutputStream fileOut = null;
        try {
          fileOut = new FileOutputStream(f);
          byte[] buffer = new byte[2048];
          int bNum = fileIn.read(buffer);
          while(bNum > 0) {
            fileOut.write(buffer);
            bNum = fileIn.read(buffer);
          }
        }
        finally {
          try {
            if(fileIn != null) {
              fileIn.close();
            }
          }
          finally {
            if(fileOut != null) {
              fileOut.close();
            }
          }
        }
      }
    }
    else {
      System.out.println("No attachment");
    }
  }
}

POI 3.7:

import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.util.Iterator;
import java.util.Map;

import org.apache.poi.hdgf.chunks.Chunk;
import org.apache.poi.hsmf.MAPIMessage;
import org.apache.poi.hsmf.datatypes.AttachmentChunks;
import org.apache.poi.hsmf.datatypes.Chunks;
import org.apache.poi.hsmf.exceptions.ChunkNotFoundException;

// You need poi-scratchpad-3.7  and poi-3.7 ( http://poi.apache.org/ )
public class DetectMSGAttachment {
    public static void main (String ... args) throws IOException {
        String msgfile = "c:/temp/messagewithattachment.msg";
        MAPIMessage msg = new MAPIMessage(msgfile);
        AttachmentChunks attachments[] = msg.getAttachmentFiles();
        if(attachments.length > 0) {
            for (AttachmentChunks a  : attachments) {
                System.out.println(a.attachLongFileName);
                // extract attachment
                ByteArrayInputStream fileIn = new ByteArrayInputStream(a.attachData.getValue());
                File f = new File("c:/temp", a.attachLongFileName.toString()); // output
                OutputStream fileOut = null;
                try {
                    fileOut = new FileOutputStream(f);
                    byte[] buffer = new byte[2048];
                    int bNum = fileIn.read(buffer);
                    while(bNum > 0) {
                        fileOut.write(buffer);
                        bNum = fileIn.read(buffer);
                    }
                }
                finally {
                    try {
                        if(fileIn != null) {
                            fileIn.close();
                        }
                    }
                    finally {
                        if(fileOut != null) {
                            fileOut.close();
                        }
                    }
                }
            }
        }
        else {

            System.out.println("No attachment");
        }
    }
}

2. Using msgparser library

http://auxilii.com/msgparser/

msgparser is a small open-source Java library that parses Outlook .msg files and provides their content using Java objects. msgparser uses the Apache POI – POIFS library to parse the message files which use the OLE 2 Compound Document format.

import java.util.List;
import com.auxilii.msgparser.*;
import com.auxilii.msgparser.attachment.*;

public class SimpleMsgParser {
  public static void main(String[] args) throws Exception{
    MsgParser msgp = new MsgParser();
    Message msg = msgp.parseMsg("c:/temp/test2.msg");

    String fromEmail = msg.getFromEmail();
    String fromName = msg.getFromName();
    String subject = msg.getSubject();
    String body = msg.getBodyText();

    System.out.println("From :" + fromName + " <" + fromEmail + ">");
    System.out.println("Subject :" + subject);
    System.out.println("");
    System.out.println(body);
    System.out.println("");

    List atts = msg.getAttachments();
    for (Attachment att : atts) {
      if (att instanceof FileAttachment) {
        FileAttachment file = (FileAttachment) att;
        System.out.println("Attachment : " + file.getFilename());
        // you get the actual attachment with
        // byte date[] = file.getData();
      }
    }
  }
}

3. Using jmbox

https://jmbox.dev.java.net/

The jmbox project (read jambox) is a Local Store Provider for JavaMail, enabling developers to use JavaMail api to manage the mail stored in local repositories like Outlook Express, Mozilla, Netscape etc.

At the moment are supported navigation and reading from Outlook Express 5/6 mail (dbx format).

Done! Happy Coding!

Related posts:

Immutable Objects in Java
Java Program to Use Dynamic Programming to Solve Approximate String Matching
Constructor Dependency Injection in Spring
Java Program to Implement Hash Tables Chaining with Doubly Linked Lists
Java Program to Implement Knapsack Algorithm
Autoboxing và Unboxing trong Java
Quick Guide to @RestClientTest in Spring Boot
Java Program to Implement SimpeBindings API
Convert a Map to an Array, List or Set in Java
Java InputStream to String
Spring Cloud AWS – EC2
Hướng dẫn sử dụng String Format trong Java
Java Program to Implement LinkedHashSet API
Java Program to Implement PriorityBlockingQueue API
Java Program to Implement Ford–Fulkerson Algorithm
Java Program to Implement Sorted Singly Linked List
Setting a Request Timeout for a Spring REST API
Tạo ứng dụng Java RESTful Client không sử dụng 3rd party libraries
Java Program to Solve Set Cover Problem assuming at max 2 Elements in a Subset
HashSet trong Java hoạt động như thế nào?
LIKE Queries in Spring JPA Repositories
Handling Errors in Spring WebFlux
Java Program to Implement CopyOnWriteArrayList API
Giới thiệu JDBC Connection Pool
A Guide to the ResourceBundle
Java 8 Streams peek() API
The “final” Keyword in Java
Spring Security Authentication Provider
A Guide to Apache Commons Collections CollectionUtils
OAuth2 for a Spring REST API – Handle the Refresh Token in Angular
Java Program to Implement Dijkstra’s Algorithm using Priority Queue
Java Program to Create a Balanced Binary Tree of the Incoming Data