FTP apache commons progress bar in java - java

I'm working on a little program, which can upload a file to my FTP Server and do some other stuff with it.
Now... It all works, i'm using the org.apache.commons.net.ftp FTPClient class for uploading.
ftp = new FTPClient();
ftp.connect(hostname);
ftp.login(username, password);
ftp.setFileType(FTP.BINARY_FILE_TYPE);
ftp.changeWorkingDirectory("/shares/public");
int reply = ftp.getReplyCode();
if (FTPReply.isPositiveCompletion(reply)) {
addLog("Uploading...");
} else {
addLog("Failed connection to the server!");
}
File f1 = new File(location);
in = new FileInputStream(
ftp.storeFile(jTextField1.getText(), in);
addLog("Done");
ftp.logout();
ftp.disconnect();
The file which should uploaded, is named in hTextField1.
Now... How do i add a progress bar? I mean, there is no stream in ftp.storeFile... How do i handle this?
Thanks for any help! :)
Greetings

You can do it using the CopyStreamListener, that according to Apache commons docs is the listener to be used when performing store/retrieve operations.
CopyStreamAdapter streamListener = new CopyStreamAdapter() {
#Override
public void bytesTransferred(long totalBytesTransferred, int bytesTransferred, long streamSize) {
//this method will be called everytime some bytes are transferred
int percent = (int)(totalBytesTransferred*100/yourFile.length());
// update your progress bar with this percentage
}
});
ftp.setCopyStreamListener(streamListener);
Hope this helps

Related

FTPS storeFile return always false Java

im trying to send files to FTPS server
connection method: FTPS, ACTIVE, EXPLICIT
setFileType(FTP.BINARY_FILE_TYPE);
setFileTransferMode(FTP.BLOCK_TRANSFER_MODE);
Checking the reply string right after connect i got:
234 AUTH command ok. Expecting TLS Negotiation.
from here
234 Specifies that the server accepts the authentication mechanism specified by the client, and the exchange of security data is complete. A higher level nonstandard code created by Microsoft.
while trying to send file with storeFile or storeUniqeFile i get false
checking the reply string right after store file i got: 501 Server cannot accept argument.
what is weird i was able creating a directory to this client without any issues
with makeDirectory("test1");
i was trying both this links : link1 , link2
FOR EXAMPLE when i was trying to use ftp.enterLocalPassiveMode(); before ftp.storeFile(destinationfile, in);
i got time out error .
Does anyone have any idea how to solve it ?
public static void main(String[] args) throws Exception {
FTPSProvider ftps = new FTPSProvider();
String json = "connection details";
DeliveryDetailsFTPS details = gson.fromJson(json, DeliveryDetailsFTPS .class);
File file = File.createTempFile("test", ".txt");
FileUtils.write(file, " some test", true);
try (FileInputStream stream = new FileInputStream(file)) {
ftps.sendInternal(ftps.getClient(details), details, stream, file.getName());
}
}
protected void sendInternal(FTPClient client, DeliveryDetailsFTPS details, InputStream stream, String filename) throws Exception {
try {
// release the enc
DeliveryDetailsFTPS ftpDetails = (DeliveryDetailsFTPS) details;
setClient(client, ftpDetails);
boolean isSaved = false;
try (BufferedInputStream bis = new BufferedInputStream(stream)) {
isSaved = client.storeFile(filename, bis);
}
client.makeDirectory("test1");
client.logout();
if (!isSaved) {
throw new IOException("Unable to upload file to FTP");
}
} catch (Exception ex) {
LOG.debug("Unable to send to FTP", ex);
throw ex;
} finally {
client.disconnect();
}
}
#Override
protected FTPClient getClient(DeliveryDetails details) {
return new FTPSClient(isImplicitSSL((DeliveryDetailsFTPS ) details));
}
protected void setClient(FTPClient client, DeliveryDetailsFTPS details) throws Exception {
DeliveryDetailsFTPS ftpDetails = (DeliveryDetailsFTPS ) details;
client.setConnectTimeout(100000);
client.setDefaultTimeout(10000 * 60 * 2);
client.setControlKeepAliveReplyTimeout(300);
client.setControlKeepAliveTimeout(300);
client.setDataTimeout(15000);
client.connect(ftpDetails.host, ftpDetails.port);
client.setBufferSize(1024 * 1024);
client.login(ftpDetails.username, ftpDetails.getSensitiveData());
client.setControlEncoding("UTF-8");
int code = client.getReplyCode();
if (code == 530) {
throw new IOException(client.getReplyString());
}
// Set binary file transfer
client.setFileType(FTP.BINARY_FILE_TYPE);
client.setFileTransferMode(FTP.BLOCK_TRANSFER_MODE);
if (ftpDetails.ftpMode == FtpMode.PASSIVE) {
client.enterLocalPassiveMode();
}
client.changeWorkingDirectory(ftpDetails.path);
}
I have tried this solution as well didn't solve the problem:
they only way i was able send file is with FileZilla and it is using FTPES .
But i need my Java code to do it . can anyone give me a clue
I have tried almost any possible solution offered on different websites could not make it work with Apache FTPS CLIENT ,
had to use a different class which worked like a charm here is a snippet:
com.jscape.inet.ftps Link
private Ftps sendWithFtpsJSCAPE(ConnDetails details, InputStream stream, String filename) throws FtpException, IOException {
Ftps ftp;
FtpConnectionDetails ftpDetails = FtpConnectionDetails details;
ftp = new Ftps(ftpDetails.getHost(), ftpDetails.getUsername(), ftpDetails.getPassword());
if (ftpDetails.getSecurityMode().equals(FtpConnectionDetails.SecurityMode.EXPLICIT)) {
ftp.setConnectionType(Ftps.AUTH_TLS);
} else {
ftp.setConnectionType(Ftps.IMPLICIT_SSL);
}
ftp.setPort(ftpDetails.getPort());
if (!ftpDetails.getFtpMode().equals(FtpMode.ACTIVE)) {
ftp.setPassive(true);
}
ftp.setTimeout(FTPS_JSCAPE_TIME_OUT);
ftp.connect();
ftp.setBinary();
ftp.setDir(ftpDetails.getPath());
ftp.upload(stream, filename);
return ftp;
}

