2016-08-22 13 views
2

base64を使用してエンコードされたコンテンツを取得するために必要なPDFファイルがたくさんあります。私はストリームとしてファイルを取得し、これらのファイルをエンコードする多くの労働者に配布し、各ファイルの文字列base64を返すAkkaアプリケーションを持っています。それは作品ストリーム用のJavaバッファードベース64エンコーダ

org.apache.commons.codec.binary.Base64InputStream; 
    ... 
    Base64InputStream b64IStream = null; 
    InputStreamReader reader = null; 
    BufferedReader br = null; 
    StringBuilder sb = new StringBuilder(); 
    try { 
     b64IStream = new Base64InputStream(input, true); 
     reader = new InputStreamReader(b64IStream); 
     br = new BufferedReader(reader); 
     String line; 
     while ((line = br.readLine()) != null) { 
      sb.append(line); 
     } 
    } finally { 
     if (b64IStream != null) { 
      b64IStream.close(); 
     } 
     if (reader != null) { 
      reader.close(); 
     } 
     if (br != null) { 
      br.close(); 
     } 
    } 

が、私は、バッファを使用してファイルをエンコードし、このためのより高速な代替がある場合はできる最善の方法だろうかを知りたいと思います:私は、エンコーディングのための基本的なソリューションを得ました。

私のようないくつかの他のアプローチテスト:

  • Base64.getEncoder
    • をsun.misc.BASE64Encoder
    • Base64.encodeBase64
    • javax.xml.bind.DatatypeConverter.printBase64
    • com.google.guava.BaseEncoding.base64

    高速ですが、ファイル全体が必要ですか?また、1つのPDFファイルをエンコードしている間、他のスレッドをブロックしたくありません。

    すべての入力は本当に役に立ちます。ありがとうございました!

    +0

    「バッファ付き」とはどういう意味ですか?入力とは何でしょうか。出力はどのようなものでしょうか?ストリーム?チャンネル?文字列? – RealSkeptic

    +0

    入力はInputStream、出力はbase64文字列の内容です。バッファはBufferedReaderになります。 –

    答えて

    3

    Base64についての楽しい事実:3バイトをとり、4文字に変換します。つまり、バイナリデータを3で割り切れるチャンクで読み取ると、チャンクを Base64エンコーダに送ることができ、ファイル全体をフィードしたのと同じ方法でエンコードします。

    private static final int BUFFER_SIZE = 3 * 1024; 
    
    try (BufferedInputStream in = new BufferedInputStream(input, BUFFER_SIZE);) { 
        Base64.Encoder encoder = Base64.getEncoder(); 
        StringBuilder result = new StringBuilder(); 
        byte[] chunk = new byte[BUFFER_SIZE]; 
        int len = 0; 
        while ((len = in.read(chunk)) == BUFFER_SIZE) { 
         result.append(encoder.encodeToString(chunk)); 
        } 
        if (len > 0) { 
         chunk = Arrays.copyOf(chunk,len); 
         result.append(encoder.encodeToString(chunk)); 
        } 
    } 
    

    これはことを意味します - 完全に合法である - そして、あなたがする必要があるすべてはの線に沿って何かであるあなたは、出力ストリームがちょうどBase64でデータの一つの長い行になりたい場合は今

    、最後のチャンクだけが3で割り切れない長さを有することがあり、したがってパディング文字を含むことになる。

    上記の例はJava 8 Base64を使用していますが、実際には任意の長さのバイト配列を取り、そのバイト配列のbase64文字列を返すエンコーダを使用できます。

    これは、あなたが望むようにバッファーサイズで遊ぶことができることを意味します。

    出力にMIME互換が必要な場合は、出力を行に分割する必要があります。この例では、上記の例のチャンクサイズを4/3倍すると、丸い数の行が得られるようにチャンクサイズを設定します。たとえば、1行に64文字を使用する場合、各行は64/4 * 3(48バイト)をエンコードします。 48バイトをエンコードすると、1行になります。 480バイトをエンコードすると、10行のフルラインが得られます。

    したがって、上記のBUFFER_SIZEを4800などに変更してください。Base64.getEncoder()の代わりにBase64.getMimeEncoder(64,new byte[] { 13, 10})を使用してください。そして、エンコードすると、最後のチャンクを除く各チャンクから100個のフルサイズのラインが得られます。 whileループにresult.append("\r\n")を追加する必要があります。

    +0

    ありがとう!私はjavaを使用しているのでエンコーダを切り替える必要がありました。この変更の前にエンコードするには900msかかっていましたが、現在は同じファイルに対して平均で103msかかります。 –

    関連する問題