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

标签 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)
    ...

提前致谢。

最佳答案

Outlook 确实提供了包含以下信息的 FileDescriptor:

  • 掉落的元素数量
  • 对于每个项目:指向 IStorage 的文件名(例如 Test.msg + IDataObject)
  • 每个拖动的项目有一个 IStorage
  • IStorage 将是一个符合 MS 复合文件规范的虚拟文件系统(用于 MS Office - 例如 .xls、.doc,也包括 .msg)。
  • IStorage 类似于文件/文件夹结构,其中文件夹由 IStorage 对象表示,文件由 IStream 表示
  • 在 IStream 中,我们可以找到电子邮件的实际内容,例如:
    • 主题
    • 收件人
    • 电子邮件正文
    • 附件

我还为 Outlook 通过拖放界面传递二进制文件的假设而苦苦挣扎。由于与其他 Office 程序的互操作性,Outlook 采用复合文件结构。因此,人们需要将这些事情放在一起。如果将接收到的 Outlook 元素保存到文件中,则这不会是从 Outlook 导出到磁盘时的 1:1(二进制相同),而是具有相同内容的文件。

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

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

使事情变得复杂的是使用指针的 Win32 OLE 接口(interface)。此外,如果您遇到错误,接口(interface)返回类型并不那么容易解释。

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

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

希望这对您有所帮助,如果您有更多问题,请在下面发表评论。

关于java - 将 Outlook 电子邮件和其他文件拖放到 Java 应用程序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30640496/

相关文章:

Windows Server 2003 中的 Java swing 错误

c - 我有一个文件,将其所有内容复制到一个数组中。例如,如何删除第一个字符串或中间字符串?

java - 在 Java 中从 Midi 文件读取 Midi 消息

java - 如何检测是否在osgi容器中运行

Java滑动拼图,知道什么时候完成吗?

Java Swing,文本区域作为输入/输出?

file - 流行的可导入日历格式列表?

java - Angularjs 将文件多部分 FormData 中的空值传递给 Spring MVC

java - 在 RecyclerView 中切换项目 View 类型

java - 如果任何模块中存在模拟实例,则在创建 RoboGuice 注入(inject)器期间进程崩溃