user1493286
user1493286

Reputation: 49

zip the files which are present at one FTP location and copy to another FTP location directly

I want to create zip file of files which are present at one ftp location and Copy this zip file to other ftp location without saving locally.

I am able to handle this for small size of files.It works well for small size files 1 mb etc

But if file size is big like 100 MB, 200 MB , 300 MB then its giving error as,

java.io.FileNotFoundException: STOR myfile.zip : 550 The process cannot access the 
file because it is being used by another process. 
at sun.net.ftp.FtpClient.readReply(FtpClient.java:251)
at sun.net.ftp.FtpClient.issueCommand(FtpClient.java:208)
at sun.net.ftp.FtpClient.openDataConnection(FtpClient.java:398) 
at sun.net.ftp.FtpClient.put(FtpClient.java:609)

My code is

    URLConnection  urlConnection=null;
    ZipOutputStream zipOutputStream=null;
    InputStream inputStream = null;
    byte[] buf;
    int ByteRead,ByteWritten=0; 
    ***Destination where file will be zipped***
    URL url = new URL("ftp://" + ftpuser+ ":" + ftppass + "@"+ ftppass + "/" +
            fileNameToStore + ";type=i");
    urlConnection=url.openConnection();         
    OutputStream outputStream = urlConnection.getOutputStream();
    zipOutputStream = new ZipOutputStream(outputStream);
    buf = new byte[size];
    for (int i=0; i<li.size(); i++) 
    {
        try
        {
            ***Souce from where file will be read***
            URL u= new URL((String)li.get(i));  // this li has values http://xyz.com/folder
            /myPDF.pdf
            URLConnection uCon = u.openConnection();
            inputStream = uCon.getInputStream();
            zipOutputStream.putNextEntry(new ZipEntry((String)li.get(i).substring((int)li.get(i).lastIndexOf("/")+1).trim()));
            while ((ByteRead = inputStream .read(buf)) != -1)    
            {       
                zipOutputStream.write(buf, 0, ByteRead);
                ByteWritten += ByteRead;
            }
            zipOutputStream.closeEntry();
        }
        catch(Exception e)
        {
            e.printStackTrace();
        }
    }
    if (inputStream  != null) {
        try { 
            inputStream .close(); 
        } 
        catch (Exception e) { 
            e.printStackTrace();
        }
    }
    if (zipOutputStream != null) {
        try { 
            zipOutputStream.close(); 
        } catch (Exception e){
            e.printStackTrace(); 
        }     
    }

Can anybody let me know how I can avoid this error and handle large files

Upvotes: 4

Views: 1249

Answers (2)

Aaron Digulla
Aaron Digulla

Reputation: 328594

This is unrelated to file sizes; as the error says, you can't replace the file because some other process is currently locking it.

The reason why you see it more often with large files is because these take longer to transfer hence the chance of concurrent accesses is higher.

So the only solution is to make sure that no one uses the file when you try to transfer it. Good luck with that.

Possible other solutions:

  1. Don't use Windows on the server.
  2. Transfer the file under a temporary name and rename it when it's complete. That way, other processes won't see incomplete files. Always a good thing.
  3. Use rsync instead of inventing the wheel again.

Upvotes: 1

Zagrev
Zagrev

Reputation: 2020

Back in the day, before we had network security, there were FTP servers that allowed 3rd party transfers. You could use site specific commands and send a file to another FTP server directly. Those days are long gone. Sigh.

Ok, maybe not long gone. Some FTP servers support the proxy command. There is a discussion here: http://www.math.iitb.ac.in/resources/manuals/Unix_Unleashed/Vol_1/ch27.htm

Upvotes: 0

Related Questions