zoukankan      html  css  js  c++  java
  • Linux下中文文件名乱码问题的详解

    最近做的项目中,涉及Linux下生成中文文件名并压缩打包下载乱码问题,需要将生成的压缩包文件自定义重命名(包括中文),问题来了,Linux下不支持中文的,所以会导致中文乱码问题,网上找了几天,都没解决,现在终于给码出来了,希望大家指出缺点。

    首先,让linux支持中文,就是在/usr/lib/locale的默认中,添加以下三句,或者注释掉这三句前的#

    zh_CN.GBK GBK
            zh_CN.GB18030 GB18030
            zh_CN.UTF-8 UTF-8

        其次,由于下载的文件会把目录整个显示,之前转载别人的文章,使用了pathinfo函数去获取他的basename,就避免了目录结构被暴露,但是,下载的压缩包中,文件名都被置空,这纠结死我了,原来,文字编码中windows默认是GBK,而Linux默认是UTF-8,这样就导致输出的是乱码,乱码的文字被自动忽略。所以我重新写了一个pathinfo函数 path_info() 。

    分享自己的code:

    if($action == "downreport"){
        if(substr($report_ids,-1)==","){
            $report_ids = substr($report_ids,0,-1);
        }
        $report_id = $report_ids;
    if($report_id == '0'){
    die("{success:false,msg:'error',code:'e8000'}");
    }
        if(strpos($report_id,',')){
            $arrids = explode(',',$report_id);
            $newids = array();
            foreach($arrids as $id){
                $newids []= intval($id);
            }
            $ids = implodeids($newids);
            $reports = array();
            $reports_name = array();
            $paths = array();
            $query = $db->query("select `name`,filename from report_list where id in ($ids)");
            while($report = $db->fetch_array($query)){
                $reports[]= $report['filename'];
                $reports_name[]= $report['name'];
            }
            for($i = 0; $i < count($reports); $i++ ){
                $j = 1;
                $temp_fileName = $reports_name[$i]."_";
                while(file_exists(ESHINE_ROOT."tmp/temp/".$reports_name[$i] .".zip")){
                    $reports_name[$i] = $temp_fileName.$j;
                    $j++;
                }
                //$reports_name[$i] = $temp_fileName;
                copy(ESHINE_ROOT."Report/".$reports[$i].".zip",ESHINE_ROOT."tmp/temp/".$reports_name[$i].".zip");
                $paths[$i] = ESHINE_ROOT."tmp/temp/".$reports_name[$i].".zip";
            }
            //重写pathinfo函数,解决中文被置空 2014.11.26
            function path_info($filepath)
            {
                $path_parts = array();
                $path_parts ['dirname'] = rtrim(substr($filepath, 0, strrpos($filepath, '/')),"/")."/";
                $path_parts ['basename'] = ltrim(substr($filepath, strrpos($filepath, '/')),"/");
                $path_parts ['extension'] = substr(strrchr($filepath, '.'), 1);
                $path_parts ['filename'] = ltrim(substr($path_parts ['basename'], 0, strrpos($path_parts ['basename'], '.')),"/");
                return $path_parts;
            }
            //创建压缩包 2014.11.24
            function create_zip($files=array(),$destination='',$overwrite=false){
                //if the zip file already exists and overwrite is false, return false  
                //如果zip文件已经存在并且设置为不重写返回false  
                if(file_exists($destination) && !$overwrite){
                    return false;
                }
                $valid_files=array();
                //获取到真实有效的文件名  
                if(is_array($files)){
                //cycle through each file  
                    foreach($files as $file){
                        //make sure the file exists  
                        if(file_exists($file)){
                            $valid_files[]=$file;
                        }
                    }
                }
                //如果存在真实有效的文件  
                if(count($valid_files)){
                    //create the archive  
                    $zip = new ZipArchive();
                    //打开文件 如果文件已经存在则覆盖,如果没有则创建  
                    if($zip->open($destination,$overwrite?ZIPARCHIVE::OVERWRITE : ZIPARCHIVE::CREATE)!==true){
                        return false;
                    }
                    //向压缩文件add the files  
                    foreach($valid_files as $file){
                        //$zip->addFile($file,$file);
                        //$file_info_arr= pathinfo($file);
                        $file_info_arr =  path_info($file);
                        $filename = $file_info_arr['basename'];
                        $filename = iconv('UTF-8', 'GBK//IGNORE', $filename);
                        //die($filename);
                        $zip->addFile($file,$filename);
                    }
                    $zip->close();
                    //check to make sure the file exists  //检测文件是否存在  
                    return file_exists($destination);
                }else{
                    return false;
                }
            }
            if(create_zip($paths,ESHINE_ROOT."tmp/temp/".$tempFileName.".zip",true)){
                $newfiles =  ESHINE_ROOT."tmp/temp/".$tempFileName.".zip";
            }
            //sleep(1);
            $tempFileName = date("YmdHis",time()).mt_rand(1000, 9999);
            for($i = 0; $i < count($paths); $i++ ){
                @unlink($paths[$i]);
            }
            if(!$newfiles){
                echo 'Not Found' . $newfiles;
                exit;
            }else{
                header("Content-type: application/octet-stream");
                //header("Content-type: application/force-download");
                header("Accept-Ranges: bytes");
                header("Accept-Length: ".filesize($newfiles));
                header("Content-Disposition: attachment; filename=".$tempFileName.".zip");
                //header('Content-Type: application/octet-stream; name=' . $out_filename);
                touch($newfiles);
                $file = fopen($newfiles, "r");
                //echo fread($file, filesize($newfiles));
                $buffer = 1024; //
                //判断文件是否读完
                while (!feof($file)) {
                    //将文件读入内存
                    $file_data = fread($file, $buffer);
                    //每次向客户端回送1024个字节的数据
                    echo $file_data;
                }
                fclose($file);
                unlink($newfiles);
                writelog($msg_download_log_reportlist.$newfiles);
            }
        } 
    }
    


    版权声明:本文为博主原创文章,未经博主允许不得转载。

  • 相关阅读:
    乐视电视修改五大图标
    Google Home Mini配置失败解决办法
    使用FreeHttp任意篡改http报文 (FreeHttp使用及实现说明)
    IDEA和VS快捷键对比
    C# 中的字符串内插
    在线运行.NET代码
    在Windows服务器安装ss服务端用于逃脱公司行为管理
    .NET Core的代码安全分析工具
    用DotNetDetour HOOK .net类库
    C#代码获取另一程序的错误提示,并关闭窗口。
  • 原文地址:https://www.cnblogs.com/sunscheung/p/4839427.html
Copyright © 2011-2022 走看看