Чтение менее 8 Кб из HTTP InputStream - PullRequest
0 голосов
/ 12 июня 2019

У меня есть класс контроллера, перечисленный ниже - все, что он делает - это (для демонстрации моей проблемы) генерирует число, преобразует его в строку, преобразует строку в байты и записывает байты в ответ на вызов API.

API выставляется через HTTP.

Когда я пытаюсь прочитать сообщения из API - он блокирует ожидание записи 8k в поток.Есть ли способ читать менее 8 Кбайт за раз?

Блок операции чтения здесь, в java.net.SocketInputStream # socketRead0, потому что java.net.SocketInputStream # socketRead запрашивает 8 Кбайт.

@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();
    }

  }
}
...