Bir dosya sistemi yolu verildiğinde, dosya adını uzantısı olmadan çıkarmanın daha kısa bir yolu var mı?


261

WPF C # programlıyorum. Örneğin aşağıdaki yolu var:

C:\Program Files\hello.txt

ve ondan çıkarmak istiyorum hello.

Yol, stringbir veritabanından alınır. Şu anda yolu '\'bölmek ve sonra tekrar bölmek için aşağıdaki kodu kullanıyorum '.':

string path = "C:\\Program Files\\hello.txt";
string[] pathArr = path.Split('\\');
string[] fileArr = pathArr.Last().Split('.');
string fileName = fileArr.Last().ToString();

Çalışıyor, ancak buna daha kısa ve daha akıllı bir çözüm olması gerektiğine inanıyorum. Herhangi bir fikir?


Sistemimde, Path.GetFileName("C:\\dev\\some\\path\\to\\file.cs")aynı dizeyi döndürüyor ve herhangi bir nedenle "file.cs" biçimine dönüştürmüyor. Kodumu bir çevrimiçi derleyiciye ( rextester.com gibi ) kopyalayıp yapıştırırsam çalışır ...?
jbyrd

Yanıtlar:




29

Deneyin

System.IO.Path.GetFileNameWithoutExtension(path); 

gösteri

string fileName = @"C:\mydir\myfile.ext";
string path = @"C:\mydir\";
string result;

result = Path.GetFileNameWithoutExtension(fileName);
Console.WriteLine("GetFileNameWithoutExtension('{0}') returns '{1}'", 
    fileName, result);

result = Path.GetFileName(path);
Console.WriteLine("GetFileName('{0}') returns '{1}'", 
    path, result);

// This code produces output similar to the following:
//
// GetFileNameWithoutExtension('C:\mydir\myfile.ext') returns 'myfile'
// GetFileName('C:\mydir\') returns ''

https://msdn.microsoft.com/en-gb/library/system.io.path.getfilenamewithoutextension%28v=vs.80%29.aspx


Path.GetFileNameWithoutExtension (),> 3 karakterli bir dosya uzantısıyla çalışmıyor gibi görünüyor.
Nolmë Informatique



11

Bunu dene:

string fileName = Path.GetFileNameWithoutExtension(@"C:\Program Files\hello.txt");

Bu, fileName için "merhaba" döndürür.


9
string Location = "C:\\Program Files\\hello.txt";

string FileName = Location.Substring(Location.LastIndexOf('\\') +
    1);

1
+1, çünkü bunun dosya adının Path.GetInvalidChars ()] içinde geçersiz karakterler [<,> vb. İçerdiği bir Yedekleme olarak çalışması durumunda faydalı olabilir.
bhuvin

Bu aslında UNIX ftp sunucularında yolla çalışırken oldukça kullanışlıdır.
s952163

6

Bunu dene,

string FilePath=@"C:\mydir\myfile.ext";
string Result=Path.GetFileName(FilePath);//With Extension
string Result=Path.GetFileNameWithoutExtension(FilePath);//Without Extension

2
En yüksek oyu alan cevapta belirtilen yöntemlerin aynısını kullandınız.
CodeCaster

1
string filepath = "C:\\Program Files\\example.txt";
FileVersionInfo myFileVersionInfo = FileVersionInfo.GetVersionInfo(filepath);
FileInfo fi = new FileInfo(filepath);
Console.WriteLine(fi.Name);

//input to the "fi" is a full path to the file from "filepath"
//This code will return the fileName from the given path

//output
//example.txt

FileVersionInfoSürüm bilgisi olmayan dosyalarda kullanılabileceğine şaşırdım . GetVersionInfo()Yalnızca zaten var olan bir dosyaya başvuran yollarda kullanılabileceğini unutmayın . Her iki sınıf da dosya adını almak için kullanılabilse de, soru da uzantıyı kaldırmasını istedi.
BACON

1

İlk olarak, sorudaki kod açıklanan çıktıyı üretmez. Dosya taban adını ( ) değil , dosya uzantısını ( "txt") ayıklar . Bunu yapmak için son satırın çağırması gerekir , böyle değil ..."hello"First()Last()

static string GetFileBaseNameUsingSplit(string path)
{
    string[] pathArr = path.Split('\\');
    string[] fileArr = pathArr.Last().Split('.');
    string fileBaseName = fileArr.First().ToString();

    return fileBaseName;
}

Bu değişikliği yaptıktan sonra, bu kodu geliştirmek kadar düşünülmesi gereken bir şey, yarattığı çöp miktarıdır:

  • A'daki her yol segmenti için bir tane string[]içerenstringpath
  • A'daki son yol segmentinde her string[]biri stringiçin en az bir tane içeren A.path

Bu nedenle, örnek yolu taban dosya adı ekstre "C:\Program Files\hello.txt"üretmelidir (geçici) objectler "C:", "Program Files", "hello.txt", "hello", "txt", bir string[3]ve bir string[2]. Yöntem çok sayıda yolda çağrıldığında bu önemli olabilir. Bunu iyileştirmek pathiçin, temel adın başlangıç ​​ve bitiş noktalarını bulmak için kendimizi arayabilir ve bunları yeni bir tane oluşturmak için kullanabiliriz 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;
}

