通过FTP下载XML文件 - java

我有一个数据库中的提要列表,可用来从FTP服务器下载XML文件,然后解析它。 scrpt被捆绑到一个jar文件中,该文件每天使用Windows Task Scheduler运行。有时,请求在获取某个xml文件时会感到不适。到目前为止,它已经在2周内发生了3次,没有我能看到的真实模式。

当它搞砸了时,我转到正在运行它的计算机上,我看到命令窗口已打开,并且在xml被完全下载之前已停止。如果我关闭命令窗口并手动运行任务,一切将正常运行。

我用来下载xml文件的代码是:

private void loadFTPFile(String host, String username, String password, String filename, String localFilename){
        System.out.println(localFilename);
        FTPClient client = new FTPClient();
        FileOutputStream fos = null;

        try {
            client.connect(host);
            client.login(username, password);
            String localFilenameOutput = createFile(assetsPath + localFilename);
            fos = new FileOutputStream(localFilenameOutput);
            client.retrieveFile(filename, fos);

        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (fos != null) 
                    fos.close();
                client.disconnect();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

该函数正在循环中调用,当它失败时,所有操作都将停止,并且脚本不会进入下一个提要。

我不确定发生了什么,可能是连接丢失了,但是我认为如果发生这种情况,try / catch将会捕获。我不确定超时是否可以解决问题或是否需要使用线程(但是我从未使用过线程)

任何人都可以向我指出发生这种情况的原因以及解决该问题的正确方法的正确方向

参考方案

更新-设置数据连接超时

由于仅下载了最后一个文件,并给出了 FTPClient.retrieveFile() 的来源,所以我认为这可能是服务器端的问题(使文件挂起或死掉的人-知道)。显然,人们无法修复服务器,甚至不知道那里发生了什么,无论如何,我建议添加 setDataTimeout(int) 超时并捕获可能的SocketTimeoutException单独记录在另一个位置,然后发送给FTP服务器管理员(以及时间信息),以便他们可以合并日志并查看问题所在。

旧答案

我没有注意到您为每个文件都进行了连接和登录,因此下面的优化只是不关闭控件连接并成功注销,而是而不是来解决问题。

您可以在调试模式下启动JVM,并在挂起调试器时附加一个调试器,无论如何,根据this answer和this thread,这可能是网络设备设备(路由器)上的超时问题。从FTPClient Javadoc

在文件传输期间,数据连接正忙,但控制
连接空闲。 FTP服务器知道控制连接在
使用,因此不会因为缺乏活动而关闭它,但是要困难得多
让网络路由器知道控制和数据连接是
彼此关联。有些路由器可能会控制
连接处于空闲状态,如果通过数据传输,则断开连接
连接花费的时间比路由器允许的空闲时间长。

一种解决方案是通过控制连接发送安全命令(即NOOP)以重置路由器的空闲计时器。启用如下:

ftpClient.setControlKeepAliveTimeout(300); // set timeout to 5 minutes

Java:正则表达式模式匹配器是否有大小限制? - java

我的模式类似于OR:“word1 | word2 | word3”我大约有800个字。可能有问题吗? 参考方案 您仅受记忆和理智的限制。 :)

Java:线程池如何将线程映射到可运行对象 - java

试图绕过Java并发问题,并且很难理解线程池,线程以及它们正在执行的可运行“任务”之间的关系。如果我创建一个有10个线程的线程池,那么我是否必须将相同的任务传递给池中的每个线程,或者池化的线程实际上只是与任务无关的“工人无人机”可用于执行任何任务?无论哪种方式,Executor / ExecutorService如何将正确的任务分配给正确的线程? 参考方案 …

JAVA:字节码和二进制有什么区别? - java

java字节代码(已编译的语言,也称为目标代码)与机器代码(当前计算机的本机代码)之间有什么区别?我读过一些书,他们将字节码称为二进制指令,但我不知道为什么。 参考方案 字节码是独立于平台的,在Windows中运行的编译器编译的字节码仍将在linux / unix / mac中运行。机器代码是特定于平台的,如果在Windows x86中编译,则它将仅在Win…

java:继承 - java

有哪些替代继承的方法? java大神给出的解决方案 有效的Java:偏重于继承而不是继承。 (这实际上也来自“四人帮”)。他提出的理由是,如果扩展类未明确设计为继承,则继承会引起很多不正常的副作用。例如,对super.someMethod()的任何调用都可以引导您通过未知代码的意外路径。取而代之的是,持有对本来应该扩展的类的引用,然后委托给它。这是与Eric…

Java:BigInteger,如何通过OutputStream编写它 - java

我想将BigInteger写入文件。做这个的最好方式是什么。当然,我想从输入流中读取(使用程序,而不是人工)。我必须使用ObjectOutputStream还是有更好的方法?目的是使用尽可能少的字节。谢谢马丁 参考方案 Java序列化(ObjectOutputStream / ObjectInputStream)是将对象序列化为八位字节序列的一种通用方法。但…