2

InputStream を RESTful サービスに投稿しようとしています。通常のファイルの場合、これで問題ありません。

別の場所では、多数のファイルをその場でパイプされた zip ストリームに書き込もうとしています。これを行うには、拡張するクラスがInputStreamあり、呼び出されたときread()に次のファイルをパイプに書き込みます。最初のファイルが書き込まれたときに呼び出しますZipOutputStream.closeEntry()が、ハングします。どうして??

このクラスを単体テストでテストすると、正常に動作します。このオブジェクトを投稿しようとすると、ハングします。デバッガーは、ロックオンを待っていると言っていますSocketWrapper

メディアタイプを に設定しようとしたことにも注意してくださいapplication/octet-stream。また、RESTful メソッドが呼び出されることはありません。

ストリームクラス...

static class MultiStreamZipInputStream extends InputStream {

    private final Iterator<InputStream> streams;
    private final byte[] buffer = new byte[4096];
    private InputStream inputStream;
    private ZipOutputStream zipOutputStream;
    private InputStream currentStream;
    private int counter = 0;

    public MultiStreamZipInputStream(List<InputStream> streamList) {

        streams = streamList.iterator();
        currentStream = streams.next();

        try {
            PipedOutputStream out = new PipedOutputStream();
            inputStream = new PipedInputStream(out);

            zipOutputStream = new ZipOutputStream(out);
            ZipEntry entry = new ZipEntry(String.valueOf(counter++)); // Use counter for random name
            zipOutputStream.putNextEntry(entry);

        } catch (IOException ex) {
            ex.printStackTrace();
        }
    }

    @Override
    public int read()
        throws IOException {

        if (inputStream.available() != 0)
            return inputStream.read();

        if (currentStream == null)
            return -1;

        int bytesRead = currentStream.read(buffer);
        if (bytesRead >= 0) {

            zipOutputStream.write(buffer,  0,  bytesRead);
            zipOutputStream.flush();

        } else  {

            currentStream.close();
            zipOutputStream.closeEntry();

            if (!streams.hasNext()) {
                currentStream = null;
                return -1;
            }

            currentStream = streams.next();
            zipOutputStream.putNextEntry(new ZipEntry(String.valueOf(counter++)));
        }

        return read();
    }
}

投稿コードは...

        MultiStreamZipInputStream myStream = ...

        Client client = Client.create();
        Builder webResource = client.resource("some URL").type("application/x-zip-compressed");
        webResource.post(ClientResponse.class, myStream);

もう一方の REST メソッドは...

@POST
@Path("/somemethod")
@Produces(MediaType.APPLICATION_JSON)
@Consumes({"application/x-zip-compressed"})
public Response someMethod(InputStream data) {...
4

0 に答える 0