就像tile说的那样,我的Java应用程序无法工作,因为它在Eclipse上开发时工作正常。
我完成了在Eclipse上构建和测试我的应用程序。它按照我的预期正常工作。我需要将其部署为可运行的jar,以便我的客户端无法在其系统上使用它。我通过在Eclipse上导出它使它成为一个可运行的jar。 当我运行可运行的jar时,应用程序开始正常工作一段时间并停止文件读取。我对Eclipse上的相同代码没有任何问题。
似乎无效的源代码段如下。
sfis = new SmbFileInputStream(sFile);
in = new BufferedInputStream(sfis);
byte buf[] = new byte[(int)sFile.length()];
int pos = 0;
int size = 10;
int temp;
while((size=in.read(buf, pos, size)) > 0){
pos += size;
temp = buf.length - pos;
if(temp < 10){
size = temp;
}
}
在Eclipse上它不会导致任何问题。它完美地从SMB连接读取数据并完成其工作。但是从jar应用程序中,似乎在某些时候停止从输入流内部读取循环。 这是一个我从未经历过的非常奇怪的案例。我找不到任何解决办法。
这是因为我的代码还是可能由Eclipse错误制作的jar文件?
----------其他信息-------------------
在Edmondo1984的大力帮助下,我找到了jar程序停止的位置。 当它从SmbFile转到inputstream时,会创建一个新线程jcifs.util.transport.Transport,并且只是阻塞该线程,并且应用程序会创建另一个jcifs.util.transport.Transport,依此类推。在创建8或9个jcifs.util.transport.Transport线程后,它被卡住并且什么都不做。
相同的代码,相同的jcifs库。但在Eclipse和本地机器上运行作为可运行的jar之间的工作方式不同。 我不知道为什么会这样。
答案 0 :(得分:2)
“流上没有其他内容”的返回值为-1
(请参阅Javadoc)。
想象一下,如果你尝试in.read(buf, pos, size)
会发生什么,但底层仍然无法使用。然后调用立即返回,返回值为0
(零)。这样,循环条件的计算结果为false,并退出循环。所以我认为你应该与!= -1
进行比较。
另一个可能的问题:您还可以考虑size = 0
(例如由于上述情况)和temp >= 10
会发生什么。因为您直接将size
的值反馈为in.read(buf, pos, size)
作为要读取的最大字节数,所以假设您已将比较更正为!= -1
,则最终可能会进入无限循环
答案 1 :(得分:1)
当介入流时,这种行为很常见。小算法不正确可能会在不同的环境中引起不同的症状。
您可以将“调试”信息打印到控制台,以便更好地了解代码停止的位置和原因。我很确定它的读取方法。
您的代码有几个问题,最臭名昭着的是阻止:
temp = buf.length - pos;
if(temp < 10){
size = temp;
}
为什么呢?当剩下10个或更少的字节时,你会尝试在下一个read()中读取它们,否则你可能会尝试读取太多(再次调整整个文件大小)。在Eclipse中运行,文件可能正在第一次读取()中读取,而Eclipse中显然没有读取。 尝试将代码更改为以下内容:
FileInputStream sfis = new FileInputStream(sFile);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte buf[] = new byte[4096];
int read = sfis.read(buf);
while(read>0){
baos.write(buf, 0, read);
read = sfis.read(buf);
}
sfis.close();
还要考虑使用Apache's Java IO utilities代码,而不是总是编写这种类型的代码。 Java中的IO需要很多样板,一个优秀的程序员有更好的事情要做。
侧面说明:将文件读入内存通常是一个坏主意。除非你要以某种方式整体转换其数据,否则流式传输总是更好。我不知道您的程序是什么,但请记住:如果您尝试读取10GB文件会发生什么?还是几个?
快乐编码,
答案 2 :(得分:0)
Java是大写字母敏感的。例如,如果您有名为image.PNG的文件,并且在您的代码中将位置设置为“/image.png”(而不是“/image.PNG”)它将在eclipse中正常工作,但在导出runnable jar文件之后java VM将无法找到该文件。