File upload in Java through FTP

Im trying to develop a simple java code which will upload some contents from local machine to a server/another machine.I used the below code
import sun.net.ftp.*;
import java.io.*;
public class SftpUpload {
public static void main(String args[]) {
String hostname = "some.remote.machine"; //Remote FTP server: Change this
String username = "user"; //Remote user name: Change this
String password = "start123"; //Remote user password: Change this
String upfile = args[0]; //File to upload passed on command line
String remdir = "/home/user"; //Remote directory for file upload
FtpClient ftp = new FtpClient();
try {
ftp.openServer(hostname); //Connect to FTP server
ftp.login(username, password); //Login
ftp.binary(); //Set to binary mode transfer
ftp.cd(remdir); //Change to remote directory
File file = new File(upfile);
OutputStream out = ftp.put(file.getName()); //Start upload
InputStream in = new FileInputStream(file);
byte c[] = new byte[4096];
int read = 0;
while ((read = in.read(c)) != -1 ) {
out.write(c, 0, read);
} //Upload finished
in.close();
out.close();
ftp.closeServer(); //Close connection
} catch (Exception e) {
System.out.println("Error: " + e.getMessage());
}
}
}
But it is showing error in Line 11 as 'Cannot instantiate the type FtpClient'.
Can some one help me how to rectify it.
You cannot instantiate it because sun.net.ftp.FtpClient is abstract class.
I suggest using Apache Commons Net instead of playing with sun.x packages. FTP client example can be found from here.
If you do want to use the Sun classes, use FtpClient.create(), as per the JavaDoc for this class.
i have resolved the exception.thats because my machine is connected in a network which doesnt allow FTP connection.when i tried it in a private dongle it worked.

Why uploaded file through Apache FTPClient is smaller then original file on the local?

