Java 找出流中有多少字节的更好方法?
目前,我依靠Java 找出流中有多少字节的更好方法?,java,apache,stream,streaming,Java,Apache,Stream,Streaming,目前,我依靠ObjectInputStream.available()方法来告诉我流中还剩下多少字节。原因是——我正在对某些处理流的函数编写一些单元/集成测试,我只是试图确保available()方法在完成后返回0 不幸的是,在测试失败时(即,我已经在流中发送了大约8个字节),我对available()==0的断言在应该为false时变为true。它应该显示>0或8个字节 我知道available() 是否有更可靠的方法来检查流是否为空(这毕竟是我的主要目标)?可能在Apache IO域或其他库
ObjectInputStream.available()
方法来告诉我流中还剩下多少字节。原因是——我正在对某些处理流的函数编写一些单元/集成测试,我只是试图确保available()
方法在完成后返回0
不幸的是,在测试失败时(即,我已经在流中发送了大约8个字节),我对available()==0
的断言在应该为false时变为true。它应该显示>0或8个字节
我知道available()
是否有更可靠的方法来检查流是否为空(这毕竟是我的主要目标)?可能在Apache IO域或其他库中
有人知道为什么available()
方法如此不可靠吗;这有什么意义?或者,是否有一种特定的、适当的使用方法
更新:
所以,正如你们中的许多人可以从评论中看到的,我面临的主要问题是,在流的一端,我发送了一定数量的字节,但在另一端,并不是所有的字节都到达了
具体地说,我在一端发送205498字节,在另一端只发送204988字节,这是一致的。我在套接字中的线程之间控制此操作的两侧,但这应该无关紧要
下面是我为收集所有字节而编写的代码
public static int copyStream(InputStream readFrom, OutputStream writeTo, int bytesToRead)
throws IOException {
int bytesReadTotal = 0, bytesRead = 0, countTries = 0, available = 0, bufferSize = 1024 * 4;
byte[] buffer = new byte[bufferSize];
while (bytesReadTotal < bytesToRead) {
if (bytesToRead - bytesReadTotal < bufferSize)
buffer = new byte[bytesToRead - bytesReadTotal];
if (0 < (available = readFrom.available())) {
bytesReadTotal += (bytesRead = readFrom.read(buffer));
writeTo.write(buffer, 0, bytesRead);
countTries = 0;
} else if (countTries < 1000)
try {
countTries++;
Thread.sleep(1L);
} catch (InterruptedException ignore) {}
else
break;
}
return bytesReadTotal;
}
public静态int-copyStream(InputStream readFrom,OutputStream writeTo,int-bytesToRead)
抛出IOException{
int bytesreadtottal=0,bytesRead=0,counttrys=0,available=0,bufferSize=1024*4;
字节[]缓冲区=新字节[bufferSize];
while(bytereadtotal
我把counttrytries变量放在那里就是为了看看会发生什么。即使没有轮胎,它也会在到达BytesToRead之前永远阻塞
什么会导致流突然无限期地阻塞呢?我知道在另一端,它会完全发送字节(因为它实际上使用了相同的方法,我看到它最终用完整的BytesToRead匹配ByteReadTotal来完成函数。但是接收器没有。事实上,当我看阵列时,它们也完美匹配到最后
更新2
我注意到,当我在copyStream方法的末尾添加一个writeTo.flush()
时,它似乎又起作用了。嗯……为什么flush在这种情况下如此重要。也就是说,为什么不使用它会导致流永久阻塞?available()(可能是0)。为了查看流中是否还有剩余字节,您必须read()
或read(byte[])
,这将返回读取的字节数。如果返回值为-1
,则您已到达文件末尾
这个小代码段将在InputStream中循环,直到它结束(read()返回-1)。我认为它永远不会返回0,因为它应该阻塞,直到它可以读取1个字节或发现没有任何内容可读取为止(因此返回-1)
如果不读取,您如何知道流中有x
字节?available()
方法清楚地说明返回可以在不阻塞的情况下读取的字节数。如果要读取更多字节,则需要阻塞。您应该使用InputStream\read()检查
返回-1
以查看是否已到达流的结尾。@SotiriosDelimanolis,不应可用()
至少给出一个返回值1,以表明阻塞时至少有1个字节要读取?如果它可以在不阻塞的情况下读取1个字节,它会这样说。它不知道在未读取字节的情况下阻塞时可以读取多少字节(即到达流的末尾).我明白了…这很有趣。在我希望流中什么都不剩的情况下,我实际上在读取一个字节0x79,然后,.read()
方法无限期地阻塞…这些症状会提醒您什么吗?目前我使用的是这样的东西:int b;while((b=singleServersT.getInputStream()).read())!=-1{System.err.print(b);}但是它实际上是在第一个字节读取后阻塞的!我在我的原始帖子中添加了关于这一新光的注释。是的,你的代码也是这样做的。TotalBytesRead==1在第一个循环之后,它阻塞了。它应该是阻塞的,你不能在不阻塞的情况下知道整个流中还剩下多少字节。嗯,你怎么能强制发送EOF?F或者测试您可以模拟InputStream,或者返回一个像new ByteArrayInputStream(myBytes)一样包装字节[]的实例;该实例将在读取数组中的所有字节后发送EOF。另外,由于数组都在内存中,因此不会阻塞任何一个,因此可用()将返回数组的长度
int currentBytesRead=0;
int totalBytesRead=0;
byte[] buf = new byte[1024];
while((currentBytesRead =in.read(buf))>0){
totalBytesRead+=currentBytesRead;
}