Android FTP client application- how to download the file from FTP Server - android

i am using org.apache.commons.net.ftp library, i have uploaded the file but when i try to download the file from FTP Server to my emulator's virtual SDCard it didn't work.
how to specify the destination path? that is the SD Card path where i need to download, and how to specify the source file path ( file in FTP server page path)?
here is the code i tried to perform the download,
try
{
FileOutputStream desFileStream1 = new FileOutputStream("/sdcard/Baby.jpg");
Boolean status1 = con.retrieveFile("/Baby", desFileStream1);
if(status1)
{
lblResult2.setText("File downloaded Successfully");
}
else
{
lblResult2.setText("File download failed");
}
DesFileStream1.close();
} catch (Exception e)
{
Log.d(TAG, "download failed");
}
any one of you help me out.

Use getExternalStorageDirectory() or getExternalStoragePublicDirectory() on Environment to find the proper root of external storage, which is not /sdcard on most Android devices.

File file = new File(Environment.getExternalStorageDirectory() + "/pdf");
if(!file.exists())
file.mkdir(); //directory is created;
try {
ftp = new FTPClient();
ftp.connect("yours ftp URL",21);//don't write ftp://
try {
int reply = ftp.getReplyCode();
if (!FTPReply.isPositiveCompletion(reply)) {
throw new Exception("Connect failed: " + ftp.getReplyString());
}
if (!ftp.login("username","password")) {
throw new Exception("Login failed: " + ftp.getReplyString());
}
try {
ftp.enterLocalPassiveMode();
if (!ftp.setFileType(FTP.BINARY_FILE_TYPE)) {
// Log.e(TAG, "Setting binary file type failed.");
}
transferFile(ftp);
} catch(Exception e) {
// handleThrowable(e);
} finally {
if (!ftp.logout()) {
// Log.e(TAG, "Logout failed.");
}
}
} catch(Exception e) {
// handleThrowable(e);
} finally {
ftp.disconnect();
}
} catch(Exception e) {
// handleThrowable(e);
}
}
private void transferFile(FTPClient ftp) throws Exception {
long fileSize=0;
fileSize = getFileSize(ftp, "nag.pdf");
Log.v("async","fileSize"+fileSize);
if(!(fileSize==0)){
InputStream is = retrieveFileStream(ftp, "nag.pdf");
downloadFile(is, fileSize);
is.close();
}
else
//nosuch files
if (!ftp.completePendingCommand()) {
throw new Exception("Pending command failed: " + ftp.getReplyString());
}
}
private InputStream retrieveFileStream(FTPClient ftp, String filePath)
throws Exception {
InputStream is = ftp.retrieveFileStream(filePath);
int reply = ftp.getReplyCode();
if (is == null
|| (!FTPReply.isPositivePreliminary(reply)
&& !FTPReply.isPositiveCompletion(reply))) {
throw new Exception(ftp.getReplyString());
}
return is;
}
private byte[] downloadFile(InputStream is, long fileSize)
throws Exception {
outputStream os = newFileOutputStream(Environment.getExternalStorageDirectory()
+ "/pdf/nag.pdf");
byte[] buffer = new byte[(int) fileSize];
int readCount;
while( (readCount = is.read(buffer)) > 0) {
os.write(buffer, 0, readCount);
}
Log.i("tag", "buffer = " + buffer);
return buffer; // <-- Here is your file's contents !!!
}
private long getFileSize(FTPClient ftp, String filePath) throws Exception {
long fileSize = 0;
FTPFile[] files = ftp.listFiles(filePath);
if (files.length == 1 && files[0].isFile()) {
fileSize = files[0].getSize();
}
Log.i("tag", "File size = " + fileSize);
return fileSize;
}
}

Related

How to save a file as apk without increasing in size in Android (can not install it)

