问题
Android n00b trying to figure out file server upload. I'm having a lot of trouble trying to upload a file to my FTP server in Android using the storeFile
method in FTPClient
, testing on a Galaxy Nexus. Two problems. First, it runs very, VERY slowly - like a minute or more for a file of a few bytes before the code moves on (so that my display often goes to sleep before it finishes running). Second, no file arrives on the server when it's done. But the code does continue running and I don't get any explicit error messages telling me something's wrong, as far as I can tell. But third, AFTER all that (and logout), it gives me a NullPointerException and aborts the activity.
(Also a fourth problem that NetworkInfo.getActiveNetworkInfo()
always seems to return CONNECTED even when I'm not connected, but that seems to be unrelated and I want to focus on the bigger problems.)
Here's my code:
[Reuse.logIt
is a method I use to print to logcat, and printToUI
to setText
on the display. As you can probably tell, I'm trying to give myself a lot of signposts to figure out what's going on.]
public void uploadFile(String filename, File theFile)
{
Reuse.logIt(TAG, "UploadFile did run."); // test that at least
FTPClient theClient = new FTPClient();
// It's probably insecure to do it this way, but first I just want to make it work.
final String theSite = [the name of my site];
String username = [my username];
String password = [my password];
// get network status
Context theContext = getApplicationContext();
ConnectivityManager cMgr = (ConnectivityManager)theContext.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo netInfo = cMgr.getActiveNetworkInfo();
String beginStatus = netInfo.getState().toString();
// always says CONNECTED whether we're connected or not.
String networkStatus = "Network status = "+beginStatus;
Reuse.logIt(TAG, networkStatus);
// pass the network status where it can be displayed in a different window's text.
Brouillon instance = (Brouillon) theContext;
instance.setDataResult(networkStatus);
if (beginStatus == "CONNECTED")
// If we don't have a network connection, don't upload the file.
{
try
{
theClient.connect(theSite);
// When login succeeds, the login method returns true.
boolean login = theClient.login(username, password);
if (login)
{
// success!
Reuse.logIt(TAG, "Logged in successfully to "+theSite+"!");
printToUI("ftp_connect", "Logged in successfully to "+theSite+"!");
Reuse.logIt(TAG, "The code does continue after logging in.");
// Now upload the file.
String ftpPath = "/brouillon/";
String filenameOnFTP = ftpPath+filename;
Reuse.logIt(TAG, "It defined the variables.");
FileInputStream fis = new FileInputStream(theFile);
Reuse.logIt(TAG, "It created the FileInputStream too.");
theClient.storeFile(filenameOnFTP, fis);
Reuse.logIt(TAG, "We created a file called "+filenameOnFTP+".");
printToUI("upload","We created a file called "+filenameOnFTP+".");
}
else
{
Reuse.logIt(TAG, "Could not connect to "+theSite+".");
printToUI("ftp_connect","Could not connect to "+theSite+".");
}
boolean logout = theClient.logout();
if (logout)
{
Reuse.logIt(TAG, "Logged out successfully.");
printToUI("loggedout","Logged out successfully.");
}
else
{
Reuse.logIt(TAG, "Logout failed!");
printToUI("loggedout","Logout failed!");
}
}
catch(IOException e)
{
e.printStackTrace();
Reuse.logIt(TAG, "Got error message "+e.toString()+".");
}
}
else
{
// For testing purposes, abort the program if not connected. Can change that later.
Reuse.logIt(TAG, "beginStatus was not CONNECTED!");
System.exit(0);
}
}
}
And here's my logcat. (Set on Error mode. If giving a more verbose mode would help, I'm happy to do that, but I'm leaving it out at first because it would make this post really long.)
03-29 13:08:13.400: E/SyncStatus(8764): Sync button pushed.
03-29 13:08:13.400: E/SyncStatus(8764): File created and closed.
03-29 13:08:13.400: E/SyncStatus(8764): UploadFile did run.
03-29 13:08:13.431: E/SyncStatus(8764): Network status = CONNECTED
03-29 13:08:14.556: E/SyncStatus(8764): Logged in successfully to [site name]!
03-29 13:08:14.556: E/SyncStatus(8764): The code does continue after logging in.
03-29 13:08:14.556: E/SyncStatus(8764): It defined the variables.
03-29 13:08:14.556: E/SyncStatus(8764): It created the FileInputStream too.
03-29 13:10:32.283: E/wpa_supplicant(452): android_priv_cmd: failed to issue private commands
03-29 13:11:28.603: E/SyncStatus(8764): We created a file called /brouillon/filename.txt.
03-29 13:11:28.705: E/SyncStatus(8764): Logged out successfully.
03-29 13:11:28.713: E/AndroidRuntime(8764): FATAL EXCEPTION: main
03-29 13:11:28.713: E/AndroidRuntime(8764): java.lang.NullPointerException
03-29 13:11:28.713: E/AndroidRuntime(8764): at com.loveofallwisdom.brouillon.SyncStatus$2.run(SyncStatus.java:174)
03-29 13:11:28.713: E/AndroidRuntime(8764): at android.os.Handler.handleCallback(Handler.java:725)
03-29 13:11:28.713: E/AndroidRuntime(8764): at android.os.Handler.dispatchMessage(Handler.java:92)
03-29 13:11:28.713: E/AndroidRuntime(8764): at android.os.Looper.loop(Looper.java:137)
03-29 13:11:28.713: E/AndroidRuntime(8764): at android.app.ActivityThread.main(ActivityThread.java:5041)
03-29 13:11:28.713: E/AndroidRuntime(8764): at java.lang.reflect.Method.invokeNative(Native Method)
03-29 13:11:28.713: E/AndroidRuntime(8764): at java.lang.reflect.Method.invoke(Method.java:511)
03-29 13:11:28.713: E/AndroidRuntime(8764): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793)
03-29 13:11:28.713: E/AndroidRuntime(8764): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560)
03-29 13:11:28.713: E/AndroidRuntime(8764): at dalvik.system.NativeStart.main(Native Method)
03-29 13:11:38.931: E/wpa_supplicant(452): android_priv_cmd: failed to issue private commands
回答1:
please try it to do in this way:
public static String uploadOrder(String fileName)
{
String m;
FTPClient con = null;
m = "Conn failed";
try
{
con = new FTPClient();
con.connect("xxx.xxx.210.176");
//username and password for ftp server
if (con.login("ftpxxx@xxxxx", "pass"))
{
con.enterLocalPassiveMode();//passive mode - IMPORTANT
con.setFileType(FTP.ASCII_FILE_TYPE);//only for txt file ACII mode, for rest binary mode
String data = Environment.getExternalStorageDirectory().getPath() +"/"+ fileName; //data location
FileInputStream in = new FileInputStream(data);
File f = new File(data);
con.changeWorkingDirectory("xxxxxx");//
if(con.changeWorkingDirectory("Orders"))//
{
Log.i("FTP","Got into directory");
}
if(!con.changeWorkingDirectory(MainPage.fb_id))//
{
in.close();
con.logout();
con.disconnect();
return m;
}
if(con.storeFile(fileName, in))
{
m = "Upload success!";
}
if(!f.exists()) m = "File not exists.";
in.close();
//logging out
con.logout();
con.disconnect();
}
else
{
m = "Unsuccessful";
}
}
catch (Exception e)
{
m = e.getMessage();
}
return m;
}
来源:https://stackoverflow.com/questions/15708147/ftpclient-storefile-uploads-slowly-and-then-doesnt-work