1

現在、AzureBlobStorage を使用して Lucene を操作しようとしています。そのため、新しいディレクトリを作成し、遅延が多すぎるのを避けるために、RAMDirectory をキャッシュとして使用します (これは最適な解決策ではないかもしれませんが、簡単に実行できるように思えました。提案は受け付けています)。.nrmとにかく、ファイルをブロブにアップロードするときに常に EOFExceptions を発生させるファイルをクラウドに書き込む場合を除いて、すべてがうまく機能しているようです。

ディレクトリがどのように機能するかを簡単に説明すると、理解に役立ちます。BlobOutputStreamかなりカプセル化された新しい IndexOutput を作成しましたRAMOutputStreamが、閉じると、すべてが azureBlobStorage にアップロードされます。これがどのように行われるかは次のとおりです。

String fname = name;
output.flush();
long length = output.length();
output.close();
System.out.println("Size of the upload: " + length);
InputStream bStream = directory.openCachedInputAsStream(fname);
System.out.println("Uploading cache version of: " + fname);
blob.upload(bStream, length);
System.out.println("PUT finished for: " + fname);

blobは でCloubBlockBlobありoutputRAMOutputStreamです。で新しいをdirectory.openCacheInputAsStream開きます。InputStreamIndexInput

そのため、アップロード時に.nrm常に発生するファイルを除いて、ほとんどの場合すべてが機能します。EOFExceptionインデックスにドキュメントが 1 つしかなく、「NRM-1 とそのドキュメントの標準」が含まれている場合、長さは 5 バイトであることを確認しましたが。

アップロード呼び出しでストリームのサイズを指定したときに、Azure がファイルに存在する以上のサイズをアップロードしようとする理由がよくわかりません。

説明するのが非常に難しいため、明確でない場合は申し訳ありません。さらにコードが必要な場合は教えてください。github などですべてにアクセスできるようにします。

回答ありがとうございます

編集

だから多分私のコードはinputStream問題を示すかもしれません:

public class StreamInput extends InputStream {
public IndexInput input;

public StreamInput(IndexInput openInput) {
    input = openInput;
}

@Override
public int read() throws IOException {
    System.out.println("Attempt to read byte: "+ input.getFilePointer());
    int b = input.readByte();
    System.out.println(b);
    return b;
}
}

そして、ここに私が得る痕跡があります:


Size of the upload: 5
Uploading cache version of: _0.nrm
Attempt to read byte: 0
78
Attempt to read byte: 1
82
Attempt to read byte: 2
77
Attempt to read byte: 3
-1
Attempt to read byte: 4
114
Attempt to read byte: 5
Attempt to read byte: 1029
java.io.EOFException: read past EOF: RAMInputStream(name=_0.nrm)
    at org.apache.lucene.store.RAMInputStream.switchCurrentBuffer(RAMInputStream.java:100)
    at org.apache.lucene.store.RAMInputStream.readByte(RAMInputStream.java:73)
    at org.lahab.clucene.core.StreamInput.read(StreamInput.java:18)
    at java.io.InputStream.read(InputStream.java:151)
    at com.microsoft.windowsazure.services.core.storage.utils.Utility.writeToOutputStream(Utility.java:1024)
    at com.microsoft.windowsazure.services.blob.client.BlobOutputStream.write(BlobOutputStream.java:560)
    at com.microsoft.windowsazure.services.blob.client.CloudBlockBlob.upload(CloudBlockBlob.java:455)
    at com.microsoft.windowsazure.services.blob.client.CloudBlockBlob.upload(CloudBlockBlob.java:374)
    at org.lahab.clucene.core.BlobOutputStream.close(BlobOutputStream.java:92)
    at org.apache.lucene.util.IOUtils.close(IOUtils.java:141)
    at org.apache.lucene.index.NormsWriter.flush(NormsWriter.java:172)
    at org.apache.lucene.index.DocInverter.flush(DocInverter.java:71)
    at org.apache.lucene.index.DocFieldProcessor.flush(DocFieldProcessor.java:60)
    at org.apache.lucene.index.DocumentsWriter.flush(DocumentsWriter.java:581)
    at org.apache.lucene.index.IndexWriter.doFlush(IndexWriter.java:3587)
    at org.apache.lucene.index.IndexWriter.prepareCommit(IndexWriter.java:3376)
    at org.apache.lucene.index.IndexWriter.commitInternal(IndexWriter.java:3485)
    at org.apache.lucene.index.IndexWriter.commit(IndexWriter.java:3467)
    at org.apache.lucene.index.IndexWriter.commit(IndexWriter.java:3451)
    at org.lahab.clucene.server.IndexerNode.addDocuments(IndexerNode.java:139)

アップロードが行き過ぎているようです...

4

1 に答える 1

0

したがって、問題は私のinputStreamであり、ドキュメントを読み取ってバイトをキャストできないという事実でもありました;)。私の読み取り関数は次のようになります。

System.out.println("file:" + input.getFilePointer() + "/" + input.length());
if (input.getFilePointer() >= input.length()) {
    return -1;
}
System.out.println("Attempt to read byte: "+ input.getFilePointer());
int b = (int) input.readByte() & 0xff;
System.out.println(b);
return b;

javadocはinputStream.read()について次のように述べています。

入力ストリームからデータの次のバイトを読み取ります。値byteは、0〜255の範囲のintとして返されます。ストリームの終わりに達したために使用可能なバイトがない場合は、値-1が返されます。このメソッドは、入力データが使用可能になるか、ストリームの終了が検出されるか、例外がスローされるまでブロックします。

そして& 0xff、符号ビットをマスクすることです

于 2012-10-18T17:51:09.250 に答える