将Outlook电子邮件和其他文件拖放到Java应用程序

时间:2015-06-04 09:47:12

标签: java swing file email drag-and-drop

我创建了一个Java应用程序,用户可以拖放文件将其保存到指定的文件夹中。我正在使用FileDrop,不幸的是,它无法处理直接从Outlook拖放的电子邮件。它首先将电子邮件放入桌面(创建.eml文件)然后放入应用程序,但我真的想绕过这一步。 您可以在下面看到我的代码:

new FileDrop(panel, new FileDrop.Listener() {
    public void filesDropped(java.io.File[] files) {
        for (int i=0; i<files.length; i++) {
            File newFile = files[i];
            byte[] myByteArray = null;
            try { //get the data of the file into a byte array
                myByteArray = org.apache.commons.io.FileUtils.readFileToByteArray(newFile);
            } catch (IOException e1) {
                e1.printStackTrace();
            }

            String newFileName = newFile.getName();

            try { //create the file
                FileOutputStream file = new FileOutputStream("projects/"+ newFileName);
                file.write(myByteArray);
                file.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
});

我很想听到这个问题的任何可能的解决方案 顺便说一下,这是我收到的错误消息的一部分,指出问题发生在public void filesDropped(java.io.File[] files) {行,因为丢弃到应用程序中的电子邮件尚未被识别为文件(我猜)

...
2015-06-04 12:10:50.860 java[718:71442] Couldn't get a copy of an HFS Promise from the pasteboard
2015-06-04 12:10:50.860 java[718:71442] Looked for HFSPromises on the pasteboard, but found none.
Exception in thread "AWT-EventQueue-0" java.lang.IllegalArgumentException: URI is not hierarchical
    at java.io.File.<init>(File.java:363)
    at net.iharder.dnd.FileDrop.createFileArray(FileDrop.java:453)
    ...

提前致谢。

1 个答案:

答案 0 :(得分:0)

Outlook确实为FileDescriptor提供了以下信息:

  • 掉落的物品数
  • 对于每个项目:指向IStorage的文件名(例如Test.msg + IDataObject)
  • 每个拖动的项目有一个IStorage
  • 根据化合物文件的MS规范(在MS Office中使用-例如,.xls,.doc和.msg),IStorage将是一个虚拟文件系统。
  • 然后,IStorage类似于文件/文件夹结构,其中文件夹由IStorage对象表示,文件由IStreams表示
  • 在IStream中,可以找到电子邮件的实际内容,例如:
    • 主题
    • 收件人
    • 电子邮件正文
    • 附件

我还花了很长时间来假设Outlook会通过Dragndrop界面传递二进制文件。由于与其他Office程序具有互操作性,因此Outlook通过了复合文件结构。因此,人们需要一起迷惑那些事情。如果将从Outlook中接收到的元素保存到文件中,那将不是1:1,就像您从Outlook中导出到磁盘(二进制相同)一样,而是具有相同内容的文件。

对于完整的解决方案,该方法的工作方式如下:

  • 获取文件描述符
  • 对于每个文件
    • 文件名
    • 指向IDataObject的指针
    • 从IDataObject获取根IStorage
      • 迭代IStorage的子元素
        • 如果子元素是IStream,则处理IStream
        • 如果子元素是IStorage,则递归返回“迭代子元素”

使之复杂的是使用指针的Win32 OLE接口。此外,如果遇到错误,接口返回类型也不那么容易解释。

有关更多详细信息,请在这篇文章中找到我的答案: Can I drag items from Outlook into my SWT application?

我创建了一个小型库,为Outlook项目提供了SWT传输类型。您可以在GitHub上找到它: https://github.com/HendrikHoetker/OutlookItemTransfer

希望这对您有帮助,如果您还有其他问题,请在下面发表评论。