http://topic.csdn.net/u/20120705/11/4b20d635-cfe0-4c12-8384-2a7d17e22cad.html?56443
上午发的帖子没人回,自己不能再回复了,就再发一个,大家去看看,两边都给分,就是想解决问题呀!

解决方案 »

  1.   

    你代码中的128是什么意思,可能就是它引起你array的copy丢失字符后(长度不对),产生了非法字符,而且你截取字节,太生硬了,c#是unicode编码,如果你是奇数个字节,那就会有乱码了
      

  2.   

    根据你的需求,我写了个校验方法,调试过,你试试:       //传入校验前字符数组,及返回数组的最大长度,返回校验后不包含不完整字符的字符数组
            Byte[] GetCheckedArr(Byte[] btArr, int iMaxLen)
            {           
                if (iMaxLen >= btArr.Length || iMaxLen <= 0 || btArr == null)
                {
                    return btArr;
                }                        //定义一个bool类型,指示字符是否完整
                Boolean isComplete = true;            for (int i = 0; i < iMaxLen; i++)
                {
                    //判断是否为汉字
                    if (btArr[i] > 127)
                    {
                        isComplete = !isComplete;
                    }
                }            if (!isComplete)
                {
                    --iMaxLen;
                }            if (iMaxLen == 0)
                {
                    return null;
                }            Byte[] btReturn = new Byte[iMaxLen];            Array.Copy(btArr, 0, btReturn, 0, iMaxLen);            return btReturn;
            }
    调用示例:
    String sTmp     = "是否是汉字,ABC";
    Byte[] btTmp    = Encoding.Default.GetBytes(sTmp);
    Byte[] btResult = GetCheckedArr(btTmp, 3);
      

  3.   

    谢谢  可是我这边的情况是文件名里不只是汉字,还有各种文件名中允许出现的ASCII码,下面是我写的程序,大家看下:string path = f;
                            string newpath = path;
                            string fullname = Path.GetFileName(path);//返回文件名和后缀名
                            string name = Path.GetFileNameWithoutExtension(path);//返回文件名
                            string extn = Path.GetExtension(path);//返回后缀名
                            byte[] Bytes = System.Text.Encoding.Default.GetBytes(fullname);//获得文件名+后缀名的字节数组
                            byte[] nameBytes = System.Text.Encoding.Default.GetBytes(name);//获得文件名的字节数组
                            byte[] extnBytes = System.Text.Encoding.Default.GetBytes(extn);//获得后缀名的字节数组
                            string newname = fullname;//新(文件名+后缀名)
                            while (Bytes.Length > 128)
                            {
                                Common.ImportDllCom.SetProfile(Utils.LogName, "log", fullname + "(" + DateTime.Now.ToString("yyyyMMddHHmmss") + ")", "文件名长度超限");
                                int cutCount = Bytes.Length - 128;
                                int initialCopyCount = nameBytes.Length - cutCount;
                                int finalCopyCount;
                                                            //排除误截汉字编码的可能
                                if (nameBytes[initialCopyCount - 1] > 127)
                                {
                                    if (nameBytes[initialCopyCount - 2] > 127)
                                    {
                                        finalCopyCount = initialCopyCount;
                                    }
                                    else
                                    {
                                        finalCopyCount = initialCopyCount - 1;
                                        cutCount = cutCount + 1;
                                    }
                                }
                                else 
                                    finalCopyCount = initialCopyCount;
                                
                                ArrayList al = new ArrayList();
                                al.InsertRange(0, nameBytes);//这里是将文件名部分完全添加到ArrayList中
                                al.RemoveRange(finalCopyCount, cutCount);//根据需要截取的长度,删除ArrayList中多余的元素
                                al.InsertRange(finalCopyCount, extnBytes);//将后缀名部分添加到ArrayList的最后
                                byte[] newNameBytes = new byte[al.Count];//根据ArrayList中的元素数目新建字节数组
                                al.CopyTo(newNameBytes);//将ArrayList中的所有元素复制到新文件名的字节数组中
                                newname = System.Text.Encoding.Default.GetString(newNameBytes);//将新文件名的字节数组编码成字符串
                                byte[] test = System.Text.Encoding.Default.GetBytes(newname);                            newpath = Path.GetDirectoryName(path).TrimEnd('\\') + "\\" + newname;
                                break;
                            }
                            File.Move(path, newpath);//改文件名
    调试结果是通的,结果被我们测试人员又给测出毛病来了
    原来我那个防误删的模块忘了考虑前面连续是汉字的情况,只考虑了前面是ASCII码的情况,这样的话,如果最后一个字节刚好截的是一个汉字的前半个字节,那就又乱码了。现在我想了个方法,能不能判断下:当最后一个字节>127,它的前边也>127时,判断它后面连续的非ASCII码的个数,如果是奇数个,那就删掉它,如果是偶数个,那就保留它。
    大家有没有具体的可以调用的函数?就是GetCount之类的,不过要加判断条件,我实在是新手,储备量太少,找不到函数
      

  4.   

    [Quote=引用 7 楼  的回复:
    调试结果是通的,结果被我们测试人员又给测出毛病来了
    原来我那个防误删的模块忘了考虑前面连续是汉字的情况,只考虑了前面是ASCII码的情况,这样的话,如果最后一个字节刚好截的是一个汉字的前半个字节,那就又乱码了。现在我想了个方法,能不能判断下:当最后一个字节>127,它的前边也>127时,判断它后面连续的非ASCII码的字节的个数,如果是奇数个,那就删掉它,如果是偶数个,那就保留它。
    最重要是红色的那两个条件,怎么实现[/Quote]
      

  5.   

    这是最后调试成功的代码:string path = f;
    string newpath = path;
    string fullname = Path.GetFileName(path);//返回文件名和后缀名
    string name = Path.GetFileNameWithoutExtension(path);//返回文件名
    string extn = Path.GetExtension(path);//返回后缀名
    byte[] Bytes = System.Text.Encoding.Default.GetBytes(fullname);//获得文件名+后缀名的字节数组
    byte[] nameBytes = System.Text.Encoding.Default.GetBytes(name);//获得文件名的字节数组
    byte[] extnBytes = System.Text.Encoding.Default.GetBytes(extn);//获得后缀名的字节数组
    string newname = fullname;//新(文件名+后缀名)
    while (Bytes.Length > 128)
    {
       int cutCount = Bytes.Length - 128;
       int initialCopyCount = nameBytes.Length - cutCount;
       int finalCopyCount;
       int notAsciiBytesNumber = 0;   for (int i = initialCopyCount; i < nameBytes.Length; i++)
       {
          if (nameBytes[i] > 127)
             notAsciiBytesNumber++;
          else
             break;
       }

       //排除误截汉字编码的可能
        if (nameBytes[initialCopyCount - 1] > 127)
        {
            if (nameBytes[initialCopyCount - 2] > 127)
                {
                    if (notAsciiBytesNumber % 2 == 0)
                        {
                            finalCopyCount = initialCopyCount;
                        }
                    else
                        {
                            finalCopyCount = initialCopyCount - 1;
                            cutCount = cutCount + 1;
                        }
                }
            else
                {
                    finalCopyCount = initialCopyCount - 1;
                    cutCount = cutCount + 1;
                }
        }
        else
            finalCopyCount = initialCopyCount;
                                
        ArrayList al = new ArrayList();
        al.InsertRange(0, nameBytes);//这里是将文件名部分完全添加到ArrayList中
         al.RemoveRange(finalCopyCount, cutCount);//根据需要截取的长度,删除ArrayList中多余的元素
         al.InsertRange(finalCopyCount, extnBytes);//将后缀名部分添加到ArrayList的最后
         byte[] newNameBytes = new byte[al.Count];//根据ArrayList中的元素数目新建字节数组
         al.CopyTo(newNameBytes);//将ArrayList中的所有元素复制到新文件名的字节数组中
         newname = System.Text.Encoding.Default.GetString(newNameBytes);//将新文件名的字节数组编码成字符串     newpath = Path.GetDirectoryName(path).TrimEnd('\\') + "\\" + newname;
         break;
        }
      File.Move(path, newpath);//改文件名