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:

Spring Boot - CORS Support
Java Program to Compute the Volume of a Tetrahedron Using Determinants
Java Program to Find the GCD and LCM of two Numbers
Java Program to Find Path Between Two Nodes in a Graph
Java Program to Check Cycle in a Graph using Topological Sort
Java Program to Perform the Unique Factorization of a Given Number
Hướng dẫn sử dụng Java String, StringBuffer và StringBuilder
Giới thiệu Aspect Oriented Programming (AOP)
Java Program to Perform Postorder Non-Recursive Traversal of a Given Binary Tree
Spring Cloud AWS – S3
Handling Errors in Spring WebFlux
Spring Boot - Cloud Configuration Server
Spring Boot - Exception Handling
Java Program to Implement LinkedHashSet API
Java Program to Perform Inorder Recursive Traversal of a Given Binary Tree
Quick Guide to the Java StringTokenizer
A Guide to @RepeatedTest in Junit 5
Spring Boot - Cloud Configuration Client
Java Program to Implement Branch and Bound Method to Perform a Combinatorial Search
Java 8 – Powerful Comparison with Lambdas
Loại bỏ các phần tử trùng trong một ArrayList như thế nào?
Lớp HashMap trong Java
Java Program to Implement ArrayBlockingQueue API
Java Program to Convert a Decimal Number to Binary Number using Stacks
Constructor Injection in Spring with Lombok
Java Program to Implement Euclid GCD Algorithm
Java Program to Implement LinkedHashMap API
The SpringJUnitConfig and SpringJUnitWebConfig Annotations in Spring 5
Introduction to Spring Data REST
Convert Character Array to String in Java
Apache Commons Collections OrderedMap
Java Program to Implement Weight Balanced Tree