I am uploading files(.cvs,.zip,.rar,.doc,.png,.jpg...) to ftp server. The strange is everything is successfully but I miss some data.
Does any body know why it happens and how to fix it?
public static void uploadWithCommonsFTP(File fileToBeUpload) {
FTPClient f = new FTPClient();
try {
f.connect(server.getServer());
f.login(server.getUsername(), server.getPassword());
f.changeWorkingDirectory("user");
f.setFileType(FTP.BINARY_FILE_TYPE);
f.setFileTransferMode(FTP.BINARY_FILE_TYPE);//this is part of Mohammad Adil's solutions
f.enterLocalPassiveMode();
ByteArrayInputStream in = new ByteArrayInputStream(FileUtils.readFileToByteArray(fileToBeUpload));
boolean reply = f.storeFile(fileToBeUpload.getName(), in);
if(!f.completePendingCommand()) {
f.logout();
f.disconnect();
System.err.println("File transfer failed.");
System.exit(1);
}
if(reply){
JOptionPane.showMessageDialog(null,"uploaded successfully.");
}else{
JOptionPane.showMessageDialog(null,"Upload failed.");
}
}
//Logout and disconnect from server
in.close();//this is part of Mohammad Adil's solutions
f.logout();
f.disconnect();
} catch (IOException e) {
e.printStackTrace();
}
}
It's often forgotten that FTP has two modes of operation - one for text files and the other for binary(jpg,csv,pdf,zip) files.
Your code doesn't work because the default transfer mode for FTPClient is FTP.ASCII_FILE_TYPE. You just need to update the configuration to transfer in binary mode.
Add this in your code :
f.setFileTransferMode(FTP.BINARY_FILE_TYPE);
just put that line after f.setFileType(FTP.BINARY_FILE_TYPE);
and it should work then.
EDIT:
You are not closing inputStream in your code,Just call in.close() before calling logout()

upload progress in FTPClient

I'm using commons-net FTPClient to upload some files.
How can I get progress of upload (number of bytes uploaded up now)?
Thanks
Sure, just use CopyStreamListener. Below you will find an example (copied from commons-io wiki) of file retrieval, so You can easily change it other-way-round.
try {
InputStream stO =
new BufferedInputStream(
ftp.retrieveFileStream("foo.bar"),
ftp.getBufferSize());
OutputStream stD =
new FileOutputStream("bar.foo");
org.apache.commons.net.io.Util.copyStream(
stO,
stD,
ftp.getBufferSize(),
/* I'm using the UNKNOWN_STREAM_SIZE constant here, but you can use the size of file too */
org.apache.commons.net.io.CopyStreamEvent.UNKNOWN_STREAM_SIZE,
new org.apache.commons.net.io.CopyStreamAdapter() {
public void bytesTransferred(long totalBytesTransferred,
int bytesTransferred,
long streamSize) {
// Your progress Control code here
}
});
ftp.completePendingCommand();
} catch (Exception e) { ... }
I think perhaps it is better to us the CountingOutputStream since it seems intended for this very purpose ?
This is answered by someone here: Monitoring progress using Apache Commons FTPClient

dwr - upload file and download file in one request

is it possible to upload a file and subsequently when receiving response download the file,
I mean in one request I'll upload a file and download the file in one action?
Maybe this demo code will be helpful for you:
http://directwebremoting.org/dwr-demo/simple/download.html
Yes It's possible to do that at least in dwr 3.
An example which return a excel to download from client:
//Java side:
public FileTransfer getExcel(Parametros param){
byte[] result = <here get data>;
InputStream myInputStream = new ByteArrayInputStream(result);
String excelFormat = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
FileTransfer dwrExcelFile = new FileTransfer("excel.xlsx", excelFormat, myInputStream);
return dwrExcelFile;
}
//Javascript side:
function downloadExcelFile() {
dwr.engine.setTimeout(59000);
var params = <params_to_send>;
<Java_class>.getExcel(params, {callback:function(dataFromServer) {
downloadExcelCallback(dataFromServer);
}});
}
function downloadExcelCallback(data) {
dwr.engine.openInDownload(data);
}

Categories