大家来支招吧!C# 字节编码成字符串 http://topic.csdn.net/u/20120705/11/4b20d635-cfe0-4c12-8384-2a7d17e22cad.html?56443上午发的帖子没人回,自己不能再回复了,就再发一个,大家去看看,两边都给分,就是想解决问题呀! 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 你代码中的128是什么意思,可能就是它引起你array的copy丢失字符后(长度不对),产生了非法字符,而且你截取字节,太生硬了,c#是unicode编码,如果你是奇数个字节,那就会有乱码了 根据你的需求,我写了个校验方法,调试过,你试试: //传入校验前字符数组,及返回数组的最大长度,返回校验后不包含不完整字符的字符数组 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); 谢谢 可是我这边的情况是文件名里不只是汉字,还有各种文件名中允许出现的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之类的,不过要加判断条件,我实在是新手,储备量太少,找不到函数 [Quote=引用 7 楼 的回复:调试结果是通的,结果被我们测试人员又给测出毛病来了原来我那个防误删的模块忘了考虑前面连续是汉字的情况,只考虑了前面是ASCII码的情况,这样的话,如果最后一个字节刚好截的是一个汉字的前半个字节,那就又乱码了。现在我想了个方法,能不能判断下:当最后一个字节>127,它的前边也>127时,判断它后面连续的非ASCII码的字节的个数,如果是奇数个,那就删掉它,如果是偶数个,那就保留它。最重要是红色的那两个条件,怎么实现[/Quote] 这是最后调试成功的代码: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);//改文件名 [急]请教校内网写日志问题。。 怎样过滤List或者ComboBox中相同的选项?在线等! C#调用VB6.0的dll 如何将水晶报表的纸张大小设置永久保存至SQL数据库? 按照数字排序 int类型的结果如何在其后面追加小数显示位数? 用C#如何将excel照相机功能抓取的图片读到pictruebox中去? 想把C#程序打包安装程序 C#简单数组遍历 急!谁有c#实现的论坛网页源代码?(asp) 这个Top控件为什么老报错???救救 日志文件的生成问题-log4net
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);
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之类的,不过要加判断条件,我实在是新手,储备量太少,找不到函数
调试结果是通的,结果被我们测试人员又给测出毛病来了
原来我那个防误删的模块忘了考虑前面连续是汉字的情况,只考虑了前面是ASCII码的情况,这样的话,如果最后一个字节刚好截的是一个汉字的前半个字节,那就又乱码了。现在我想了个方法,能不能判断下:当最后一个字节>127,它的前边也>127时,判断它后面连续的非ASCII码的字节的个数,如果是奇数个,那就删掉它,如果是偶数个,那就保留它。
最重要是红色的那两个条件,怎么实现[/Quote]
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);//改文件名