I try to download file from server and save it in internel storage and then install it.
I downloaded it using retrofit by this code
Call<ResponseBody> call = apiService.getNewVersion();
call.enqueue(new Callback<ResponseBody>() {
#Override
public void onResponse(Call<ResponseBody> call,
Response<ResponseBody> response) {
if (response.isSuccessful() ) {
Log.d("1", "server contacted and has file");
boolean writtenToDisk =
writeResponseBodyToDisk(response.body());
Log.d("2", "file download was a success? " + writtenToDisk);
} else {
Log.d("3", "server contact failed");
}
}
#Override
public void onFailure(Call<ResponseBody> call, Throwable t) {
Log.e("4", "error");
}
});
and I saved it by this code
private boolean writeResponseBodyToDisk(ResponseBody body) {
try {
// todo change the file location/name according to your needs
File futureStudioIconFile = new
File(context.getExternalFilesDir(null) + File.separator + "app-debug.apk");
InputStream inputStream = null;
OutputStream outputStream = null;
try {
byte[] fileReader = new byte[4096];
long fileSize = body.contentLength();
long fileSizeDownloaded = 0;
inputStream = body.byteStream();
outputStream = new FileOutputStream(futureStudioIconFile);
while (true) {
int read = inputStream.read(fileReader);
if (read == -1) {
break;
}
outputStream.write(fileReader, 0, read);
fileSizeDownloaded += read;
Log.d("TAG", "file download: " + fileSizeDownloaded + " of "
+ fileSize);
}
outputStream.flush();
return true;
} catch (IOException e) {
return false;
} finally {
if (inputStream != null) {
inputStream.close();
}
if (outputStream != null) {
outputStream.close();
}
}
} catch (IOException e) {
return false;
}
}
its original 4.56MB but it shows 6.08MB in Android storage.
When I open it to install it shows
version N /A size N/ A
and when I try to install it, it shows this parse problem
Do you have any idea to solve this problem?
How to remove extra bytes?
You should make sure that you use HttpResponseMessage.content in your web service method because a normal return will not be a standard size for the file that you want:
[HttpGet]
[Route("api/Depository/DownloadFileFTP")] // /{pass}
public HttpResponseMessage DownloadFileFTP() //string pass
{
HttpResponseMessage result = null;
string ftphost = "*******";
string ftpfilepath = "/app-debug.apk";
byte[] fileData;
string ftpfullpath = "ftp://" + ftphost + ftpfilepath;
using (WebClient request = new WebClient())
{
request.Credentials = new NetworkCredential("**", "****");
fileData = request.DownloadData(ftpfullpath);
}
byte[] bytes = fileData;
result = Request.CreateResponse(HttpStatusCode.OK);
result.Content = new ByteArrayContent(bytes);
result.Content.Headers.ContentDisposition = new
System.Net.Http.Headers.ContentDispositionHeaderValue("attachment");
result.Content.Headers.ContentDisposition.FileName = "app.apk";
return result;
}

okhttp not downloading the file

I am using okhttp for downloading video from server. there is no error no exception but the file is not downloading every where but it seems as it is.
Here is the code:
OkHttpClient httpClient = new OkHttpClient();
Call call = httpClient.newCall(new Request.Builder().url("http://res.cloudinary.com/demo/video/upload/v1427018743/ygzxwxmflekucvqcrb8c.mp4").get().build());
try {
File file = new File(getCacheDir(), user_Videos.get(i).video_title+ ".mp4");
OutputStream out = new FileOutputStream(file);
Response response = call.execute();
if (response.code() == 200) {
InputStream inputStream = null;
try {
inputStream = response.body().byteStream();
byte[] buff = new byte[1024 * 8];
long downloaded = 0;
long target = response.body().contentLength();
publishProgress(0L, target);
while (true) {
int readed = inputStream.read(buff);
if (readed == -1) {
break;
}
//write buff
downloaded += readed;
try {
out.write(buff,0,readed);
} catch (Exception e) {
e.printStackTrace();
}
publishProgress(downloaded, target);
if (isCancelled()) {
return false;
}
}
return downloaded == target;
} catch (IOException ignore) {
return false;
} finally {
if (inputStream != null) {
out.flush();
out.close();
inputStream.close();
}
}
} else {
return false;
}
} catch (IOException e) {
e.printStackTrace();
return false;
}
The progress is showing correctly but video is not showing in directory.
Thanks.
So there is no problem in my code but the path. Thanks #greenapps who made me think about path/ directory.
Basically I just change the path to a real one instead of cache and yup here is the video.
Changed this line
File file = new File(getCacheDir(), user_Videos.get(i).video_title + ".mp4");
to this
File file = new File(Environment.getExternalStorageDirectory(), user_Videos.get(i).video_title+ ".mp4");
Thanks #greenapps for the clue.

