सबसे पहले, प्रश्न में कोड वर्णित आउटपुट का उत्पादन नहीं करता है। यह फ़ाइल एक्सटेंशन ( "txt"
) और फ़ाइल आधार नाम ( "hello"
) नहीं निकालता है । ऐसा करने के लिए अंतिम पंक्ति को कॉल करना चाहिए First()
, न Last()
कि इस तरह ...
static string GetFileBaseNameUsingSplit(string path)
{
string[] pathArr = path.Split('\\');
string[] fileArr = pathArr.Last().Split('.');
string fileBaseName = fileArr.First().ToString();
return fileBaseName;
}
उस परिवर्तन को करने के बाद, इस कोड को बेहतर बनाने के बारे में सोचने वाली एक बात यह है कि यह कचरे की मात्रा है:
- में प्रत्येक पथ खंड के लिए एक
string[]
युक्तstring
path
- अंतिम पथ खंड में प्रत्येक के लिए
string[]
कम से कम एक युक्तstring
.
path
इसलिए, नमूना पथ से आधार फ़ाइल नाम निकालने "C:\Program Files\hello.txt"
का उत्पादन करना चाहिए (अस्थायी) object
रों "C:"
, "Program Files"
, "hello.txt"
, "hello"
, "txt"
, एक string[3]
, और एक string[2]
। यह महत्वपूर्ण हो सकता है यदि विधि को बड़ी संख्या में पथों पर बुलाया जाए। इसे बेहतर बनाने के लिए, हम path
आधार नाम की शुरुआत और अंत बिंदुओं का पता लगाने के लिए खुद को खोज सकते हैं और एक नया बनाने के लिए उन का उपयोग कर सकते हैं string
...
static string GetFileBaseNameUsingSubstringUnsafe(string path)
{
// Fails on paths with no file extension - DO NOT USE!!
int startIndex = path.LastIndexOf('\\') + 1;
int endIndex = path.IndexOf('.', startIndex);
string fileBaseName = path.Substring(startIndex, endIndex - startIndex);
return fileBaseName;
}
यह \
आधार नाम की शुरुआत के रूप में आखिरी के बाद चरित्र के सूचकांक का उपयोग कर रहा है , और वहां से आधार नाम .
के अंत के बाद चरित्र के सूचकांक के रूप में उपयोग करने के लिए पहली बार देख रहा है। क्या यह मूल कोड से कम है? काफी नहीं। यह एक "होशियार" समाधान है? मुझे ऐसा लगता है। कम से कम, यह इस तथ्य के लिए नहीं होगा कि ...
जैसा कि आप टिप्पणी से देख सकते हैं, पिछली विधि समस्याग्रस्त है। यद्यपि यह काम करता है यदि आप एक एक्सटेंशन के साथ फ़ाइल नाम के साथ सभी पथों को समाप्त करते हैं, तो यह अपवाद छोड़ देगा यदि पथ \
(यानी निर्देशिका पथ) के साथ समाप्त होता है या अन्यथा अंतिम खंड में कोई एक्सटेंशन नहीं है। इसे ठीक करने के लिए, हम के लिए खाते में एक अतिरिक्त जांच जोड़ने की जरूरत endIndex
है -1
(यानी .
नहीं पाया जाता है) ...
static string GetFileBaseNameUsingSubstringSafe(string path)
{
int startIndex = path.LastIndexOf('\\') + 1;
int endIndex = path.IndexOf('.', startIndex);
int length = (endIndex >= 0 ? endIndex : path.Length) - startIndex;
string fileBaseName = path.Substring(startIndex, length);
return fileBaseName;
}
अब यह संस्करण मूल के मुकाबले कहीं कम नहीं है, लेकिन यह अधिक कुशल है और (अब) सही भी है।
जहाँ तक .NET कार्यप्रणाली है जो इस कार्यक्षमता को लागू करती है, कई अन्य उत्तर का उपयोग करने का सुझाव देते हैं Path.GetFileNameWithoutExtension()
, जो एक स्पष्ट, आसान समाधान है, लेकिन प्रश्न में कोड के समान परिणाम नहीं देता है। ( GetFileBaseNameUsingSplit()
और नीचे) के बीच एक सूक्ष्म लेकिन महत्वपूर्ण अंतर है : पूर्व पहले से पहले सब कुछ निकालता है और बाद वाला अंतिम से पहले सब कुछ निकालता है । यह प्रश्न में नमूने के लिए कोई फर्क नहीं पड़ता है , लेकिन इस तालिका पर एक नज़र डालते हैं, जब ऊपर दिए गए चार तरीकों के परिणामों की तुलना विभिन्न पथों के साथ की जाती है ...Path.GetFileNameWithoutExtension()
GetFileBaseNameUsingPath()
.
.
path
| Description | Method | Path | Result |
|-----------------------|---------------------------------------|----------------------------------|------------------------------------------------------------------|
| Single extension | GetFileBaseNameUsingSplit() | "C:\Program Files\hello.txt" | "hello" |
| Single extension | GetFileBaseNameUsingPath() | "C:\Program Files\hello.txt" | "hello" |
| Single extension | GetFileBaseNameUsingSubstringUnsafe() | "C:\Program Files\hello.txt" | "hello" |
| Single extension | GetFileBaseNameUsingSubstringSafe() | "C:\Program Files\hello.txt" | "hello" |
|-----------------------|---------------------------------------|----------------------------------|------------------------------------------------------------------|
| Double extension | GetFileBaseNameUsingSplit() | "C:\Program Files\hello.txt.ext" | "hello" |
| Double extension | GetFileBaseNameUsingPath() | "C:\Program Files\hello.txt.ext" | "hello.txt" |
| Double extension | GetFileBaseNameUsingSubstringUnsafe() | "C:\Program Files\hello.txt.ext" | "hello" |
| Double extension | GetFileBaseNameUsingSubstringSafe() | "C:\Program Files\hello.txt.ext" | "hello" |
|-----------------------|---------------------------------------|----------------------------------|------------------------------------------------------------------|
| No extension | GetFileBaseNameUsingSplit() | "C:\Program Files\hello" | "hello" |
| No extension | GetFileBaseNameUsingPath() | "C:\Program Files\hello" | "hello" |
| No extension | GetFileBaseNameUsingSubstringUnsafe() | "C:\Program Files\hello" | EXCEPTION: Length cannot be less than zero. (Parameter 'length') |
| No extension | GetFileBaseNameUsingSubstringSafe() | "C:\Program Files\hello" | "hello" |
|-----------------------|---------------------------------------|----------------------------------|------------------------------------------------------------------|
| Leading period | GetFileBaseNameUsingSplit() | "C:\Program Files\.hello.txt" | "" |
| Leading period | GetFileBaseNameUsingPath() | "C:\Program Files\.hello.txt" | ".hello" |
| Leading period | GetFileBaseNameUsingSubstringUnsafe() | "C:\Program Files\.hello.txt" | "" |
| Leading period | GetFileBaseNameUsingSubstringSafe() | "C:\Program Files\.hello.txt" | "" |
|-----------------------|---------------------------------------|----------------------------------|------------------------------------------------------------------|
| Trailing period | GetFileBaseNameUsingSplit() | "C:\Program Files\hello.txt." | "hello" |
| Trailing period | GetFileBaseNameUsingPath() | "C:\Program Files\hello.txt." | "hello.txt" |
| Trailing period | GetFileBaseNameUsingSubstringUnsafe() | "C:\Program Files\hello.txt." | "hello" |
| Trailing period | GetFileBaseNameUsingSubstringSafe() | "C:\Program Files\hello.txt." | "hello" |
|-----------------------|---------------------------------------|----------------------------------|------------------------------------------------------------------|
| Directory path | GetFileBaseNameUsingSplit() | "C:\Program Files\" | "" |
| Directory path | GetFileBaseNameUsingPath() | "C:\Program Files\" | "" |
| Directory path | GetFileBaseNameUsingSubstringUnsafe() | "C:\Program Files\" | EXCEPTION: Length cannot be less than zero. (Parameter 'length') |
| Directory path | GetFileBaseNameUsingSubstringSafe() | "C:\Program Files\" | "" |
|-----------------------|---------------------------------------|----------------------------------|------------------------------------------------------------------|
| Current file path | GetFileBaseNameUsingSplit() | "hello.txt" | "hello" |
| Current file path | GetFileBaseNameUsingPath() | "hello.txt" | "hello" |
| Current file path | GetFileBaseNameUsingSubstringUnsafe() | "hello.txt" | "hello" |
| Current file path | GetFileBaseNameUsingSubstringSafe() | "hello.txt" | "hello" |
|-----------------------|---------------------------------------|----------------------------------|------------------------------------------------------------------|
| Parent file path | GetFileBaseNameUsingSplit() | "..\hello.txt" | "hello" |
| Parent file path | GetFileBaseNameUsingPath() | "..\hello.txt" | "hello" |
| Parent file path | GetFileBaseNameUsingSubstringUnsafe() | "..\hello.txt" | "hello" |
| Parent file path | GetFileBaseNameUsingSubstringSafe() | "..\hello.txt" | "hello" |
|-----------------------|---------------------------------------|----------------------------------|------------------------------------------------------------------|
| Parent directory path | GetFileBaseNameUsingSplit() | ".." | "" |
| Parent directory path | GetFileBaseNameUsingPath() | ".." | "." |
| Parent directory path | GetFileBaseNameUsingSubstringUnsafe() | ".." | "" |
| Parent directory path | GetFileBaseNameUsingSubstringSafe() | ".." | "" |
|-----------------------|---------------------------------------|----------------------------------|------------------------------------------------------------------|
... और आप देखेंगे कि Path.GetFileNameWithoutExtension()
एक पथ पारित होने पर अलग-अलग परिणाम मिलते हैं जहां फ़ाइल नाम में एक डबल एक्सटेंशन या एक अग्रणी और / या अनुगामी होता है .
। आप निम्न कोड के साथ इसे अपने लिए आजमा सकते हैं ...
using System;
using System.IO;
using System.Linq;
using System.Reflection;
namespace SO6921105
{
internal class PathExtractionResult
{
public string Description { get; set; }
public string Method { get; set; }
public string Path { get; set; }
public string Result { get; set; }
}
public static class Program
{
private static string GetFileBaseNameUsingSplit(string path)
{
string[] pathArr = path.Split('\\');
string[] fileArr = pathArr.Last().Split('.');
string fileBaseName = fileArr.First().ToString();
return fileBaseName;
}
private static string GetFileBaseNameUsingPath(string path)
{
return Path.GetFileNameWithoutExtension(path);
}
private static string GetFileBaseNameUsingSubstringUnsafe(string path)
{
// Fails on paths with no file extension - DO NOT USE!!
int startIndex = path.LastIndexOf('\\') + 1;
int endIndex = path.IndexOf('.', startIndex);
string fileBaseName = path.Substring(startIndex, endIndex - startIndex);
return fileBaseName;
}
private static string GetFileBaseNameUsingSubstringSafe(string path)
{
int startIndex = path.LastIndexOf('\\') + 1;
int endIndex = path.IndexOf('.', startIndex);
int length = (endIndex >= 0 ? endIndex : path.Length) - startIndex;
string fileBaseName = path.Substring(startIndex, length);
return fileBaseName;
}
public static void Main()
{
MethodInfo[] testMethods = typeof(Program).GetMethods(BindingFlags.NonPublic | BindingFlags.Static)
.Where(method => method.Name.StartsWith("GetFileBaseName"))
.ToArray();
var inputs = new[] {
new { Description = "Single extension", Path = @"C:\Program Files\hello.txt" },
new { Description = "Double extension", Path = @"C:\Program Files\hello.txt.ext" },
new { Description = "No extension", Path = @"C:\Program Files\hello" },
new { Description = "Leading period", Path = @"C:\Program Files\.hello.txt" },
new { Description = "Trailing period", Path = @"C:\Program Files\hello.txt." },
new { Description = "Directory path", Path = @"C:\Program Files\" },
new { Description = "Current file path", Path = "hello.txt" },
new { Description = "Parent file path", Path = @"..\hello.txt" },
new { Description = "Parent directory path", Path = ".." }
};
PathExtractionResult[] results = inputs
.SelectMany(
input => testMethods.Select(
method => {
string result;
try
{
string returnValue = (string) method.Invoke(null, new object[] { input.Path });
result = $"\"{returnValue}\"";
}
catch (Exception ex)
{
if (ex is TargetInvocationException)
ex = ex.InnerException;
result = $"EXCEPTION: {ex.Message}";
}
return new PathExtractionResult() {
Description = input.Description,
Method = $"{method.Name}()",
Path = $"\"{input.Path}\"",
Result = result
};
}
)
).ToArray();
const int ColumnPadding = 2;
ResultWriter writer = new ResultWriter(Console.Out) {
DescriptionColumnWidth = results.Max(output => output.Description.Length) + ColumnPadding,
MethodColumnWidth = results.Max(output => output.Method.Length) + ColumnPadding,
PathColumnWidth = results.Max(output => output.Path.Length) + ColumnPadding,
ResultColumnWidth = results.Max(output => output.Result.Length) + ColumnPadding,
ItemLeftPadding = " ",
ItemRightPadding = " "
};
PathExtractionResult header = new PathExtractionResult() {
Description = nameof(PathExtractionResult.Description),
Method = nameof(PathExtractionResult.Method),
Path = nameof(PathExtractionResult.Path),
Result = nameof(PathExtractionResult.Result)
};
writer.WriteResult(header);
writer.WriteDivider();
foreach (IGrouping<string, PathExtractionResult> resultGroup in results.GroupBy(result => result.Description))
{
foreach (PathExtractionResult result in resultGroup)
writer.WriteResult(result);
writer.WriteDivider();
}
}
}
internal class ResultWriter
{
private const char DividerChar = '-';
private const char SeparatorChar = '|';
private TextWriter Writer { get; }
public ResultWriter(TextWriter writer)
{
Writer = writer ?? throw new ArgumentNullException(nameof(writer));
}
public int DescriptionColumnWidth { get; set; }
public int MethodColumnWidth { get; set; }
public int PathColumnWidth { get; set; }
public int ResultColumnWidth { get; set; }
public string ItemLeftPadding { get; set; }
public string ItemRightPadding { get; set; }
public void WriteResult(PathExtractionResult result)
{
WriteLine(
$"{ItemLeftPadding}{result.Description}{ItemRightPadding}",
$"{ItemLeftPadding}{result.Method}{ItemRightPadding}",
$"{ItemLeftPadding}{result.Path}{ItemRightPadding}",
$"{ItemLeftPadding}{result.Result}{ItemRightPadding}"
);
}
public void WriteDivider()
{
WriteLine(
new string(DividerChar, DescriptionColumnWidth),
new string(DividerChar, MethodColumnWidth),
new string(DividerChar, PathColumnWidth),
new string(DividerChar, ResultColumnWidth)
);
}
private void WriteLine(string description, string method, string path, string result)
{
Writer.Write(SeparatorChar);
Writer.Write(description.PadRight(DescriptionColumnWidth));
Writer.Write(SeparatorChar);
Writer.Write(method.PadRight(MethodColumnWidth));
Writer.Write(SeparatorChar);
Writer.Write(path.PadRight(PathColumnWidth));
Writer.Write(SeparatorChar);
Writer.Write(result.PadRight(ResultColumnWidth));
Writer.WriteLine(SeparatorChar);
}
}
}
टीएल; डीआर प्रश्न में कोड व्यवहार नहीं करता है क्योंकि कुछ कोने के मामलों में उम्मीद की जाती है। यदि आप अपना मार्ग हेरफेर कोड लिखने जा रहे हैं, तो ध्यान रखें ...
- ... आप एक "विस्तार" को कैसे परिभाषित करते हैं (क्या यह पहले से पहले
.
सब कुछ है या आखिरी से पहले सब कुछ है .
?)
- ... कई एक्सटेंशन वाली फाइलें
- ... बिना एक्सटेंशन वाली फाइलें
- ... एक अग्रणी के साथ फाइल
.
- ... एक अनुगामी के साथ फाइलें
.
(शायद कुछ ऐसा नहीं होगा जिसका आप कभी विंडोज पर सामना करेंगे, लेकिन वे संभव हैं )
- ... "विस्तार" वाली निर्देशिकाएं या जिनमें अन्यथा शामिल हैं a
.
- ... रास्ते जो एक के साथ समाप्त होते हैं
\
- ... सापेक्ष पथ
सभी फ़ाइल पथ सामान्य सूत्र का अनुसरण नहीं करते हैं X:\Directory\File.ext
!
Path.GetFileName("C:\\dev\\some\\path\\to\\file.cs")
उसी स्ट्रिंग को लौटा रहा है और इसे किसी कारण से "file.cs" में परिवर्तित नहीं कर रहा है। अगर मैं अपने कोड को एक ऑनलाइन कंपाइलर (जैसे rextester.com ) में कॉपी / पेस्ट करता हूं , तो यह काम करता है ...?