Android应用通过FTP上传用户头像报错:No such file or directory问题排查求助
问题分析
兄弟,你踩了一个很典型的「跨设备路径认知」坑——Android设备上的/storage/emulated/0/Download/red-bull-2384130__480.png是你手机本地的存储路径,但你的PHP服务器运行在远程主机上,它根本没法访问你手机里的文件啊!就像你不能把自己电脑的C盘路径发给同事,让他直接打开你电脑里的文件一样,所以ftp_put才会报「找不到文件或目录」的错。
正确的实现方案
要完成头像上传,正确的流程是:Android端把图片的二进制数据直接传到PHP服务器,PHP接收到文件后,再通过FTP把它传到目标服务器。下面是具体的修改步骤:
1. PHP端代码修改(接收上传文件+FTP上传)
替换你现有的uploadfile.php,改成支持接收文件上传的版本:
<?php $ftp_server = "ftp......."; $ftp_user_name = "......"; $ftp_user_pass = "......."; $Random_str = uniqid(); $remote_file = $Random_str . ".jpg"; // 先处理Android上传的文件 if (!isset($_FILES['avatar'])) { echo "请上传图片文件"; exit; } $local_temp_file = $_FILES['avatar']['tmp_name']; // 检查临时文件是否有效 if (!file_exists($local_temp_file)) { echo "上传的文件无效"; exit; } // 连接FTP服务器 $conn_id = ftp_connect($ftp_server); if (!$conn_id) { echo "无法连接FTP服务器"; exit; } // 登录FTP $login_result = ftp_login($conn_id, $ftp_user_name, $ftp_user_pass); if (!$login_result) { echo "FTP登录失败"; ftp_close($conn_id); exit; } // 重点:图片是二进制文件,必须用FTP_BINARY模式上传,别用ASCII! if (ftp_put($conn_id, $remote_file, $local_temp_file, FTP_BINARY)) { echo "头像上传成功,文件名:$remote_file"; } else { echo "FTP上传失败"; } // 关闭连接 ftp_close($conn_id); ?>
2. Android端代码修改(上传文件而非路径)
你需要在Android端把图片以Multipart/form-data的形式POST到PHP接口,而不是只传字符串路径。这里给你一个用OkHttp的示例(如果用其他网络框架思路类似):
// 假设你已经拿到了要上传的图片File对象 File avatarFile = new File("/storage/emulated/0/Download/red-bull-2384130__480.png"); OkHttpClient client = new OkHttpClient(); // 构建表单上传请求 RequestBody requestBody = new MultipartBody.Builder() .setType(MultipartBody.FORM) .addFormDataPart("avatar", avatarFile.getName(), RequestBody.create(MediaType.parse("image/png"), avatarFile)) .build(); Request request = new Request.Builder() .url("https://你的服务器域名/mobilapp/uploadfile.php") .post(requestBody) .build(); // 异步上传 client.newCall(request).enqueue(new Callback() { @Override public void onFailure(Call call, IOException e) { // 处理上传失败逻辑 e.printStackTrace(); } @Override public void onResponse(Call call, Response response) throws IOException { if (response.isSuccessful()) { String serverResult = response.body().string(); // 处理服务器返回的结果,比如获取生成的文件名 } } });
额外注意事项
- 权限问题:Android端需要申请文件读取权限(比如
READ_EXTERNAL_STORAGE,Android 13+可能需要更细分的媒体权限),否则没法读取本地图片。 - 传输模式:原代码用了
FTP_ASCII,这会导致图片损坏——文本文件用ASCII,二进制文件(图片、视频)必须用FTP_BINARY。 - 临时文件:PHP接收的文件会存在服务器的临时目录,
ftp_put用完后PHP会自动清理,不用额外手动删除。
内容的提问来源于stack exchange,提问作者wiz 2021
相关产品推荐
相关产品推荐

