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);
        }
    } 
}


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

原文地址:https://www.cnblogs.com/sunscheung/p/4839427.html