使用Apache Commons连接FTP报错:Android应用上传文件遇553权限拒绝
Hey there, I’ve run into this exact error a few times when working with FTP uploads on Android, so let’s walk through the most likely fixes step by step. That 553 error almost always boils down to either server-side permissions, local file access issues, or missing FTP client configurations.
1. First: Rule Out FTP Server-Side Permissions
This is the #1 culprit. Before digging into your Android code, verify the basics on the server:
- Check the target directory’s write permissions: The FTP user you’re logging in with needs explicit write access to the remote directory. On Linux-based servers, use
ls -lto check the directory’s owner/group and permissions. You might need to runchmod 755 /path/to/remote/dir(or 775 if group access is needed) orchown ftpuser:ftpgroup /path/to/remote/dirto set the correct ownership. - Test with a desktop FTP client: Fire up FileZilla or WinSCP, log in with the same credentials, and try uploading a file to the exact same remote path. If this fails too, the problem is definitely on the server side—reach out to your hosting provider or server admin to fix permissions.
2. Verify Local File Access on Android
Even though you’re using internal storage, there are a few things to check:
- Confirm the local file exists and is readable: Add checks in your code to ensure the file isn’t missing or locked:
File localFile = new File(getFilesDir(), "your-target-file.ext"); if (!localFile.exists()) { Log.e("FTP_UPLOAD", "Local file not found!"); return; } if (!localFile.canRead()) { Log.e("FTP_UPLOAD", "No read permission for local file!"); return; } - Scoped Storage considerations (Android 10+): If you’re accessing files outside your app’s private internal storage (like shared media), you’ll need the appropriate runtime permissions (e.g.,
READ_MEDIA_IMAGESfor Android 13+). But for files stored ingetFilesDir()orgetCacheDir(), your app has full access by default—no extra permissions needed.
3. Fix Apache Commons FTP Client Configurations
Missing these two critical settings is a super common mistake:
- Enable Passive Mode: Android devices are almost always behind firewalls/NAT, so active FTP mode will fail. Add this line right after logging in:
ftpClient.enterLocalPassiveMode(); - Set Correct File Type: If you’re uploading non-text files (images, binaries), using the default text mode can corrupt files and trigger permission-like errors. Set the file type to binary:
ftpClient.setFileType(FTP.BINARY_FILE_TYPE);
4. Double-Check Remote File Paths
Sometimes the error is just a typo in the remote path:
- Make sure the remote directory actually exists on the server. If it doesn’t, create it first with
ftpClient.makeDirectory("/path/to/remote/dir"); - Avoid special characters (spaces, accented letters, symbols) in the remote filename—some FTP servers struggle with these. Test with a simple filename like
test.txtfirst.
Working Example Code
Here’s a cleaned-up snippet that incorporates all the fixes above:
FTPClient ftpClient = new FTPClient(); try { // Connect and login ftpClient.connect("your-ftp-server-url", 21); boolean loginSuccess = ftpClient.login("your-username", "your-password"); if (!loginSuccess) { Log.e("FTP", "Login failed: " + ftpClient.getReplyString()); return; } // Critical configurations ftpClient.enterLocalPassiveMode(); ftpClient.setFileType(FTP.BINARY_FILE_TYPE); // Prepare local file (internal storage) File localFile = new File(getFilesDir(), "sample-image.jpg"); if (!localFile.exists() || !localFile.canRead()) { Log.e("FTP", "Local file issue: " + localFile.getAbsolutePath()); return; } // Upload the file try (InputStream inputStream = new FileInputStream(localFile)) { boolean uploadSuccess = ftpClient.storeFile("/remote-uploads/sample-image.jpg", inputStream); if (uploadSuccess) { Log.i("FTP", "File uploaded successfully!"); } else { Log.e("FTP", "Upload failed: " + ftpClient.getReplyString()); } } // Cleanup ftpClient.logout(); } catch (IOException e) { e.printStackTrace(); } finally { if (ftpClient.isConnected()) { try { ftpClient.disconnect(); } catch (IOException e) { e.printStackTrace(); } } }
Start with the server-side check first—it’ll save you a ton of time. If the desktop FTP client works, then move to adjusting your Android code with the passive mode and file type settings.
内容的提问来源于stack exchange,提问作者danial iranpour

