我下面列出了一个控制器类-它所做的就是(为了演示我的问题)生成一个数字,将其转换为字符串,将该字符串转换为字节,然后将这些字节写为对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();
}
}
}