C# 字节编码回退

lisa9342 2012-07-05 11:33:47
日志记录:

错误(20120705)=System.ArgumentException: 路径中具有非法字符。
在 System.Security.Permissions.FileIOPermission.HasIllegalCharacters(String[] str)
在 System.Security.Permissions.FileIOPermission.AddPathList(FileIOPermissionAccess access, AccessControlActions control, String[] pathListOrig, Boolean checkForDuplicates, Boolean needFullPath, Boolean copyPathList)
在 System.Security.Permissions.FileIOPermission..ctor(FileIOPermissionAccess access, String[] pathList, Boolean checkForDuplicates, Boolean needFullPath)
在 System.IO.File.Move(String sourceFileName, String destFileName)
在 SendEpg.Form1.SendFile()


调试:
http://my.csdn.net/uploads/201207/05/1341459319_4254.jpg
不知道图片能不能显示,我在说明一下:就是到了要截取的最后的那个字节,它是一半的汉字,所以被默认替换回退成“?”,但是这个问号被视为非法字符,不能处理



我是想,可不可以有个检查机制,看看最后一个字节是可以编码成一个完整字符还是不能,如果不能的话,就把最后一个字节给删掉,只编码前面的字节

foreach (string f in files)
{
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;
byte[] newNameBytes = new byte[128];
Array.Copy(nameBytes, 0, newNameBytes, 0, nameBytes.Length - cutCount);//将文件名部分截取指定字节拷贝到新文件名数组
Array.Copy(extnBytes, 0, newNameBytes, nameBytes.Length - cutCount, extn.Length);//将后缀名部分拷贝到新文件名数组
newname = System.Text.Encoding.Default.GetString(newNameBytes);//将新文件名数组编码成字符串 就是这里 newpath = Path.GetDirectoryName(path).TrimEnd('\\') + "\\" + newname;
break;
}
try
{
File.Move(path, newpath);//改文件名
}
catch { }
...全文
205 8 打赏 收藏 转发到动态 举报
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
lisa9342 2012-07-09
  • 打赏
  • 举报
回复
这是最后调试成功的代码:


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);//改文件名



谢谢大家!
lisa9342 2012-07-05
  • 打赏
  • 举报
回复
不要沉啊 帮帮忙啦
lisa9342 2012-07-05
  • 打赏
  • 举报
回复
别沉别沉呀!大家看得见不?如果我没表述清楚请提问,谢谢了!帮忙看看
lisa9342 2012-07-05
  • 打赏
  • 举报
回复
这是图片
popo0762 2012-07-05
  • 打赏
  • 举报
回复
补充说明,以上方法,只适用于假设你前面的字符都是完整的,而最后一个字符不确定是否完整的情况。
cuiwenjun57 2012-07-05
  • 打赏
  • 举报
回复
先获取异常吧,我是来顶贴的
popo0762 2012-07-05
  • 打赏
  • 举报
回复
根据你的需求,我写了个校验方法,调试过,你试试:

//传入校验前字符数组,及返回数组的最大长度,返回校验后不包含不完整字符的字符数组
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);
熙风 2012-07-05
  • 打赏
  • 举报
回复
try Catch 捕获异常

110,502

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