1

ファイルDoc、xls、ppt、およびVsdのメタデータ(標準およびカスタム)のみを変更するプログラムを実行しています。プログラムは正常に動作しますが、ファイル全体をメモリにロードせずにこれを行う方法があるかどうか疑問に思います:

POIFSFileSystem POIFS = 新しい POIFSFileSystem (新しい FileInputStream ("file.xls"))

NPOIFSFileSystem メソッドはより高速で、メモリの消費量も少なくなりますが、読み取り専用です。

私はApache POI 3.9を使用しています

4

2 に答える 2

0

目的のパーツをメモリにマップし、 を使用して作業することができますjava.nio.FileChannel

おなじみのバイト チャネルの読み取り、書き込み、およびクローズ操作に加えて、このクラスは次のファイル固有の操作を定義します。

  • バイトは、チャネルの現在の位置に影響を与えない方法で、ファイル内の絶対位置で読み書きできます。

  • ファイルの領域はメモリに直接マップできます。大きなファイルの場合、これは通常の読み取りまたは書き込みメソッドを呼び出すよりもはるかに効率的です。

于 2013-09-02T17:48:41.490 に答える
0

あなたの質問の時点では、悲しいことに、それを行うための非常にメモリの少ない方法はありませんでした。良いニュースは、2014 年 4 月 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 の例HPSF TestWrite 単体テストを参照してください)

于 2014-04-28T09:33:57.150 に答える