You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.01 03:02:46