我有以下代码来下载通过TCP传输的文件:
try (OutputStream out = new FileOutputStream(path); InputStream is = socket.getInputStream();) {
byte[] bytes = new byte[1024];
int count, xp = 0;
while ((count = is.read(bytes)) > 0) { // TODO after upload the service doesn't leave while loop
out.write(bytes, 0, count);
}
System.out.println("hello");
...
if (ready.equalsIgnoreCase(CdnResponse.READY.getContext())){
int read = 0;
byte[] bytes = new byte[1024];
while ((read = inputStream.read(bytes)) != -1) {
out.write(bytes, 0, read);
}
}
一旦所有的字节都被处理了(它们总是被处理的,它像正常的一样工作,只是不退出循环),文件就被创建了,没有一个问题,但是,循环没有退出。
TCP/IP连接被设计为长期流式连接(构建在无序、无保证、基于数据包的IP协议之上)。
这意味着is.read(bytes)
完全按照规范的要求执行:它将等待至少一个字节可用,或者“流结束”信号进入。只要这两种情况都不发生(没有字节到达,但流没有关闭),它就会自动阻塞。如果有必要的话永远。
解决方法是[A]预先发送文件的大小,然后调整循环,使其只在收到该数量的字节后退出,或者[B]关闭流。
// upload side
void upload() {
Path p = Paths.get("/path/to/file/you/want/to/send");
long fileSize = Files.size(p);
out.write(longToBytes(fileSize);
try (InputStream in = Files.newInputStream(p)) {
in.transferTo(out);
}
}
public static byte[] longToBytes(long x) {
ByteBuffer buffer = ByteBuffer.allocate(Long.BYTES);
buffer.putLong(x);
return buffer.array();
}
此代码具有以下属性:
java.nio.file
API。TransferTo
方法,这避免了必须声明一个字节数组作为缓冲区的rigamarole和一个while循环。然后在下载端:
void download() {
long size = bytesToLong(in.readNBytes(8));
Path p = Paths.get("/file/to/store/data/at");
// Generally network transfer sizes are a bit higher than 1k;
// up to 64k in fact. Best to declare a larger buffer!
byte[] bb = new byte[65536];
try (OutputStream out = Files.newOutputStream(p)) {
while (size > 0) {
int count = in.read(bb);
if (count == -1) throw new IOException("Unexpected end of stream");
out.write(bb, 0, count);
size -= count;
}
}
}
public static long bytesToLong(byte[] bytes) {
ByteBuffer buffer = ByteBuffer.allocate(Long.BYTES);
buffer.put(bytes);
buffer.flip();//need flip
return buffer.getLong();
}
0
2个字节),这表示文件已完成。如果您需要的话,我将把它作为一个练习,让您来实现上行和下载端。
问题内容: 在下面的代码中,我希望循环在+ + =时立即退出。但是,使用语句进行测试表明它一直持续到循环完成为止。我尝试过,然后在语句集中进行设置,但这会导致无限循环。我认为使用然后设置可能有效,但也可以一直运行到循环结束为止。什么是最优雅,最快的退出方式?谢谢。 问题答案: 该循环将只匹配条件时,当控制返回到它,即循环完全执行。因此,这就是即使满足条件也不会立即退出程序的原因。 但是,如果条件没
出现的问题是,当用户确实输入了一个正数时,它仍然忽略输入,并要求用户再次输入一个正整数。我想我只是没有正确退出循环,但我不确定是如何退出的。
//在下面的程序中,在内部,当用户收到指令时,他可以简单地进入哨兵退出while循环,但是,当您得到希望购买的票的结果时,按999并不退出程序
问题内容: 在Java中退出/终止while循环的最佳方法是什么? 例如,我的代码当前如下: 问题答案: 用途: 但是,如果您的代码看起来 完全 像您指定的那样,则可以使用普通循环并将条件更改为:
所以我这里有一个程序,它只是简单地模仿跳棋(但不是跳,而是一个棋子简单地“吃掉”另一个棋子)。我有一个简单的类,它实现了一个“checkers”类对象,并创建了一个名为“chips”的int数组变量。还有一个“while”语句,它在chip[0]和chips[1]整数大于0时创建了一个循环。看起来是这样的: Checkers类中的count方法如下所示: 板是8 x 8(这就是board.leng
问题内容: 我正在尝试通过按键盘上的键来使while循环中断。我的代码是: 问题答案: 请勿使用循环获取输入,或。您真正想要的是一行输入,然后将其拆分为一个双打列表。因此,请使用,拆分并解析每个项目。像这样: 这忽略了任何形式的输入验证,但显示了一种通用方法。 这将起作用,因为一旦您单击“ enter”(输入),它将结束第一行,这意味着扫描程序可以越过进入代码的大部分。由于您再也不会尝试阅读任何内