java.io.FileNotFoundException: /: open failed: EISDIR (Is a directory)

File albumF = getVideoAlbumDir();
String path = albumF.getAbsolutePath();
// path =/storage/emulated/0/Pictures/.MyImages (Hidden folder)
// fileSelected.fileName()=IMG_20140417_113847.jpg
File localFile = new File(path + "/" + fileSelected.fileName());
Log.v("", "file exist===" + localFile.exists());
if (!localFile.exists()) {
Log.v("", "inside if===");
Log.v("", "Parent Filet===" + localFile.getParentFile());
localFile.getParentFile().mkdirs();
// localFile.createNewFile();
copy(fileSelected, localFile);
} else {
Log.v("", "inside else===");
mCurrentPhotoPath = localFile.getAbsolutePath();
uploadMediaFile();
}
This copy method copies data from dropbox file to my local storage.
private void copy(final Entry fileSelected, final File localFile) {
final ProgressDialog pd = ProgressDialog.show(ChatActivity.this,
"Downloading...", "Please wait...");
new Thread(new Runnable() {
#Override
public void run() {
BufferedInputStream br = null;
BufferedOutputStream bw = null;
DropboxInputStream fd;
try {
fd = mDBApi.getFileStream(fileSelected.path,
localFile.getAbsolutePath());
br = new BufferedInputStream(fd);
bw = new BufferedOutputStream(new FileOutputStream(
localFile));
byte[] buffer = new byte[4096];
int read;
while (true) {
read = br.read(buffer);
if (read <= 0) {
break;
}
bw.write(buffer, 0, read);
}
pd.dismiss();
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
android.os.Message msg = new android.os.Message();
msg.arg1 = 100;
if (msg.arg1 >= 100) {
progressHandler.sendMessage(msg);
mCurrentPhotoPath = localFile.getAbsolutePath();
}
} catch (DropboxException e) {
e.printStackTrace();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (bw != null) {
try {
bw.close();
if (br != null) {
br.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}).start();
I am creating file in a folder using localFile.getParentFile().mkdirs();
I got above error when I upload this file to server.
how to fix this?
If you've tried all other options - and problem still persists - then maybe you have a case when the file you want to create matches name of already existing directory.(which might be earlier created my some call to mkdirs() maybe accidentally).
Example:
You want to save file Test\test.pdf but you already have folder Test\Test.pdf\

Dropbox Sync API Android - Updating Cached Files

I am facing trouble in updating the existing cached file within my Android Application.
for(DbxFileInfo fInfo : fileList)
{
Log.d(TAG, "File Path = "+fInfo.path.toString());
String fileName = fInfo.path.getName().trim();
try
{
DbxPath tempFilePath = new DbxPath(fInfo.path.toString());
DbxFile tempFile = mDbFileSystem.open(tempFilePath);
if(tempFile.getSyncStatus().isCached)
{
Log.v(TAG, "File is already cached !");
if(tempFile.getSyncStatus().isLatest)
{
Log.v(TAG, "File's Latest Version is Cached !");
}
else
{
Log.v(TAG, "File's Latest Version is not Cached !");
}
}
try
{
tempFile.getNewerStatus();
}
catch(Exception dBException)
{
Log.e(TAG, "Error while getting newer Status !");
}
InputStream input = new BufferedInputStream(tempFile.getReadStream());
OutputStream output = new FileOutputStream(cntx.getFilesDir() + "/SyncedData/" + fileName);
byte data[] = new byte[1024];
int count;
//total size is in Bytes
while ((count = input.read(data)) != -1)
{
totalBytesDownloaded += count;
publishProgress((int) (totalBytesDownloaded * 100/totalFileSize));
output.write(data, 0, count);
}
output.flush();
output.close();
input.close();
tempFile.close();
mDbFileSystem.delete(tempFile.getPath());
result = true;
}
catch(Exception e)
{
Log.e(TAG, "Error occured while downloading files !, Error = "+e.toString());
result = false;
}
}
I am putting different files with same names on my Synced Dropbox folder and after Downloading them i am getting the older version of files.
Is there any way i can update my existing cached files or Clear the Dropbox Cache (that is within my App)
Any help is highly appreciated, thanks.
Here's how the Sync API works:
It constantly syncs metadata (what files exist and their revisions) and notifies you via listeners you set up on the file system.
For open files, it downloads any newer version of the file available and notifies you via the listener you set up on the file itself.
So if you want to get the latest version of a file, you need to open the file and hold it open while waiting for the listener to notify you that the newer version of the file is cached. Then you can call update to get access to that new data.
EDIT: Pasting code from https://www.dropbox.com/developers/sync/start/android#listeners:
DbxFileStatus status = testFile.getSyncStatus();
if (!status.isCached) {
testFile.addListener(new DbxFile.Listener() {
#Override
public void onFileChange(DbxFile file) {
// Check testFile.getSyncStatus() and read if it's ready
}
});
// Check if testFile.getSyncStatus() is ready already to ensure nothing
// was missed while adding the listener
}
Here is my attempt to get the latest file but as I stated in the comment to your question, it seems I sometimes have to do two sync calls in order to get the latest file.
The fileModified and fileSize comparison is rather crude but seems to do the trick. Better than what I have found so far at least.
public DropboxFileDownloader() {
super("FileDownloader");
}
#Override
protected void onHandleIntent(Intent intent) {
String turiosHome = intent.getStringExtra(Constants.EXTRA_HOME);
String fileName = intent.getStringExtra(Constants.EXTRA_FILENAME);
String folderPath = intent.getStringExtra(Constants.EXTRA_FOLDERPATH);
ResultReceiver receiver = intent.getParcelableExtra(Constants.EXTRA_RECEIVER);
Bundle bundle = new Bundle();
String fullpath = folderPath + "/" + fileName;
DbxFile file;
long fileModified = 0;
long fileSize = 0;
try {
file = dbxFs.open(new DbxPath(fullpath));
try {
DbxFileStatus fileStatus = file.getNewerStatus();
if (fileStatus != null && !fileStatus.isLatest) {
/*while (file.getNewerStatus().pending == PendingOperation.DOWNLOAD) {
Log.d(TAG, "Waiting for " + fileName + " to be downloaded");
Thread.sleep(1000);
}*/
if (fileStatus.isCached) {
//Start of Edit
try
{
//Running this do while loop until the Latest version of this file is cached.
do
{
Log.d(TAG, "Updating the existing file !");
//Updating the file
file.update();
while (file.getNewerStatus().pending ==PendingOperation.DOWNLOAD)
{
Log.d(TAG, "Waiting for " + fileName+ " to be downloaded");
Thread.sleep(1000);
}
} while (fileStatus.isLatest);
}
catch (Exception dBException)
{
Log.e(TAG, "Error while getting newer Status !, Error = "+dBException.toString());
dBException.printStackTrace();
}
//End of Edit
}
}
fileModified = file.getInfo().modifiedTime.getTime();
fileSize = file.getInfo().size;
} catch (DbxException e) {
Log.e(TAG, e.getMessage(), e);
bundle.putString(Constants.EXTRA_MESSAGE, e.getMessage());
receiver.send(DropboxFileDownloaderResultReceiver.RESULTCODE_ERROR, bundle);
return;
} catch (InterruptedException e) {
e.printStackTrace();
}
} catch (InvalidPathException e1) {
Log.e(TAG, e1.getMessage(), e1);
bundle.putString(Constants.EXTRA_MESSAGE, e1.getMessage());
receiver.send(DropboxFileDownloaderResultReceiver.RESULTCODE_ERROR, bundle);
return;
} catch (DbxException e1) {
Log.e(TAG, e1.getMessage(), e1);
bundle.putString(Constants.EXTRA_MESSAGE, e1.getMessage());
receiver.send(DropboxFileDownloaderResultReceiver.RESULTCODE_ERROR, bundle);
return;
}
File stored_dir = new File(turiosHome + "/" + folderPath);
if (!stored_dir.exists()) {
stored_dir.mkdirs();
}
File stored_file = new File(turiosHome + "/" + folderPath,
fileName);
// File stored_file = getFileStreamPath(fileName);
long local_modified = stored_file.lastModified();
long local_size = stored_file.length();
boolean should_sync = (fileModified > local_modified)
|| fileSize != local_size;// && Math.abs(fileModified -
// local_modified) >
// TimeUnit.MILLISECONDS.convert(1,
// TimeUnit.MINUTES);
boolean fileexists = stored_file.exists();
if (should_sync || !fileexists) {
InputStream inputStream = null;
FileOutputStream out = null;
try {
// read this file into InputStream
inputStream = file.getReadStream();
out = new FileOutputStream(stored_file);
int read = 0;
byte[] bytes = new byte[1024];
int bytes_counter = 0;
while ((read = inputStream.read(bytes)) != -1) {
out.write(bytes, 0, read);
bytes_counter++;
}
Log.d(TAG, "Wrote: " + file.getPath().getName() + " "
+ bytes_counter + " kb");
if (!fileexists) {
bundle.putString(Constants.EXTRA_FILEPATH, fullpath);
receiver.send(DropboxFileDownloaderResultReceiver.RESULTCODE_CREATED, bundle);
} else {
bundle.putString(Constants.EXTRA_FILEPATH, fullpath);
receiver.send(DropboxFileDownloaderResultReceiver.RESULTCODE_UPDATED, bundle);
}
} catch (IOException e) {
Log.e(TAG, e.getMessage(), e);
bundle.putString(Constants.EXTRA_MESSAGE, e.getMessage());
receiver.send(DropboxFileDownloaderResultReceiver.RESULTCODE_ERROR, bundle);
} finally {
try {
if (inputStream != null) {
inputStream.close();
}
if (out != null) {
out.flush();
out.close();
}
} catch (IOException e) {
Log.e(TAG, e.getMessage(), e);
bundle.putString(Constants.EXTRA_MESSAGE, e.getMessage());
receiver.send(DropboxFileDownloaderResultReceiver.RESULTCODE_ERROR, bundle);
}
}
}
else {
bundle.putString(Constants.EXTRA_FILEPATH, fullpath);
receiver.send(DropboxFileDownloaderResultReceiver.RESULTCODE_UPTODATE, bundle);
}
file.close();
}
}
I can't found working example for me. But for my case - i don't need cashed version of files - only newest (data synchronization between devices).
I used
mDbFileSystem.setMaxFileCacheSize(0);
All or nothing. But now nessasary thread for downloading in background.

Android FTPClient - retrieveFileStream() always returns null

I am a newbie to Android. I am trying download a file from ftp server to sdcard using Apache Commons FTPClient. The line InputStream input = client.retrieveFileStream("/" + fileName); always returns null. But the file is there in Ftp location. Kindly help me to know where the mistake is.
I have set the following permissions in my manifest; android:name="android.permission.INTERNET" and android:name="android.permission.WRITE_EXTERNAL_STORAGE"
My Code
private static void downLoad(){
FTPClient client = new FTPClient();
FileOutputStream fos = null;
try {
client.connect("ftp.doamin.com");
client.login("8888", "8888");
String filePath = "/mnt/sdcard/download/CheckboxHTML.txt" ;
String fileName = "CheckboxHTML.txt";
fos = new FileOutputStream(filePath);
InputStream input = client.retrieveFileStream("/" + fileName);
byte[] data = new byte[1024];
int count = input.read(data);
while ((count = input.read(data)) != -1) {
fos.write(data, 0, count);
}
fos.close();
if(!client.completePendingCommand()) {
client.logout();
client.disconnect();
System.err.println("File transfer failed.");
}
} catch (SocketException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
Thanks for your time and interest. Ananth.
AFAIK. You are suppose to finalize file transfers by calling completePendingCommand() and verifying that the transfer was indeed successful. i.e. you need to add call the function below fos.clos().
fos.close();
client.completePendingCommand()
You may also consider this, according to the API for FTPClient.retrieveFileStream(), the method returns null when it cannot open the data connection, in which case you should check the reply code (e.g. getReplyCode(), getReplyString(), getReplyStrings()) to see why it failed.
File file = new File(Environment.getExternalStorageDirectory() + "/pdf");
if(!file.exists())
file.mkdir(); //directory is created;
try {
ftp = new FTPClient();
ftp.connect("yours ftp URL",21);//don't write ftp://
try {
int reply = ftp.getReplyCode();
if (!FTPReply.isPositiveCompletion(reply)) {
throw new Exception("Connect failed: " + ftp.getReplyString());
}
if (!ftp.login("username","password")) {
throw new Exception("Login failed: " + ftp.getReplyString());
}
try {
ftp.enterLocalPassiveMode();
if (!ftp.setFileType(FTP.BINARY_FILE_TYPE)) {
// Log.e(TAG, "Setting binary file type failed.");
}
transferFile(ftp);
} catch(Exception e) {
// handleThrowable(e);
} finally {
if (!ftp.logout()) {
// Log.e(TAG, "Logout failed.");
}
}
} catch(Exception e) {
// handleThrowable(e);
} finally {
ftp.disconnect();
}
} catch(Exception e) {
// handleThrowable(e);
}
}
private void transferFile(FTPClient ftp) throws Exception {
long fileSize=0;
fileSize = getFileSize(ftp, "nag.pdf");
Log.v("async","fileSize"+fileSize);
if(!(fileSize==0)){
InputStream is = retrieveFileStream(ftp, "nag.pdf");
downloadFile(is, fileSize);
is.close();
}
else
//nosuch files
if (!ftp.completePendingCommand()) {
throw new Exception("Pending command failed: " + ftp.getReplyString());
}
}
private InputStream retrieveFileStream(FTPClient ftp, String filePath)
throws Exception {
InputStream is = ftp.retrieveFileStream(filePath);
int reply = ftp.getReplyCode();
if (is == null
|| (!FTPReply.isPositivePreliminary(reply)
&& !FTPReply.isPositiveCompletion(reply))) {
throw new Exception(ftp.getReplyString());
}
return is;
}
private byte[] downloadFile(InputStream is, long fileSize)
throws Exception {
outputStream os = newFileOutputStream(Environment.getExternalStorageDirectory()
+ "/pdf/nag.pdf");
byte[] buffer = new byte[(int) fileSize];
int readCount;
while( (readCount = is.read(buffer)) > 0) {
os.write(buffer, 0, readCount);
}
Log.i("tag", "buffer = " + buffer);
return buffer; // <-- Here is your file's contents !!!
}
private long getFileSize(FTPClient ftp, String filePath) throws Exception {
long fileSize = 0;
FTPFile[] files = ftp.listFiles(filePath);
if (files.length == 1 && files[0].isFile()) {
fileSize = files[0].getSize();
}
Log.i("tag", "File size = " + fileSize);
return fileSize;
}
}
After have worked on this problem and spent hours, I've found out that the Android Apache retrieveFile() and retrieveFileStream sometimes don't work very well when the FileSize is too big.
Ensure to set the right TypeFile to BinaryFile
mFTPClient.setFileType(FTP.BINARY_FILE_TYPE);
Also never forget to pass in LocalPassiveMode for download commands
mFTPClient.enterLocalPassiveMode();

Categories

Resources