Java JAR中InputStream的不同行为
我发现自己解决了软件中的一个奇怪错误:问题是,只有当我将应用程序打包到一个可运行的JAR中时,它才会出现 问题出在这段简单的代码中:我添加了loopCounter来计算循环的次数Java JAR中InputStream的不同行为,java,inputstream,Java,Inputstream,我发现自己解决了软件中的一个奇怪错误:问题是,只有当我将应用程序打包到一个可运行的JAR中时,它才会出现 问题出在这段简单的代码中:我添加了loopCounter来计算循环的次数 private static byte[] read(InputStream source) { ByteArrayOutputStream out = new ByteArrayOutputStream(); int loopCounter = 0; int bytesRead; t
private static byte[] read(InputStream source) {
ByteArrayOutputStream out = new ByteArrayOutputStream();
int loopCounter = 0;
int bytesRead;
try {
byte[] buffer = new byte[4096];
while ((bytesRead = source.read(buffer)) != -1) {
out.write(buffer, 0, bytesRead);
loopCounter++;
}
} catch (IOException e) {
e.printStackTrace();
}
return out.toByteArray();
}
例如:
source = ClassLoader.class.getResourceAsStream("file.lol");
loopCounter in Eclipse = 1366
loopCounter in JAR = 1405
我的问题是:为什么相同的输入流会有如此显著的差异
编辑:我用正确的代码更改了代码,但循环计数器仍然不同。InputStream.read()
不能保证一次填满整个缓冲区,因此您需要跟踪实际读取的字节数:
byte[] buffer = new byte[4096];
int bytesRead = 0;
while ((bytesRead = source.read(buffer)) != -1) {
out.write(buffer, 0, bytesRead);
loopCounter++;
}
因此,对于InputStream
的不同实现,每次迭代读取的字节数可能会有所不同,这并不奇怪,因此迭代次数也可能有所不同
实际上,InputStream.read()
的特定调用读取的字节数取决于许多因素
第一个因素是InputStream
的实现:从Eclipse运行应用程序时,使用直接从文件系统读取资源的InputStream
,而从jar文件运行应用程序时,使用从jar文件提取资源的InputStream
。显然,jar文件解压算法的某些内部结构可能会影响您得到的块的大小
另一个因素是底层环境的行为。例如,从文件系统读取文件的系统调用也可能返回不同大小的块,这取决于操作系统的某些内部行为,依此类推。在这两种情况下,该方法是否返回相同的内容?如果使用DataInputStream包装InputStream并尝试使用readFully方法,您可能会得到相同的loopCounter。@SoboLAN我已经修复了代码,现在该方法返回相同的数组,但计数器仍然不同谢谢!我已经和类似的问题斗争了两天了,这就是问题所在。我希望它一次读取整个数组。这个解决方案使该方法在Eclipse和Jar中返回相同的数组,虽然这是正确的,但loopCounter仍然是正确的different@integeruser字体没关系。特定调用
read()
读取的字节数取决于许多因素,因此循环计数器的值不必相等。我知道了,但我的问题是:这些因素是什么?:)对不起,英语不是我的母语