I used following code for downloading XML file from ftp to android phone memory using that i able to connect ftp but while retrieving XML to local memory it is giving following exception 07-19 15:01:03.721: DEBUG/SntpClient(61): request time failed: java.net.SocketException: Address family not supported by protocol
please help somebody thank you,
Java class
private void fnfileDownloadBuf()
{
FTPClient client = new FTPClient();
FileOutputStream fos = null;
try {
//client.connect("ftp://ftp.qualityinaction.net/QIA/Questions/Airlines/");
client.connect("ftp.qualityinaction.net");
client.login("qualityinaction.net","password");
client.setFileType(FTP.BINARY_FILE_TYPE);
//
// The remote filename to be downloaded.
//
// String filename = "/QIA/Questions/Airlines/index.xml";
String filename = getFilesDir().getAbsolutePath()+ File.separator + "/index.xml";
// String filename = "/QIA/Questions/Airlines/index.xml";
File file = new File(filename);
fos = new FileOutputStream(file);
//
// Download file from FTP server
//
//client.retrieveFile("/" + filename, fos);
client.retrieveFile("/QIA/Questions/Airlines/index.xml;type=i", fos);
// client.retrieveFile( getFilesDir().getAbsolutePath()+ File.separator + "/index.xml", fos);
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (fos != null) {
fos.close();
}
client.disconnect();
} catch (IOException e) {
e.printStackTrace();
}
}
}
manifest XML file
<uses-permission android:name="android.permission.INTERNET"></uses-permission>
Exception
exception 07-19 15:01:03.721: DEBUG/SntpClient(61): request time failed: java.net.SocketException: Address family not supported by protocol
for that you have to use passive mode corrected code as shown below..
** Java Code **
FTPClient ObjFtpCon = new FTPClient();
try
{
ObjFtpCon.connect(strIp);
if (ObjFtpCon.login(strFtpUser, strFtpPwd))
{
ObjFtpCon.enterLocalPassiveMode(); // important!
ObjFtpCon.cwd("/QIA/Questions/Hotel/");
String[] strArrQuesFiles=ObjFtpCon.listNames();
int intcnt=0;
boolean blnresult = false;
File objfile=new File(getFilesDir().getAbsolutePath()+ "/Questions");
if(!objfile.exists())objfile.mkdirs();
objfile=null;
for(intcnt=0;intcnt<strArrQuesFiles.length;intcnt++)
{
objfile=new File(getFilesDir().getAbsolutePath()+ File.separator + "/Questions/" + strArrQuesFiles[intcnt]);
objfile.createNewFile();
//ByteArrayInputStream in = new ByteArrayInputStream(data.getBytes());
FileOutputStream objFos=new FileOutputStream(objfile);
blnresult=ObjFtpCon.retrieveFile(strArrQuesFiles[intcnt] , objFos);
objFos.close();
}
// boolean result = con.storeFile("/QIA/Response/test/Responses.xml", in);
if (blnresult) dlgAlert.setMessage("Questions Are Successfully Downloaded").create().show();
}
}
catch (Exception e)
{
e.printStackTrace();
}
try
{
ObjFtpCon.logout();
ObjFtpCon.disconnect();
}
catch (IOException e)
{
e.printStackTrace();
}
}
Related
I am creating Xmpp application using SMACK api and Spark for test.
I am able to send from Spark but I cannot see Any Directory and File created in android gallery.
I log the method incoming.getAmountWritten() and it is giving me
07-27 21:00:58.789: V/Receiving Status ...(17652): 208861
It means I have got the file and now I have to write on physical storage. May be there is problem with my android code.
Please find Android Code
#Override
public void fileTransferRequest(final FileTransferRequest fileRequest) {
final File dir = Environment.getExternalStorageDirectory();
final File folder = new File(dir+ "/illuxplain/");
boolean success = true;
if (!folder.exists()) {
success = folder.mkdir();
}
if (success) {
Thread receiving = new Thread(new Runnable() {
#Override
public void run() {
IncomingFileTransfer incoming = fileRequest.accept();
Log.v("Receiving File Name", incoming.getFileName());
File file = new File(folder, incoming.getFileName());
try {
incoming.recieveFile(file);
while (!incoming.isDone()) {
try {
Thread.sleep(1000L);
} catch (Exception e) {
Log.e("", e.getMessage());
}
if (incoming.getStatus().equals(Status.error)) {
Log.e("ERROR!!! ", incoming.getError() + "");
}
if (incoming.getException() != null) {
incoming.getException().printStackTrace();
}
}
Log.v("Receiving Status ... ",""+incoming.getAmountWritten());
} catch (Exception e) {
e.printStackTrace();
Log.e("", e.getMessage());
}
}
});
receiving.start();
}else{
System.out.println("Directory Not Created");
}
}
}
When I go to gallery and see if I got the file. I see no directory created and of course no file.
You need to write the data into the file. Here is an example to code to write the data in to the file
File file = new File(folder, incoming.getFileName());
String string = "Hello world!";
FileOutputStream outputStream;
try {
outputStream = new FileOutputStream(file);
outputStream.write(string.getBytes());
outputStream.close();
} catch (Exception e) {
e.printStackTrace();
}
In my Android app I should store the data from user in simple text-file, that I created in the raw directory. After this, I'm trying to write file in APPEND MODE by using simple code from the Google's examples:
try
{
FileOutputStream fos = openFileOutput(FILE_NAME, Context.MODE_APPEND);
fos.write((nameArticle+"|"+indexArticle).getBytes());
fos.close();
}
catch (FileNotFoundException e)
{
e.printStackTrace();
}
catch (IOException e)
{
e.printStackTrace();
}
But nothing happens: no exceptions, but I can see nothing in my FILE_NAME, besides the single record, which was added by me.
What am I doing wrong ? Is it possible at common to write to file in emulator ?
openFileOutput will only allow you to open a private file associated with this Context's application package for writing. I'm not sure where the file you're trying to write to is located. I mean full path. You can use the code below to write to a file located anywhere (as long as you have perms). The example is using the external storage, but you should be able to modify it to write anywhere:
public Uri writeToExternalStoragePublic() {
final String filename = mToolbar.GetTitle() + ".html";
final String packageName = this.getPackageName();
final String folderpath = Environment.getExternalStorageDirectory().getAbsolutePath() + "/Android/data/" + packageName + "/files/";
File folder = new File(folderpath);
File file = null;
FileOutputStream fOut = null;
try {
try {
if (folder != null) {
boolean exists = folder.exists();
if (!exists)
folder.mkdirs();
file = new File(folder.toString(), filename);
if (file != null) {
fOut = new FileOutputStream(file, false);
if (fOut != null) {
fOut.write(mCurrentReportHtml.getBytes());
}
}
}
} catch (IOException e) {
Toast.makeText(this, e.getMessage(), Toast.LENGTH_LONG).show();
}
return Uri.fromFile(file);
} finally {
if (fOut != null) {
try {
fOut.flush();
fOut.close();
} catch (IOException e) {
Toast.makeText(this, e.getMessage(), Toast.LENGTH_LONG).show();
}
}
}
}
In the example you have given, try catching 'I0Exception`, I have a feeling you do not have permission where you are trying to write.
Have a Happy New Year.
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();
In my application i am downloading images from the web and these images will be stored in the sdcard. Here i am using the url as file name. For this first i am checking the file name is exits in the sdcard. if it exists then get the image from the sdcard. otherwise i am getting from web.But i am geting the following exception how to handle it.
Exception
09-09 15:24:58.873: WARN/System.err(1117): java.io.IOException: Parent directory of file is not writable: /sdcard/http+++ecx.images-amazon.com+images+I+41KdssHpg1L._SL160_.jpg
09-09 15:24:58.904: WARN/System.err(1117): at java.io.File.createNewFile(File.java:1263)
09-09 15:24:58.924: WARN/System.err(1117): at com.ibkr.elgifto.GiftCategories$itemlistadapter$4$1.run(GiftCategories.java:947)
Code
private Drawable getDrawableFromUrl(String imageUrl) {
String filename = imageUrl;
filename = filename.replace("/", "+");
filename = filename.replace(":", "+");
filename = filename.replace("~", "s");
final File file = new File(Environment.getExternalStorageDirectory() + File.separator + filename);
boolean exists = file.exists();
if (!exists) {
try {
URL myFileUrl = new URL(imageUrl);
HttpURLConnection conn = (HttpURLConnection) myFileUrl.openConnection();
conn.setDoInput(true);
conn.connect();
InputStream is = conn.getInputStream();
final Bitmap result = BitmapFactory.decodeStream(is);
is.close();
new Thread() {
public void run() {
ByteArrayOutputStream bytes = new ByteArrayOutputStream();
if (result != null) {
result.compress(Bitmap.CompressFormat.JPEG, 40, bytes);
}
try {
if (file.createNewFile()) {
//
} else {
//
}
FileOutputStream fo;
fo = new FileOutputStream(file);
fo.write(bytes.toByteArray());
fo.flush();
fo.close();
// result.recycle();
} catch (IOException e) {
e.printStackTrace();
}
}
}.start();
BitmapDrawable returnResult = new BitmapDrawable(result);
return returnResult;
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return null;
} else {
return new BitmapDrawable(BitmapFactory.decodeFile(file.toString()));
}
}
just add permission to AndroidManifest.xml file and check, it may work.
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
You should always check whether SD storage is available before accessing it. If it's not, you can inform the user about failure instead of crashing application. Here's the function I'm using:
public static boolean storageAvailable()
{
String state = Environment.getExternalStorageState();
if (!Environment.MEDIA_MOUNTED.equals(state)) return false;
return true;
}
There's also possibility you forgot to add required permission into AndroidManifest.xml:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
public class FtpDownloadDemo {
public static void Connection(String filename) {
FTPClient client = new FTPClient();
FileOutputStream fos = null;
try {
client.connect("ftp.domain.com");
client.login("admin", "secret");
//
// The remote filename to be downloaded.
//
ftpClient.setFileType(FTP.IMAGE_FILE_TYPE);
fos = new FileOutputStream(filename);
//
// Download file from FTP server
//
client.retrieveFile("/" + filename, fos);
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (fos != null) {
fos.close();
}
client.disconnect();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
I am using this code to download some image file. but at fos = new FileOutputStream(filename); getting file.jpeg is readonly file exception. i am using commons.net jar file for ftp connection. please help me where i am wrong.
I supplied the host, username and password when creating the class and then called this to download the file. Those guys were right it probably was trying to write to the root or something. I have been using commons-net-2.2.jar for this client.
public void GetFileFTP(String srcFileSpec, String destpath, String destname) {
File pathSpec = new File(destpath);
FTPClient client = new FTPClient();
BufferedOutputStream fos = null;
try {
client.connect(mhost);
client.login(muser, mpass);
client.enterLocalPassiveMode(); // important!
client.setFileType(org.apache.commons.net.ftp.FTP.BINARY_FILE_TYPE);
fos = new BufferedOutputStream(
new FileOutputStream(pathSpec.toString()+"/"+destname));
client.retrieveFile(srcFileSpec, fos);
}//try
catch (IOException e) {
Log.e("FTP", "Error Getting File");
e.printStackTrace();
}//catch
finally {
try {
if (fos != null) fos.close();
client.disconnect();
}//try
catch (IOException e) {
Log.e("FTP", "Disconnect Error");
e.printStackTrace();
}//catch
}//finally
Log.v("FTP", "Done");
}//getfileFTP
Hope this helps.
phavens