【问题标题】:how to restart file uploading when an exception occurs发生异常时如何重新启动文件上传
【发布时间】:2015-08-05 06:10:53
【问题描述】:

我正在开发一个遇到问题的 java 应用程序。当我将文件发送到服务器并引发异常时,不会发送文件。如何重试发送文件?

       public void uploadtxtFile(String localFileFullName, String fileName, String hostDir)
                throws Exception {
            File file = new File(localFileFullName);
            if (!(file.isDirectory())) {
                if (file.exists()) {
                    FileInputStream input = null;
                   try {
                        input = new FileInputStream(new File(localFileFullName));
                        if (input != null) {
                            hostDir = hostDir.replaceAll("//", "/");
                           logger.info("uploading host dir : " + hostDir);
                     //new 

//                       TestThread testThread=new TestThread(hostDir,input);
//                      Thread t=new Thread(testThread);
//                  
//                      try{
//                          t.start();
//                          
//                      }catch(Exception ex){
//                          logger.error("UPLOADE start thread create exception new:" + ex);
//                      }
//                      // new end

                        DBConnection.getFTPConnection().enterLocalPassiveMode();
                        // the below line exeption is come
                      boolean bool = DBConnection.getFTPConnection().storeFile(hostDir, input);
                       //input.close();//new comment
                           if (bool) {
                               logger.info("Success uploading file on host dir :"+hostDir);
                          } else {
                                logger.error("file  not uploaded.");
                        }
                      } else {
                             logger.error("uploading file input null.");
                 }
                 }catch(CopyStreamException cs)
                    {   logger.error("Copy StreamExeption is come "+cs);
                    } catch(Exception ex)
                    {
                         logger.error("Error in connection ="+ex);//this is catch where I handle the exeption

                    }finally {
    //                  boolean disconnect= DBConnection.disConnect();
                        input.close();
                   }

                } else {
                     logger.info("uploading file is not exists.");
                }
            }
        }

这是代码,我想重新开始上传文件,但我不知道。我使用线程尝试过,但再次抛出异常。我也尝试使用while 循环,但它会无限循环,并且还会显示异常以及另一个异常。 下面是我使用的线程代码:

public void run() {

               System.out.println("Enter Thread TestThread");

               DBConnection.getFTPConnection().enterLocalPassiveMode();
                 //  System.out.println("Error in DBConnection ");
                  //here server timeout error is get


                  boolean bool1=false;

                   boolean bool=true;
                    try {
                    bool = DBConnection.getFTPConnection().storeFile(hostDir1, input1);
                    } catch (IOException e) {
                        // TODO Auto-generated catch block
                    e.printStackTrace();


                    }finally {
                        //disconnect();

                    try {
                    input1.close();
                        } catch (IOException e) {
                            // TODO Auto-generated catch block
                        e.printStackTrace();
                        }
                   }

                   if (bool) {
                       System.out.println("File is Uploded");
                    } else {

                    while(bool!=true){
                    try {
                         DBConnection.getFTPConnection().enterLocalPassiveMode();
                            bool1=DBConnection.getFTPConnection().storeFile(hostDir1, input1);

                        } catch (IOException e) {
                            // TODO Auto-generated catch block
                            e.printStackTrace();
                        }finally {
                            //disconnect();

                            try {
                            input1.close();
                        } catch (IOException e) {
                                // TODO Auto-generated catch block
                            e.printStackTrace();
                            }
                    }
                     System.out.println("file  not uploaded."+bool1);
                         bool=bool1;
                   }
            }
              }
    }
              }

任何人都可以解决如何将文件上传到服务器吗?

异常如下图:

  1. 软件导致连接中止:recv failed
  2. 软件导致连接中止:套接字写入错误
  3. org.apache.commons.net.io.CopyStreamException:复制时捕获 IOException。

【问题讨论】:

  • 你怎么知道这是一个可重试的问题?上传是否只是间歇性失败?
  • 抛出异常是有原因的。与其尽可能努力地忽略它们,不如专注于找出它们最初被抛出的原因。例如,如果您的防火墙正在拔掉该连接上的插头,您可以根据需要随时重试,它不会改变任何东西。还请阅读this question,并尝试使用 Wireshark 之类的工具检查您的连接,看看那里到底发生了什么。
  • 我不知道这是否是可重复的问题,但我尝试重试。我不知道如何使用 Wireshark 来检查连接,我的防火墙已经准备好关闭
  • 我不知道为什么会出现异常,因为它不是每次都出现,我不知道如何解决它出现在这一行 boolean bool = DBConnection.getFTPConnection().storeFile(hostDir, input);你有什么办法解决这个问题吗

标签: java multithreading exception-handling ftp-client


【解决方案1】:

在您调用需要重试的方法的类中添加如下静态类:

static class RetryOnExceptionStrategy {
public static final int DEFAULT_RETRIES = 3;
public static final long DEFAULT_WAIT_TIME_IN_MILLI = 2000;

private int numberOfRetries;
private int numberOfTriesLeft;
private long timeToWait;

public RetryOnExceptionStrategy() {
    this(DEFAULT_RETRIES, DEFAULT_WAIT_TIME_IN_MILLI);
}

public RetryOnExceptionStrategy(int numberOfRetries,
        long timeToWait) {
    this.numberOfRetries = numberOfRetries;
    numberOfTriesLeft = numberOfRetries;
    this.timeToWait = timeToWait;
}

/**
 * @return true if there are tries left
 */
public boolean shouldRetry() {
    return numberOfTriesLeft > 0;
}

public void errorOccured() throws Exception {
    numberOfTriesLeft--;
    if (!shouldRetry()) {
        throw new Exception("Retry Failed: Total " + numberOfRetries
                + " attempts made at interval " + getTimeToWait()
                + "ms");
    }
    waitUntilNextTry();
}

public long getTimeToWait() {
    return timeToWait;
}

private void waitUntilNextTry() {
    try {
        Thread.sleep(getTimeToWait());
    } catch (InterruptedException ignored) {
    }
}
}   

现在将您的方法调用如下包装在一个while循环中:

RetryOnExceptionStrategy errorStrategy=new RetryOnExceptionStrategy();
while(errorStrategy.shouldRetry()){
try{
 //Method Call
}
catch(Exception excep){
 errorStrategy.errorOccured();
}
}

基本上,您只是将方法调用包装在 while 循环中,这将 保持 returnig 为真,直到您的重试次数达到零(假设您从 3 开始)。

每次发生异常时,捕获异常并调用方法 这将减少您的 retryCount 并且方法调用会再次延迟执行。

【讨论】:

    【解决方案2】:

    使用此类应用程序的一般方法是:

    1. 创建一个类,比如UploadWorker,它将Callable 扩展为包装器。让包装器在失败时返回您需要的任何错误和详细信息。
    2. 为这个包装器创建一个ExecutorService(基本上是一个线程池)以在线程中运行。
    3. 提交您的UploadWorker 实例,然后您将获得Future。在未来致电get() 以阻塞方式等待或只是等待一段时间等待结果。
    4. 如果 get() 向您返回错误消息,请再次将您的工作线程提交到线程池。

    【讨论】:

      【解决方案3】:

      去掉 uploadtxtFile 中的 try/catch 内容,让它扔掉,然后使用 Failsafe 之类的东西来执行重试:

      RetryPolicy retryPolicy = new RetryPolicy()
        .retryOn(CopyStreamException.class)
        .withDelay(1, TimeUnit.SECONDS)
        .withMaxRetries(5);
      
      Failsafe.with(retryPolicy).run(() -> uploadtxtFile(.....));
      

      再简单不过了。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2023-03-24
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-10-20
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多