LHA Library for Java

jp.gr.java_conf.dangan.util.lha
Class LhaImmediateOutputStream

java.lang.Object
  extended by java.io.OutputStream
      extended by jp.gr.java_conf.dangan.util.lha.LhaImmediateOutputStream
All Implemented Interfaces:
java.io.Closeable, java.io.Flushable

public class LhaImmediateOutputStream
extends java.io.OutputStream

接続されたRandomAccessFileに 圧縮データを出力するためのユーティリティクラス。
java.util.zip.ZipOutputStream と似たインターフェイスを持つように作った。
圧縮失敗時( 圧縮後サイズが圧縮前サイズを上回った場合 )の処理を 手動で行わなければならない。 以下に そのようなコードを示す。

 LhaCompressFiles( String arcfile, File[] files ){
   LhaImmediateOutputStream lio = new LhaImmediateOutputStream( arcfile );
 
   for( int i = 0 ; i < files.length ; i++ ){
     RandomAccessFile raf = new RandomAccessFile( files[i] );
     LhaHeader header = new LhaHeader( files[i].getName() );
     header.setLastModified( new Date( files.lastModified() ) );
     header.setOriginalSize( files.length() );
     byte[] buffer  = new byte[8192];
     int    length;
 
     while( 0 <= ( length = raf.read( buffer ) ) ){
         lio.write( buffer, 0, length );
     }
 
     if( !lio.closeEntry() ){
       header.setCompressMethod( CompressMethod.LH0 );
       lio.putNextEntry( lhaheader );
       raf.seek( 0 );
       while( 0 <= ( length = raf.read( buffer ) ) ){
           lio.write( buffer, 0, length );
       }
       lio.closeEntry();
     }
 
   lio.close();
 }
 
進捗報告を実装する場合、このような処理をクラス内に隠蔽すると進捗報告は何秒間か 時によっては何十分も応答しなくなる。(例えばギガバイト級のデータを扱った場合) LhaRetainedOutputStream で発生する、このような事態を避けるために設計されている。
また、JDK 1.1 以前では RandomAccessFile が setLength を持たないため、 書庫データの後ろに他のデータがある場合でもファイルサイズを切り詰めることが出来ない。
この問題点は常にサイズ0の新しいファイルを開く事によって回避する事ができる。
 -- revision history --
 $Log: LhaImmediateOutputStream.java,v $
 Revision 1.2  2002/12/11 02:25:06  dangan
 [bug fix]
     jdk1.2 でコンパイルできなかった箇所を修正。

 Revision 1.1  2002/12/08 00:00:00  dangan
 [maintenance]
     LhaConstants から CompressMethod へのクラス名の変更に合わせて修正。

 Revision 1.0  2002/08/05 00:00:00  dangan
 add to version control
 [change]
     コンストラクタから 引数に String encode を取るものを廃止、
     Properties を引数に取るものを追加。
 [maintenance]
     ソース整備
     タブ廃止
     ライセンス文の修正

 

Version:
$Revision: 1.2 $
Author:
$Author: dangan $

Constructor Summary
LhaImmediateOutputStream(java.io.File filename)
          filename のファイルに 圧縮データを出力するOutputStreamを構築する。
各圧縮形式に対応した符号器の生成式等を持つプロパティには LhaProperty.getProperties() で得られたプロパティが使用される。
LhaImmediateOutputStream(java.io.File filename, java.util.Properties property)
          filename のファイルに 圧縮データを出力するOutputStreamを構築する。
LhaImmediateOutputStream(java.io.RandomAccessFile file)
          fileに 圧縮データを出力するOutputStreamを構築する。
各圧縮形式に対応した符号器の生成式等を持つプロパティには LhaProperty.getProperties() で得られたプロパティが使用される。
LhaImmediateOutputStream(java.io.RandomAccessFile file, java.util.Properties property)
          fileに 圧縮データを出力するOutputStreamを構築する。
各圧縮形式に対応した符号器の生成式等を持つプロパティには LhaProperty.getProperties() で得られたプロパティが使用される。
LhaImmediateOutputStream(java.lang.String filename)
          filename のファイルに 圧縮データを出力するOutputStreamを構築する。
各圧縮形式に対応した符号器の生成式等を持つプロパティには LhaProperty.getProperties() で得られたプロパティが使用される。
LhaImmediateOutputStream(java.lang.String filename, java.util.Properties property)
          filename のファイルに 圧縮データを出力するOutputStreamを構築する。
 
Method Summary
 void close()
          出力先に全てのデータを出力し、ストリームを閉じる。
また、使用していた全てのリソースを解放する。
 boolean closeEntry()
          現在出力中のエントリを閉じ、次のエントリが出力可能な状態にする。
putNextEntryNotYetCompressed() で開いたエントリを閉じる場合 このメソッドは圧縮に失敗した(圧縮後サイズが圧縮前サイズを上回った)場合、 エントリ全体を書き込み先 の RandomAccessFile から削除する。
この削除処理は単に ファイルポインタを エントリ開始位置まで巻き戻すだけなので RandomAccessFile に setLength() が無い jdk1.1 以前では エントリを無圧縮(もしくは他の圧縮法)で再出力しない場合、 書庫データの終端以降に圧縮に失敗した不完全なデータが残ったままになる。
 void flush()
          現在書き込み中のエントリのデータを強制的に出力先に書き出す。 これは PostLzssEncoder, LzssOutputStream の規約どおり flush() しなかった場合とは別のデータを出力する。 (大抵の場合は 単に圧縮率が低下するだけである。)
 void putNextEntry(LhaHeader header)
          新しいエントリを書き込むようにストリームを設定する。
このメソッドは 既に圧縮済みのエントリの場合は putNextEntryAlreadyCompressed(), 未だに圧縮されていない場合は putNextEntryNotYetCompressed() を呼び出す。
圧縮されているかの判定は、 header.getCompressedSize()
header.getCRC()
のどれか一つでも LhaHeader.UNKNOWN であれば未だに圧縮されていないとする。
header には正確な OriginalSize が指定されている必要がある。
 void putNextEntryAlreadyCompressed(LhaHeader header)
          既に圧縮済みのエントリを書きこむようにストリームを設定する。
圧縮済みデータが正しい事は、呼び出し側が保証する事。
 void putNextEntryNotYetCompressed(LhaHeader header)
          未だに圧縮されていないエントリを書きこむようにストリームを 設定する。header に CompressedSize,CRCが指定されていても無 視される。このメソッドに渡される header には LhaHeader.setOriginalSize() を用いて 正確なオリジナルサイズ が指定されている必要がある。
 void write(byte[] buffer)
          現在のエントリに bufferの内容を全て書き出す。
 void write(byte[] buffer, int index, int length)
          現在のエントリに bufferの indexから lengthバイトのデータを書き出す。
 void write(int data)
          現在のエントリに1バイトのデータを書きこむ。
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Constructor Detail

LhaImmediateOutputStream

public LhaImmediateOutputStream(java.lang.String filename)
                         throws java.io.FileNotFoundException
filename のファイルに 圧縮データを出力するOutputStreamを構築する。
各圧縮形式に対応した符号器の生成式等を持つプロパティには LhaProperty.getProperties() で得られたプロパティが使用される。

Parameters:
filename - 圧縮データを書きこむファイルの名前
Throws:
java.io.FileNotFoundException - filename で与えられたファイルが見つからない場合。
java.lang.SecurityException - セキュリティマネージャがファイルへのアクセスを許さない場合。
See Also:
LhaProperty.getProperties()

LhaImmediateOutputStream

public LhaImmediateOutputStream(java.lang.String filename,
                                java.util.Properties property)
                         throws java.io.FileNotFoundException
filename のファイルに 圧縮データを出力するOutputStreamを構築する。

Parameters:
filename - 圧縮データを書きこむファイルの名前
property - 各圧縮形式に対応した符号器の生成式等が含まれるプロパティ
Throws:
java.io.FileNotFoundException - filename で与えられたファイルが見つからない場合。
java.lang.SecurityException - セキュリティマネージャがファイルへのアクセスを許さない場合。
See Also:
LhaProperty

LhaImmediateOutputStream

public LhaImmediateOutputStream(java.io.File filename)
                         throws java.io.IOException
filename のファイルに 圧縮データを出力するOutputStreamを構築する。
各圧縮形式に対応した符号器の生成式等を持つプロパティには LhaProperty.getProperties() で得られたプロパティが使用される。

Parameters:
filename - 圧縮データを書きこむファイルの名前
Throws:
java.io.FileNotFoundException - filename で与えられたファイルが見つからない場合。
java.lang.SecurityException - セキュリティマネージャがファイルへのアクセスを許さない場合。
java.io.IOException - JDK1.2 でコンパイルするためだけに存在する。
See Also:
LhaProperty.getProperties()

LhaImmediateOutputStream

public LhaImmediateOutputStream(java.io.File filename,
                                java.util.Properties property)
                         throws java.io.IOException
filename のファイルに 圧縮データを出力するOutputStreamを構築する。

Parameters:
filename - 圧縮データを書きこむファイルの名前
property - 各圧縮形式に対応した符号器の生成式等が含まれるプロパティ
Throws:
java.io.FileNotFoundException - filename で与えられたファイルが見つからない場合。
java.lang.SecurityException - セキュリティマネージャがファイルへのアクセスを許さない場合。
java.io.IOException - JDK1.2 でコンパイルするためだけに存在する。
See Also:
LhaProperty

LhaImmediateOutputStream

public LhaImmediateOutputStream(java.io.RandomAccessFile file)
fileに 圧縮データを出力するOutputStreamを構築する。
各圧縮形式に対応した符号器の生成式等を持つプロパティには LhaProperty.getProperties() で得られたプロパティが使用される。

Parameters:
file - RandomAccessFile のインスタンス。
  • 既に close() されていない事。
  • コンストラクタの mode には "rw" オプションを使用して、 読みこみと書きこみが出来るように生成されたインスタンスであること。
の条件を満たすもの。
See Also:
LhaProperty.getProperties()

LhaImmediateOutputStream

public LhaImmediateOutputStream(java.io.RandomAccessFile file,
                                java.util.Properties property)
fileに 圧縮データを出力するOutputStreamを構築する。
各圧縮形式に対応した符号器の生成式等を持つプロパティには LhaProperty.getProperties() で得られたプロパティが使用される。

Parameters:
file - RandomAccessFile のインスタンス。
  • 既に close() されていない事。
  • コンストラクタの mode には "rw" オプションを使用して、 読みこみと書きこみが出来るように生成されたインスタンスであること。
の条件を満たすもの。
property - 各圧縮形式に対応した符号器の生成式等が含まれるプロパティ
See Also:
LhaProperty
Method Detail

write

public void write(int data)
           throws java.io.IOException
現在のエントリに1バイトのデータを書きこむ。

Specified by:
write in class java.io.OutputStream
Parameters:
data - 書きこむデータ
Throws:
java.io.IOException - 入出力エラーが発生した場合。

write

public void write(byte[] buffer)
           throws java.io.IOException
現在のエントリに bufferの内容を全て書き出す。

Overrides:
write in class java.io.OutputStream
Parameters:
buffer - 書き出すデータの入ったバイト配列
Throws:
java.io.IOException - 入出力エラーが発生した場合。

write

public void write(byte[] buffer,
                  int index,
                  int length)
           throws java.io.IOException
現在のエントリに bufferの indexから lengthバイトのデータを書き出す。

Overrides:
write in class java.io.OutputStream
Parameters:
buffer - 書き出すデータの入ったバイト配列
index - buffer内の書き出すべきデータの開始位置
length - データのバイト数
Throws:
java.io.IOException - 入出力エラーが発生した場合。

flush

public void flush()
           throws java.io.IOException
現在書き込み中のエントリのデータを強制的に出力先に書き出す。 これは PostLzssEncoder, LzssOutputStream の規約どおり flush() しなかった場合とは別のデータを出力する。 (大抵の場合は 単に圧縮率が低下するだけである。)

Specified by:
flush in interface java.io.Flushable
Overrides:
flush in class java.io.OutputStream
Throws:
java.io.IOException - 入出力エラーが発生した場合
See Also:
PostLzssEncoder.flush(), LzssOutputStream.flush()

close

public void close()
           throws java.io.IOException
出力先に全てのデータを出力し、ストリームを閉じる。
また、使用していた全てのリソースを解放する。

Specified by:
close in interface java.io.Closeable
Overrides:
close in class java.io.OutputStream
Throws:
java.io.IOException - 入出力エラーが発生した場合

putNextEntry

public void putNextEntry(LhaHeader header)
                  throws java.io.IOException
新しいエントリを書き込むようにストリームを設定する。
このメソッドは 既に圧縮済みのエントリの場合は putNextEntryAlreadyCompressed(), 未だに圧縮されていない場合は putNextEntryNotYetCompressed() を呼び出す。
圧縮されているかの判定は、 のどれか一つでも LhaHeader.UNKNOWN であれば未だに圧縮されていないとする。
header には正確な OriginalSize が指定されている必要がある。

Parameters:
header - 書きこむエントリについての情報を持つ LhaHeaderのインスタンス。
Throws:
java.io.IOException - 入出力エラーが発生した場合
java.lang.IllegalArgumentException - header.getOriginalSize() が LhaHeader.UNKNOWN を返す場合

putNextEntryAlreadyCompressed

public void putNextEntryAlreadyCompressed(LhaHeader header)
                                   throws java.io.IOException
既に圧縮済みのエントリを書きこむようにストリームを設定する。
圧縮済みデータが正しい事は、呼び出し側が保証する事。

Parameters:
header - 書きこむエントリについての情報を持つ LhaHeaderのインスタンス。
Throws:
java.io.IOException - 入出力エラーが発生した場合
java.lang.IllegalArgumentException -
  1. header.getOriginalSize() が LhaHeader.UNKNOWN を返す場合
  2. header.getComressedSize() が LhaHeader.UNKNOWN を返す場合
  3. header.getCRC() が LhaHeader.UNKNOWN を返す場合
の何れか。
java.lang.IllegalStateException - 以前のエントリが未だに closeEntry() されていない場合

putNextEntryNotYetCompressed

public void putNextEntryNotYetCompressed(LhaHeader header)
                                  throws java.io.IOException
未だに圧縮されていないエントリを書きこむようにストリームを 設定する。header に CompressedSize,CRCが指定されていても無 視される。このメソッドに渡される header には LhaHeader.setOriginalSize() を用いて 正確なオリジナルサイズ が指定されている必要がある。

Parameters:
header - 書きこむエントリについての情報を持つ LhaHeaderのインスタンス。
Throws:
java.io.IOException - 入出力エラーが発生した場合
java.lang.IllegalArgumentException - header.getOriginalSize() が LhaHeader.UNKNOWN を返した場合
java.lang.IllegalStateException - 以前のエントリが未だに closeEntry() されていない場合

closeEntry

public boolean closeEntry()
                   throws java.io.IOException
現在出力中のエントリを閉じ、次のエントリが出力可能な状態にする。
putNextEntryNotYetCompressed() で開いたエントリを閉じる場合 このメソッドは圧縮に失敗した(圧縮後サイズが圧縮前サイズを上回った)場合、 エントリ全体を書き込み先 の RandomAccessFile から削除する。
この削除処理は単に ファイルポインタを エントリ開始位置まで巻き戻すだけなので RandomAccessFile に setLength() が無い jdk1.1 以前では エントリを無圧縮(もしくは他の圧縮法)で再出力しない場合、 書庫データの終端以降に圧縮に失敗した不完全なデータが残ったままになる。

Returns:
エントリが出力された場合は true、 圧縮前よりも圧縮後の方がサイズが大きくなったため、 エントリが削除された場合は false。 また、現在処理中のエントリが無かった場合も true を返す。
Throws:
java.io.IOException - 入出力エラーが発生した場合

LHA Library for Java

When you found typographical errors or omissions, Please mail to cqw10305@nifty.com
The company name and product name which are used in this document, it is the trademark or registered trademark of each company generally.
Copyright © 2001-2002 Michel Ishizuka. All Rights Reserved.