Lấy tên tệp mà không cần tiện ích mở rộng


279

Khi nhận tên tệp trong một thư mục nhất định:

DirectoryInfo di = new DirectoryInfo(currentDirName);
FileInfo[] smFiles = di.GetFiles("*.txt");
foreach (FileInfo fi in smFiles)
{
    builder.Append(fi.Name);
    builder.Append(", ");
    ...
}

fi.Namemang lại cho tôi một tên tập tin với phần mở rộng của nó: file1.txt, file2.txt, file3.txt.

Làm thế nào tôi có thể nhận được tên tập tin mà không cần phần mở rộng? ( file1, file2, file3)

Câu trả lời:


479

Bạn có thể sử dụng Path.GetFileNameWithoutExtension:

foreach (FileInfo fi in smFiles)
{
    builder.Append(Path.GetFileNameWithoutExtension(fi.Name));
    builder.Append(", ");
}

Mặc dù tôi ngạc nhiên không có cách nào để có được điều này trực tiếp từ FileInfo(hoặc ít nhất là tôi không thể nhìn thấy nó).


7
Và để có được tiện ích mở rộng (để thêm vào sau), hãy sử dụng: Path.GetExtension (fileName);
Justin

2
@Juzzz Thật tiện dụng nếu bạn đang làm việc với một chuỗi trần, nhưng nếu bạn đã có một đối tượng FileInfo, thì không cần phải bận tâm với Đường dẫn. FileInfo đã cung cấp thuộc tính "Tiện ích mở rộng" cho mục đích này.
jmbpiano

Tôi đã gặp lỗi "'builder' không tồn tại trong bối cảnh hiện tại". Tôi đã thêm 'system.Text' nhưng vẫn gặp lỗi tương tự. Lý do là gì?
ffttyy

@ffttyy buildersẽ là một ví dụ StringBuildertrong mã của OP. Đây chỉ là một ví dụ sử dụng GetFileNameWithoutExtension - bạn có thể sẽ viết mã của riêng mình tốt hơn để gọi nó.
Rupi

9
Một điều cần lưu ý ở đây là nếu tệp của bạn chứa phần mở rộng gấp đôi, GetFileNameWithoutExtensionchỉ xóa phần mở rộng cuối . Ví dụ: tên tệp example.es6.jssẽ trở thànhexample.es6
David Roberts

48

Lưu ý rằng Path.GetFileNameWithoutExtension không phải là cách tốt nhất vì nó kiểm tra các ký tự đường dẫn không hợp lệ và cố gắng trích xuất DirectorySeparatorChar, AltDirectorySeparatorChar hoặc VolumeSpayatorChar trong một vòng lặp có vẻ không cần thiết cho tên tệp (không phải là đường dẫn đầy đủ)!
S.Serpoo Sơn

22

Giải pháp này cũng ngăn chặn việc thêm dấu phẩy.