Bu, \temel adın başlangıcı olarak sondan sonraki karakterin dizinini kullanır ve oradan .temel adın sonundan sonra karakterin dizini olarak kullanılacak ilkini arar . Bu orijinal koddan daha mı kısa? Pek değil. "Daha akıllı" bir çözüm mü? Sanırım. En azından, olmasa bile ...

Yorumdan da görebileceğiniz gibi, önceki yöntem sorunludur. Tüm yolların bir uzantıya sahip bir dosya adıyla sona erdiğini varsayarsanız da, yol sonla bitiyorsa \(yani bir dizin yolu) veya başka bir şekilde son segmentte uzantı içermiyorsa bir istisna atar . Bunu düzeltmek için, ne zaman endIndexolduğunu -1(yani .bulunamadı) hesaba katmak için ekstra bir kontrol eklememiz gerekir ...

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;
}

Şimdi bu sürüm orijinalden daha kısa bir yerde değil, ancak daha verimli ve (şimdi) de doğru.

Bu işlevselliği uygulayan .NET yöntemleri ile ilgili olarak, diğer birçok yanıt Path.GetFileNameWithoutExtension(), açık ve kolay bir çözümdür, ancak sorudaki kodla aynı sonuçları vermez . GetFileBaseNameUsingSplit()Ve Path.GetFileNameWithoutExtension()( GetFileBaseNameUsingPath()aşağıda) arasında ince ama önemli bir fark vardır : ilki her şeyden önce ilkini . çıkarır ve ikincisi her şeyi sondan önce çıkarır .. Bu path, sorudaki örnek için bir fark yaratmaz , ancak çeşitli yollarla çağrıldığında yukarıdaki dört yöntemin sonuçlarını karşılaştıran bu tabloya bakın ...

| 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()   | ".."                             | ""                                                               |
|-----------------------|---------------------------------------|----------------------------------|------------------------------------------------------------------|

... ve Path.GetFileNameWithoutExtension()dosya adının çift uzantıya veya öndeki ve / veya sondaki bir yola geçildiğinde farklı sonuçlar verdiğini göreceksiniz .. Aşağıdaki kodla kendiniz deneyebilirsiniz ...

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);
        }
    }
}

TL; DR Söz konusu kod , bazı köşe vakalarında pek çok kişi beklendiği gibi davranmıyor . Kendi yol manipülasyon kodunuzu yazacaksanız, dikkate aldığınızdan emin olun ...

  • ... bir "uzantıyı" nasıl tanımlarsınız (ilkinden önceki .her şey .mi yoksa sondan önceki her şey mi?)
  • ... birden fazla uzantıya sahip dosyalar
  • ... uzantısı olmayan dosyalar
  • ... önde gelen dosyalar .
  • ... sondaki dosyalar .(muhtemelen Windows'ta karşılaşacağınız bir şey değil, ancak bunlar mümkündür )
  • ... "uzantılı" veya başka şekilde .
  • ... ile biten yollar \
  • ... göreli yollar

Tüm dosya yolları normal formülünü izlemez X:\Directory\File.ext!


0
Namespace: using System.IO;  
 //use this to get file name dynamically 
 string filelocation = Properties.Settings.Default.Filelocation;
//use this to get file name statically 
//string filelocation = @"D:\FileDirectory\";
string[] filesname = Directory.GetFiles(filelocation); //for multiple files

Your path configuration in App.config file if you are going to get file name dynamically  -

    <userSettings>
        <ConsoleApplication13.Properties.Settings>
          <setting name="Filelocation" serializeAs="String">
            <value>D:\\DeleteFileTest</value>
          </setting>
              </ConsoleApplication13.Properties.Settings>
      </userSettings>

Soru, bir dosya yolundan uzantı olmadan dosya adının nasıl ayıklanacağını sormaktır. Bu, bunun yerine, bir yapılandırma dosyası tarafından belirtilebilen veya belirtilemeyen bir dizinin hemen alt dosyalarını alır. Bunlar gerçekten aynı şeye yakın değil.
BACON
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.