通过 POST 请求方法将文本文件上传到具有 PHP 脚本的服务器,上传文件中的 Unicode 字符存在问题

Upload a text file through POST request method to a server with PHP script has issue with Unicode characters in the uploaded file

提问人:AndroidPlayer2 提问时间:10/4/2020 更新时间:10/4/2020 访问量:123

问:

在 Android 应用程序中,

我使用以下代码将带有请求方法的 txt 文件上传到服务器:POST

    public static String ServiceCall_TextCommand(String mFileName, String mFileDestination, String mFileData) 
    {
        int serverResponseCode = 0;
        String fileName = mFileName;

        String upLoadServerUri = null;
        /************* Php script path ****************/
        upLoadServerUri = mFileDestination;

        HttpURLConnection conn = null;
        DataOutputStream dos = null;
        String lineEnd = "\r\n";
        String twoHyphens = "--";
        String boundary = "*****";
        int bytesRead, bytesAvailable, bufferSize;
        byte[] buffer;
        int maxBufferSize = 5 * 1024 * 1024;

        try {
            URL url = new URL(upLoadServerUri);

            // Open a HTTP  connection to  the URL
            conn = (HttpURLConnection) url.openConnection();
            conn.setDoInput(true); // Allow Inputs
            conn.setDoOutput(true); // Allow Outputs
            conn.setUseCaches(false); // Don't use a Cached Copy
            conn.setRequestMethod("POST");
            conn.setRequestProperty("Connection", "Keep-Alive");
            conn.setRequestProperty("ENCTYPE", "multipart/form-data");
            conn.setRequestProperty("Content-Type", "multipart/form-data;boundary=" + boundary);
            conn.setRequestProperty("uploaded_file", fileName);

            dos = new DataOutputStream(conn.getOutputStream());
            dos.writeBytes(twoHyphens + boundary + lineEnd);

            dos.writeBytes("Content-Disposition: form-data; name=\"uploaded_file\"; filename=\""
                    + fileName + "\"" + lineEnd);


            dos.writeBytes(lineEnd);

            bufferSize = mFileData.length();
            buffer = mFileData.getBytes(Charset.forName("UTF-8"));

            dos.write(buffer, 0, bufferSize);
            dos.writeBytes(lineEnd);
            dos.writeBytes(twoHyphens + boundary + twoHyphens + lineEnd);

            // Responses from the server (code and message)
            serverResponseCode = conn.getResponseCode();
            String serverResponseMessage = conn.getResponseMessage();

            Log.i("BBBuploadFile", "HTTP Response is : "
                    + serverResponseMessage + ": " + serverResponseCode);

            if (serverResponseCode == 200) {

                Log.e(TAG, "Complete");
            }
            else
            {
                return  Constants.ServerResponse_Error_General;
            }

            BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream()));
            StringBuilder total = new StringBuilder();
            String line;
            while ((line = in.readLine()) != null)
            {
                total.append(line).append('\n');
            }

            dos.flush();
            dos.close();

            // Verify Command Response Checksum
            String mServerResponse = total.toString();
            mServerResponse = getStringBetween(mServerResponse,"@#@","#@#");
  
            return mServerResponse;

        } catch (MalformedURLException ex) {

            ex.printStackTrace();
            Log.e("Upload file to server", "error: " + ex.getMessage(), ex);
            return Constants.ServerResponse_Error_General;
        } catch (Exception e) {
            e.printStackTrace();
            Log.e(TAG, "111Exception: " + e.getMessage());
            return Constants.ServerResponse_Error_General;
        }
    }

服务端PHP代码如下:

<?php
    
    header('Content-type: text/plain');
    
    require_once $ServerRoot.'/HandleUploadedFile/HandleUploadedFile.php';
    use HandleUploadedFile\HandleUploadedFile_Status;   
    
    print "\nFile Received, Root: {$_SERVER['DOCUMENT_ROOT']}\nName: {$_FILES['uploaded_file']['name']}\nSize: {$_FILES['uploaded_file']['size']}";
    echo "\nprint_r:\n";
    print_r($_FILES);

    $mClass_HandleUploadedFile_Status = new HandleUploadedFile_Status();
    if ($mClass_HandleUploadedFile_Status->IsUploadedFileValid() === true)
    {
        echo "\File is valid\n"; 
        echo "\nupload successful";
        
        $File_Name = $_FILES['uploaded_file']['name'];
        $File_SplitName = explode(".", $File_Name);
        $File_Name_NoExtension = $File_SplitName[0];
        $File_Extension = end($File_SplitName);

        $ReadFile_Resource = fopen($_FILES['uploaded_file']['tmp_name'], "r");
        $ReadFile = fread($ReadFile_Resource, filesize($_FILES['uploaded_file']['tmp_name']));
        

        $fz = filesize($_FILES['uploaded_file']['tmp_name']);
        echo "\n*#*\nfz :\n{$fz}\n#*###\n";
        
        echo "\n\nReadFile :\n{$ReadFile}\n\n";
        
        fclose($ReadFile_Resource);        
    }

<?php
    namespace HandleUploadedFile;
    class HandleUploadedFile_Status
    {
        public function IsUploadedFileValid()
        {
            if($this->UploadedFileExists() === true)
            {
                if($this->UploadedFileKeyArrayExists() === true)
                {
                    if($this->UploadedFileIsErrorOk() === true)
                    {
                        return true;
                    }
                    else 
                    {
                        return false;
                    }      
                }
                else 
                {
                    return false;
                }                
            }
            else 
            {
                return false;
            }
        }
        
        public function UploadedFileExists()
        {
            if(isset($_FILES["uploaded_file"]))
            {
                return true;
            }
            else 
            {
                return false;
            }
        }

        public function UploadedFileKeyArrayExists()
        {
            if(array_key_exists('uploaded_file', $_FILES))
            {
                return true;
            }
            else 
            {
                return false;
            }
        }

        public function UploadedFileIsErrorOk()
        {
            if($_FILES['uploaded_file']['error'] === UPLOAD_ERR_OK)
            {
                return true;
            }
            else 
            {
                return false;
            }
        }        
    }

从Android应用程序上传的mFileData如下:

ED1235bkoala02PKKKKKKaKKKKKKKKbzG^{"P":[{"a":"0f","b":"01q","c":"X","d":"Y"}]}^A

由于上述数据中没有Unicode字母,因此没有问题,一切都很好

问题:

当我添加一个Unicode字母而不是,那么PHP中不包含最后一个字母:"و""X"$ReadFile(A)

ED1235bkoala02PKKKKKKaKKKKKKKKbzG^{"P":[{"a":"0f","b":"01q","c":"و","d":"Y"}]}^A

换句话说,
似乎因为 of 是 2 个字节,那么 PHP 误解并只计算 1 个字符,因此最后一个字符不会用上面的代码读取
UTF-8"و"(A)

同样,如果我替换为最后 2 个字符,这次不会读取,依此类推"و""وک"(^A)

这绝对与编码有关,但即使我从 Android 应用程序发送,我也无法在 PHP 代码中获取真实数据UTF-8UTF-8

php android 帖子 UTF-8

评论

0赞 blackapps 10/4/2020
您上传的不是 txt 文件,而是 String mFileData。完全不同的东西。
0赞 blackapps 10/4/2020
如果要上传文件,请不要先将内容放在字符串中。您应该以这样一种方式编写代码,以便您也可以使用相同的代码上传图像。或 pdf。因为文件就是文件。一些字节。一个代码适合所有人。
0赞 AndroidPlayer2 10/4/2020
我也编写了上传图像的代码,但问题是您提到的字符串中的Unicode问题
0赞 blackapps 10/4/2020
您正在上传字符串。好吧,我已经说过了。不要使用字符串将文件放在第一位。仅上传文件的字节数。

答: 暂无答案