var filenames = String.Join(
                    ", ",
                    Directory.GetFiles(@"c:\", "*.txt")
                       .Select(filename => 
                           Path.GetFileNameWithoutExtension(filename)));

Tôi không thích DirectoryInfo, FileInfo cho kịch bản này.

DirectoryInfo và FileInfo thu thập nhiều dữ liệu về thư mục và các tệp hơn mức cần thiết để chúng mất nhiều thời gian và bộ nhớ hơn mức cần thiết.


2
+1. Tôi cũng thích Directory.GetFileshơn bất kỳ ngày nào DirectoryInfo.GetFiles, nếu tất cả những gì tôi muốn là tên tệp.
Yogesh

Tôi thích điều này vì String.Join, LINQ, không có StringBuilder.
Csaba Toth

Nếu bạn xem mã nguồn. Hàm tạo của FileInfo có trọng lượng rất nhẹ. Và tất cả các thông tin bạn nhìn thấy được thực hiện thông qua các thuộc tính. Chúng chỉ được tập hợp khi bạn gọi cho chúng
fjch1997

@ fjch1997 - Trình xây dựng gọi Path.GetFileName và kiểm tra quyền. Vì vậy, có vẻ như một chút dư thừa.
Erno

@ErnodeWeerd FileIOPermission không kiểm tra quyền đối với ACL. thay vào đó là một loại cơ chế trong .NET để kiểm tra quyền cho mã đáng tin cậy một phần. Vì vậy, nó không nên thực hiện bất kỳ cuộc gọi IO thực tế nào. Nó ảnh hưởng đến hiệu suất bao nhiêu? Tôi không thể nói mà không thử nghiệm. Nhưng tôi cho rằng nó không tuyệt lắm
fjch1997

10

Sử dụng Path.GetFileNameWithoutExtension. Đường dẫn nằm trong không gian tên System.IO.



6

Là một câu trả lời bổ sung (hoặc kết hợp với các câu trả lời hiện có), bạn có thể viết một phương thức mở rộng để thực hiện điều này cho bạn trong lớp DirectoryInfo. Đây là một mẫu mà tôi đã viết khá nhanh có thể được tô điểm để cung cấp tên thư mục hoặc các tiêu chí khác để sửa đổi, v.v .:

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;

namespace DocumentDistributor.Library
{
    public static class myExtensions
    {
        public static string[] GetFileNamesWithoutFileExtensions(this DirectoryInfo di)
        {
            FileInfo[] fi = di.GetFiles();
            List<string> returnValue = new List<string>();

            for (int i = 0; i < fi.Length; i++)
            {
                returnValue.Add(Path.GetFileNameWithoutExtension(fi[i].FullName)); 
            }

            return returnValue.ToArray<string>();
         }
    }
}

Chỉnh sửa: Tôi cũng nghĩ rằng phương pháp này có thể được đơn giản hóa hoặc tuyệt vời nếu nó sử dụng LINQ để đạt được việc xây dựng mảng, nhưng tôi không có kinh nghiệm trong LINQ để thực hiện đủ nhanh cho một mẫu loại này.

Chỉnh sửa 2 (gần 4 năm sau): Đây là phương pháp LINQ-ified tôi sẽ sử dụng:

public static class myExtensions
{
    public static IEnumerable<string> GetFileNamesWithoutExtensions(this DirectoryInfo di)
    {
        return di.GetFiles()
            .Select(x => Path.GetFileNameWithoutExtension(x.FullName));
    }
}

5

FileInfo biết phần mở rộng của riêng nó, vì vậy bạn có thể xóa nó

fileInfo.Name.Replace(fileInfo.Extension, "");
fileInfo.FullName.Replace(fileInfo.Extension, "");

hoặc nếu bạn hoang tưởng rằng nó có thể xuất hiện ở giữa hoặc muốn vi mô hóa:

file.Name.Substring(0, file.Name.Length - file.Extension.Length)

4

nếu tên tệp chứa thư mục và bạn không cần mất thư mục:

fileName.Remove(fileName.LastIndexOf("."))

2

thử cái này,

string FileNameAndExtension =  "bılah bılah.pdf";
string FileName = FileNameAndExtension.Split('.')[0];

1

Chỉ để cho bản ghi âm thôi:

DirectoryInfo di = new DirectoryInfo(currentDirName);
FileInfo[] smFiles = di.GetFiles("*.txt");
string fileNames = String.Join(", ", smFiles.Select<FileInfo, string>(fi => Path.GetFileNameWithoutExtension(fi.FullName)));

Cách này bạn không sử dụng StringBuildernhưng String.Join(). Ngoài ra xin vui lòng nhận xét rằng Path.GetFileNameWithoutExtension()cần một đường dẫn đầy đủ ( fi.FullName), không phải fi.Namenhư tôi thấy trong một trong những câu trả lời khác.


-5
using System;

using System.IO;

public class GetwithoutExtension
{

    public static void Main()
    {
        //D:Dir dhould exists in ur system
        DirectoryInfo dir1 = new DirectoryInfo(@"D:Dir");
        FileInfo [] files = dir1.GetFiles("*xls", SearchOption.AllDirectories);
        foreach (FileInfo f in files)
        {
            string filename = f.Name.ToString();
            filename= filename.Replace(".xls", "");
            Console.WriteLine(filename);
        }
        Console.ReadKey();

    }

}

5
Bạn dường như không nhận thức được rằng đã có một lớp Framework thực hiện điều này cho bạn.
Andrew Barber

3
Ngoài ra, nếu ai đó đặt tên tệp của họ là "Hiện tại.XLSFiles.xls" thì điều này sẽ gây ra sự cố THỰC SỰ.
Tom Padilla

@TomPadilla tại sao điều này sẽ gây ra vấn đề?
Luke101

Bởi vì phương thức này sẽ hiển thị "Current.files" làm tên tệp. Bởi vì mọi trường hợp của ".xls" sẽ được thay thế bằng "", bao gồm cả các trường hợp ở giữa tên.
Tom Padilla
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.