路径中有非法字符导致FTP异常

仓鼠症晚期 硬盘总是有无数的资源

这么多资源的整理总是令人头痛

特别是各种五花八门的命名方式 简直是要踩在Windows Linux 的目录非法字符上跳舞

遇到的问题

首先 Windows 上有个 文件夹末尾不能有空格的问题

在资源管理器上访问 末尾带空格的文件夹时 可以正常访问

但是 FTP 访问报没有权限

详细问题百度 文件夹后面有带有空格无法删除

我自己的文件夹末尾带空格 是由于自己写的一个bat

1
2
3
4
5
6
@echo off
for %%i in (*.avi,*.mov,*.mpg,*.RA,*.RM,*.RMVB,*.WMV,*.mkv,*.mp4,*.asf,*.m4v,*.VOB,*.ts) do (
md "%~dp0\%%~ni\"
move "%%i" "%~dp0\%%~ni\"
)
pause

用来处理某些下载下来就没有文件夹的视频文件

由于部分视频文件有xxx空格.mp4

根据文件名创建出来的文件夹就有了空格导致路径错误

可以删除但是不能重命名

在命令提示符下,进入相对路径,输入:rd /s /q “文件夹名 \“

必须删除前复制文件到新路径 然后删除旧目录 再重命名新路径

太麻烦了 百度 谷歌 微软自己的问题社区都没有解决方法

解决方式

我自己用 C# 写了个重命名的 exe(源码)

一开始也是 直接访问路径 无法访问

最后发现C# 有路径忽略 Windows 优化的前缀 “\\?\“

一试 问题解决

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104

void Director(string dir)
{
DirectoryInfo fdir = new DirectoryInfo(dir);
FileSystemInfo[] fsinfos = null;
try
{
fsinfos = fdir.GetFileSystemInfos();
}
catch
{
try
{
fdir = new DirectoryInfo("\\\\?\\" + dir);
fsinfos = fdir.GetFileSystemInfos();
}
catch {
_syncContext.Post(OutLog, "Error(" + dir + ")");
return;
}
}



foreach (FileSystemInfo fsinfo in fsinfos)
{
if ((fsinfo.Attributes & FileAttributes.Hidden) == FileAttributes.Hidden && (fsinfo.Attributes & FileAttributes.System) == FileAttributes.System)
{
//_syncContext.Post(OutLog, "跳过" + fsinfo.FullName);
continue;
}

if (fsinfo is DirectoryInfo) //判断是否为文件夹
Director(fsinfo.FullName); //递归调用

rename(fsinfo);
}//foreach


}//method



public void rename(FileSystemInfo fsinfo) {
string oldName = fsinfo is DirectoryInfo ? fsinfo.Name : Path.GetFileNameWithoutExtension(fsinfo.FullName);

//去除不可见字符
string newName = Regex.Replace(oldName, "\\p{C}", "");
//去除所有 Emoji
newName = Regex.Replace(newName, @"(\ud83c[\udf00-\udfff])|(\ud83d[\udc00-\ude4f\ude80-\udeff])|[\u2600-\u2B55]", "");
newName = newName.Replace("\\", "\");
newName = newName.Replace("/", "/");
newName = newName.Replace(":", ":");
newName = newName.Replace("*", "*");
newName = newName.Replace("!", "!");
newName = newName.Replace("?", "?");
newName = newName.Replace("<", "〈");
newName = newName.Replace(">", "〉");
newName = newName.Replace("+", "+");
newName = newName.Replace("-", "-");
newName = newName.Replace("#", "#");
newName = newName.Replace("$", "¥");
newName = newName.Replace("%", "%");
newName = newName.Replace("&", "&");
newName = newName.Replace("\"", """);
newName = newName.Replace("'", "'");
newName = newName.Replace("(", "(");
newName = newName.Replace(")", ")");
newName = newName.Replace(".", ".");
newName = Regex.Replace(newName, @"\s", " ");
//去除名称开头结尾的空格
//结尾有空格会触发 文件系统 BUG
newName = newName.Trim();

if (!newName.Equals(oldName))
{

try
{
if (fsinfo is DirectoryInfo)
Directory.Move(fsinfo.FullName, Path.GetDirectoryName(fsinfo.FullName) + "\\" + newName);
else
File.Move(fsinfo.FullName, Path.GetDirectoryName(fsinfo.FullName) + "\\" + newName + Path.GetExtension(fsinfo.FullName));
_syncContext.Post(OutError, "(" + oldName + ") -> (" + newName + ")");
}
catch {
try
{
if (fsinfo is DirectoryInfo)
Directory.Move("\\\\?\\" + fsinfo.FullName, "\\\\?\\" + Path.GetDirectoryName(fsinfo.FullName) + "\\" + newName);
else
File.Move("\\\\?\\" + fsinfo.FullName, "\\\\?\\" + Path.GetDirectoryName(fsinfo.FullName) + "\\" + newName + Path.GetExtension(fsinfo.FullName));
}
catch
{
_syncContext.Post(OutLog, fsinfo.FullName + " ERROR(" + oldName + ") -> (" + newName + ")");
}
}

errName++;
}


}// method

顺便把部分非法字符都删掉 或 替换掉

不替换这些非法字符 经常会导致 FTP 用着用着 突然乱码 无法访问