从HTTP InputStream读取少于8k字节

时间:2019-06-12 15:19:01

标签: java http inputstream

我下面列出了一个控制器类-它所做的就是(为了演示我的问题)生成一个数字,将其转换为字符串,将该字符串转换为字节,然后将这些字节写为对API调用的响应

Api通过HTTP公开。

当我尝试从API读取消息时-它阻止等待8k写入流。有没有办法一次读取少于8k的字节?

这里的java.net.SocketInputStream#socketRead0中的读取操作块是因为java.net.SocketInputStream#socketRead请求8k字节。

@Controller
@RequestMapping("/myapi/**")
public class MyApi {
private static Logger logger  = LoggerFactory.getLogger(ApiController.class);

    private Queue<Byte[]> out = new ArrayBlockingQueue<>(1000);
    private AtomicLong nextId = new AtomicLong();

    public MyApi() {
        new ScheduledThreadPoolExecutor(1).scheduleAtFixedRate(() -> {
            final long next = nextId.incrementAndGet();
            out.add(toObjectArray(Long.toString(next).getBytes()));
        }, 0, 1, TimeUnit.SECONDS);
    }

    @RequestMapping(path = "/download", method = RequestMethod.GET)
    public StreamingResponseBody download() {

        return outputStream -> {

            while (true) {
                if (out.isEmpty()) {
                    outputStream.write(1);
                    outputStream.write(new byte[]{0});
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        logger.error("Unexpected Error", e);
                    }
                } else {
                    final Byte[] msg = out.poll();
                    outputStream.write(msg.length);
                    outputStream.write(toPrimitiveArray(msg));
                }
            }
        };
    }

    private byte[] toPrimitiveArray(Byte[] bytes) {
        byte[] primitive = new byte[bytes.length];

        for (int i = 0; i < bytes.length; i++) {
            primitive[i] = bytes[i];
        }
        return primitive;
    }

    private Byte[] toObjectArray(byte[] bytes) {
        Byte[] primitive = new Byte[bytes.length];

        for (int i = 0; i < bytes.length; i++) {
            primitive[i] = bytes[i];
        }
        return primitive;
    }
}

public class Main {

  public static void main(String[] args) throws Exception {
    URL url = new URL("http://localhost:8080/myapi/download");
    InputStream stream = url.openStream();

    int length = stream.read();

    while (length != -1) {
        byte[] bytes = new byte[length];

        for (int i = 0; i < length; i++) {
            bytes[i] = (byte)stream.read();
        }
        System.out.println(Long.valueOf(new String(bytes)));
        length = stream.read();
    }

  }
}

0 个答案:

没有答案