C# 函数可缩小文件路径,使其更易于阅读
在c#中是否有任何函数可以读取文件路径 输入:“c:\users\Windows\Downloaded Program Files\Folder\Inside\example\file.txt”C# 函数可缩小文件路径,使其更易于阅读,c#,.net,filepath,C#,.net,Filepath,在c#中是否有任何函数可以读取文件路径 输入:“c:\users\Windows\Downloaded Program Files\Folder\Inside\example\file.txt” 输出:“c:\users\…\example\file.txt”,对我来说,这看起来不像是人类可读的。无论如何,我认为没有这样的功能。在\字符上拆分它,只保留前两个插槽和最后两个插槽,就可以了 类似这样的代码,尽管代码不是很优雅 string[] splits = path.Split('\\');
输出:“c:\users\…\example\file.txt”,对我来说,这看起来不像是人类可读的。无论如何,我认为没有这样的功能。在\字符上拆分它,只保留前两个插槽和最后两个插槽,就可以了 类似这样的代码,尽管代码不是很优雅
string[] splits = path.Split('\\');
Console.WriteLine( splits[0] + "\\" + splits[1] + "\\...\\" + splits[splits.Length - 2] + "\\" + splits[splits.Length - 1]);
如果需要,请根据路径字符串的长度插入省略号,然后使用以下代码:
TextRenderer.MeasureText(path, Font,
new System.Drawing.Size(Width, 0),
TextFormatFlags.PathEllipsis | TextFormatFlags.ModifyString);
它将就地修改路径
编辑:小心使用此方法。它打破了规则,说.NET中的字符串是不可变的。实际上,MeasureText
方法的第一个参数不是ref
参数,这意味着不能返回新字符串。而是更改现有字符串。处理使用创建的副本时要小心
string temp = String.Copy(path);
您可以使用以下内容:
public string ShrinkPath(string path, int maxLength)
{
List<string> parts = new List<string>(path.Split('\\'));
string start = parts[0] + @"\" + parts[1];
parts.RemoveAt(1);
parts.RemoveAt(0);
string end = parts[parts.Count-1];
parts.RemoveAt(parts.Count-1);
parts.Insert(0, "...");
while(parts.Count > 1 &&
start.Length + end.Length + parts.Sum(p=>p.Length) + parts.Count > maxLength)
parts.RemoveAt(parts.Count-1);
string mid = "";
parts.ForEach(p => mid += p + @"\");
return start+mid+end;
}
公共字符串收缩路径(字符串路径,int-maxLength)
{
列表部分=新列表(path.Split('\\');
字符串开始=部分[0]+@“\”+部分[1];
部分。移除(1);
部分。移除(0);
字符串结束=部分[parts.Count-1];
零件移除(零件计数-1);
部分。插入(0,“…”);
而(parts.Count>1&&
start.Length+end.Length+parts.Sum(p=>p.Length)+parts.Count>maxLength)
零件移除(零件计数-1);
字符串mid=“”;
parts.ForEach(p=>mid+=p+@“\”;
返回开始+中间+结束;
}
或者只使用奥利弗溶液,这更容易;-) 杰夫·阿特伍德(Jeff Atwood)在他的博客上提供了解决方案,如下所示:
[DllImport("shlwapi.dll", CharSet = CharSet.Auto)]
static extern bool PathCompactPathEx([Out] StringBuilder pszOut, string szPath, int cchMax, int dwFlags);
static string PathShortener(string path, int length)
{
StringBuilder sb = new StringBuilder();
PathCompactPathEx(sb, path, length, 0);
return sb.ToString();
}
它使用非托管函数来实现您想要的功能。Nasreddine的回答几乎正确。 在您的情况下,只需指定StringBuilder大小:
[DllImport("shlwapi.dll", CharSet = CharSet.Auto)]
static extern bool PathCompactPathEx(
[Out] StringBuilder pszOut,
string szPath,
int cchMax,
int dwFlags);
static string PathShortener(string path, int length)
{
StringBuilder sb = new StringBuilder(length + 1);
PathCompactPathEx(sb, path, length, 0);
return sb.ToString();
}
我正面临着这个问题,因为漫长的道路正在成为一个完全令人头疼的问题。这是我很快拼凑出来的东西(注意马虎),但它完成了工作
private string ShortenPath(string path, int maxLength)
{
int pathLength = path.Length;
string[] parts;
parts = label1.Text.Split('\\');
int startIndex = (parts.Length - 1) / 2;
int index = startIndex;
string output = "";
output = String.Join("\\", parts, 0, parts.Length);
decimal step = 0;
int lean = 1;
do
{
parts[index] = "...";
output = String.Join("\\", parts, 0, parts.Length);
step = step + 0.5M;
lean = lean * -1;
index = startIndex + ((int)step * lean);
}
while (output.Length >= maxLength && index != -1);
return output;
}
编辑
以下是梅林2001年修正案的更新
private string ShortenPath(string path, int maxLength)
{
int pathLength = path.Length;
string[] parts;
parts = path.Split('\\');
int startIndex = (parts.Length - 1) / 2;
int index = startIndex;
String output = "";
output = String.Join("\\", parts, 0, parts.Length);
decimal step = 0;
int lean = 1;
while (output.Length >= maxLength && index != 0 && index != -1)
{
parts[index] = "...";
output = String.Join("\\", parts, 0, parts.Length);
step = step + 0.5M;
lean = lean * -1;
index = startIndex + ((int)step * lean);
}
// result can be longer than maxLength
return output.Substring(0, Math.Min(maxLength, output.Length));
}
如果您想为这个问题编写自己的解决方案,请使用内置类,如:FileInfo、Directory等。。。这使得它不那么容易出错 下面的代码生成“VS样式”的缩短路径,如:“C:\…\Folder\File.ext”
公共静态类路径格式化程序
{
公共静态字符串收缩路径(字符串绝对路径、整数限制、字符串间隔符=“…”)
{
if(string.IsNullOrWhiteSpace(绝对路径))
{
返回字符串。空;
}
if(绝对路径长度限制)
{
打破
}
零件。插入(2,目录名称);
dir=dir.Parent;
ret=string.Join(“\\”,parts);
}
返回ret;
}
}
这里几乎所有答案都通过计算字符来缩短路径字符串。
但这种方法忽略了每个字符的宽度
这是30个“W”字符:
wwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwww
以下是30个“i”字符:
IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
如您所见,计数字符并不是真正有用的
而且不需要编写自己的代码,因为Windows API从Windows 95起就具有这一功能。
此功能的名称为“路径省略号”。
Windows APIDrawTextW()
有一个标志DT\u PATH\u省略号
,它正好做到了这一点。
在.NET framwork中,TextRenderer
类中提供了此功能(无需使用PInvoke)
有两种方法可用于此:
1。)将路径直接绘制到标签中:
public class PathLabel : Label
{
protected override void OnPaint(PaintEventArgs e)
{
if (AutoSize)
throw new Exception("You must set "+Name+".AutoSize = false in VS "
+ "Designer and assign a fix width to the PathLabel.");
Color c_Fore = Enabled ? ForeColor : SystemColors.GrayText;
TextRenderer.DrawText(e.Graphics, Text, Font, ClientRectangle, c_Fore,
BackColor, TextFormatFlags.PathEllipsis);
}
}
此标签要求您在Visual Studio Designer中关闭自动省略号
,并为标签指定固定宽度(路径应占据的最大宽度)
您甚至可以在VisualStudioDesigner中看到截断的路径
我输入了一条不适合标签的长路径:
C:\WINDOWS\Installer{40BF1E83-20EB-11D8-97C5-0009C5020658}\ARPPRODUCTICON.exe
即使在Visual Studio Designer中,也会显示如下:
2。)缩短路径而不在屏幕上绘制:
public static String ShortenPath(String s_Path, Font i_Font, int s32_Width)
{
TextRenderer.MeasureText(s_Path, i_Font, new Size(s32_Width, 100),
TextFormatFlags.PathEllipsis | TextFormatFlags.ModifyString);
// Windows inserts a '\0' character into the string instead of shortening the string
int s32_Nul = s_Path.IndexOf((Char)0);
if (s32_Nul > 0)
s_Path = s_Path.Substring(0, s32_Nul);
return s_Path;
}
标志TextFormatFlags.ModifyString
在字符串中插入“\0”字符。在C#中修改字符串是非常不寻常的。
通常字符串是不可变的。
这是因为底层APIDrawTextW()
是这样工作的。
但是,由于字符串只会缩短,而且永远不会变长,因此没有缓冲区溢出的风险
下面的代码
String s_Text = @"C:\WINDOWS\Installer{40BF1E83-20EB-11D8-97C5-0009C5020658}\ARPPRODUCTICON.exe";
s_Text = ShortenPath(s_Text, new Font("Arial", 12), 500);
将导致“C:\WINDOWS\Installer{40BF1E83-20EB-1…\ARPPRODUCTICON.exe”如果(splits.Length>4),我还将添加一个
if
在那里也进行测试。这绝对不是缩小路径…考虑一下像C:\veryveryylong\supersupersuperlong\a\b\C\d.txt这样的路径……您的解决方案将解决什么问题?这是针对WinForms还是只需要一个较短的字符串?(我这样问是因为.NET只支持绘图,它只适用于WinForms和图像)。为什么要删除完整路径?如果是这种情况,用户将无法找到文件。如果您对此不担心,则根本不显示路径,只显示文件名。user946874:不客气。另外,由于您是StackOverflow新手,我想通知您,您可以接受对您有帮助的答案最重要的是检查答案旁边的勾号。奇怪的是,这在framework 3.5中运行得很好,我更新到vs 2010和framework 4,现在我在这一行中遇到了一个无法调试的崩溃。(visual studio正忙着…)切换到CharSet.Ansi
“已解决”(?)这个问题。@v.oddou它对我来说也崩溃了,直到我看到哪个使用了另一个常量
public static String ShortenPath(String s_Path, Font i_Font, int s32_Width)
{
TextRenderer.MeasureText(s_Path, i_Font, new Size(s32_Width, 100),
TextFormatFlags.PathEllipsis | TextFormatFlags.ModifyString);
// Windows inserts a '\0' character into the string instead of shortening the string
int s32_Nul = s_Path.IndexOf((Char)0);
if (s32_Nul > 0)
s_Path = s_Path.Substring(0, s32_Nul);
return s_Path;
}
String s_Text = @"C:\WINDOWS\Installer{40BF1E83-20EB-11D8-97C5-0009C5020658}\ARPPRODUCTICON.exe";
s_Text = ShortenPath(s_Text, new Font("Arial", 12), 500);