优化DOC,XLS文件中的元数据写入

时间:2013-09-02 17:14:39

标签: java apache-poi apache-tika

我正在做一个只修改文件Doc,xls,ppt和Vsd中元数据(标准和自定义)的程序,程序正常工作但我想知道是否有办法在不加载整个文件的情况下执行此操作存储器:

POIFSFileSystem POIFS =新POIFSFileSystem(新FileInputStream(“file.xls”))

NPOIFSFileSystem方法速度更快,占用的内存更少,但只读。

我正在使用Apache POI 3.9

2 个答案:

答案 0 :(得分:0)

您可以将所需的部分映射到内存,然后使用java.nio.FileChannel处理它。

  

除了熟悉的字节通道的读,写和关闭操作外,该类还定义了以下特定于文件的操作:

     
    
      
          
  • 可以以不影响频道当前位置的方式在文件中的绝对位置读取或写入字节。

  •       
  • 文件的某个区域可以直接映射到内存中;对于大文件,这通常比调用通常的读取或写入方法更有效。

  •       
    
  

答案 1 :(得分:0)

在您提出问题时,遗憾的是,记忆力并不是很低。好消息是,截至2014-04-28,这是可能的! (这个代码应该在3.11发布时,但现在它太新了)

既然NPOIFS支持写作,包括就地写作,那么你想要做的就是:

// Open the file, and grab the entries for the summary streams
NPOIFSFileSystem poifs = new NPOIFSFileSystem(file, false);
DocumentNode sinfDoc = 
     (DocumentNode)root.getEntry(SummaryInformation.DEFAULT_STREAM_NAME);
DocumentNode dinfDoc = 
     (DocumentNode)root.getEntry(DocumentSummaryInformation.DEFAULT_STREAM_NAME);

// Open and parse the metadata
SummaryInformation sinf = (SummaryInformation)PropertySetFactory.create(
     new NDocumentInputStream(sinfDoc));
DocumentSummaryInformation dinf = (DocumentSummaryInformation)PropertySetFactory.create(
     new NDocumentInputStream(dinfDoc));

// Make some metadata changes
sinf.setAuthor("Changed Author");
sinf.setTitle("Le titre \u00e9tait chang\u00e9");
dinf.setManager("Changed Manager");

// Update the metadata streams in the file
sinf.write(new NDocumentOutputStream(sinfDoc));
dinf.write(new NDocumentOutputStream(dinfDoc));

// Write out our changes
fs.writeFilesystem();
fs.close();

你应该能够在文件大小不到20%的内存中完成所有这些操作,可能比大文件的内存少得多!

(如果您想了解更多信息,请查看ModifyDocumentSummaryInformation exampleHPSF TestWrite unit test