安卓客户端和php服务端传输包含中文文件名的文件

使用httpURLConnection可以在安卓客户端和php服务端进行文件传输。当待传输的文件名中包含中文时,会导致上传失败。如待传输的文件名为 中文.txt 。 传输失败的原因是由文件名的编码问题造成的,先贴出代码。

安卓客户端使用httpURLConnection上传文件:

public void mypostfile(File path) throws FileNotFoundException, IOException {       
    String end = "\r\n";
        String twoHyphens = "--";
        String boundary = "******";

        URL url=new URL("localhost/savefile.php");      
        HttpURLConnection httpURLConnection = (HttpURLConnection) url
                .openConnection();
        httpURLConnection.setChunkedStreamingMode(128 * 1024);// 128K
        // 允许输入输出流
        httpURLConnection.setDoInput(true);
        httpURLConnection.setDoOutput(true);
        httpURLConnection.setUseCaches(false);      

        // 使用POST方法
        httpURLConnection.setRequestMethod("POST");                 
        httpURLConnection.setRequestProperty("Connection", "Keep-Alive");
        httpURLConnection.setRequestProperty("Charset", "UTF-8");
        httpURLConnection.setRequestProperty("Content-Type",
                "multipart/form-data;boundary=" + boundary);    
        httpURLConnection.addRequestProperty("token", "heheda");

        /************
        这里获取到文件名filename,filename中包含中文会传输失败,
        因此先对filename进行utf-8编码,在服务端对接收到的filename进行解码
        *********/
        String filename=path.getName();         
        filename=URLEncoder.encode(filename,"UTF-8");

        try{
            DataOutputStream dos = new DataOutputStream(
                    httpURLConnection.getOutputStream());
            dos.writeBytes(twoHyphens + boundary + end);
            dos.writeBytes("Content-Disposition: form-data; name=\"uploadfile\"; filename=\""
                    + filename + "\"" + end);           
            dos.writeBytes(end);
            FileInputStream fis = new FileInputStream(path);

            byte[] buffer = new byte[8192];
            int count = 0;

            // 读取文件
            while ((count = fis.read(buffer)) != -1) {
                dos.write(buffer, 0, count);
            }
            fis.close();
            dos.writeBytes(end);
            dos.writeBytes(twoHyphens + boundary + twoHyphens + end);
            dos.flush();

            InputStream is = httpURLConnection.getInputStream();
            InputStreamReader isr = new InputStreamReader(is, "utf-8");
            BufferedReader br = new BufferedReader(isr);
            String result = br.readLine();          
            System.out.println(result);         
            dos.close();
            is.close();
        }catch(Exception e){
            e.printStackTrace();            
            System.out.print("failed");
        }
}

PHP服务端接受文件代码

<?php
    $filepath="E:/server/";
    if(!file_exists($filepath)){
        mkdir($filepath);
    }

    $filename=$_FILES['uploadfile']['name'];
    /*对接收到的文件名进行解码*/
    $filename=urldecode($filename);
    /*解码后的filename是UTF-8格式,直接存储的话会导致保存在本地的文件名是乱码,需转换为GBK格式存储,*/
    $savepath=$filepath.iconv("UTF-8","GBK",$filename);
    move_uploaded_file($_FILES['uploadfile']['tmp_name'],$savepath) or
        die('uploaded failed');
    echo "The file ".$filename." has been uploaded----";
?>

在安卓端上传的文件名filenamel中包含中文时,在传输前先对其进行utf-8编码

String filename=path.getName();         
filename=URLEncoder.encode(filename,"UTF-8");

在服务端接到文件之后,获取到的文件名

$filename=$_FILES['uploadfile']['name'];

进行解码

$filename=urldecode($filename);
$savepath=$filepath.iconv("UTF-8","GBK",$filename);

$filename是UTF-8格式,直接使用会导致本地生成的文件名乱码,因此需要使用iconv将其转换成GBK格式。

php读取windows本地文件时,文件名中包含中文也会出现找不到文件的错误。如下面代码中:

<?php
    $file="E:/中文.txt";
    readfile($file);
?>

运行结果为:
这里写图片描述
原因也是$filename是UTF-8编码,而本地中文文件名使用的是GBK编码,使用iconv进行转码即可。

<?php
    $file="E:/中文.txt";
    $file=iconv("UTF-8","GBK",$file);
    readfile($file);
?>

在读取文件时,如果遇到读取到的某行记录出现乱码,该行记录可能包含GBK编码格式的中文,将其转为UTF-8格式即可。
如果不知道编码格式,可以用mb_detect_encoding函数查看。

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值