รับชื่อไฟล์โดยไม่มีนามสกุล


279

เมื่อรับชื่อไฟล์ในโฟลเดอร์ที่ต้องการ:

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

fi.Namefile1.txtให้ฉันชื่อไฟล์ที่มีนามสกุล: file2.txt, file3.txt,

ฉันจะรับชื่อไฟล์ที่ไม่มีนามสกุลได้อย่างไร ( file1, file2, file3)

คำตอบ:


479

คุณสามารถใช้Path.GetFileNameWithoutExtension:

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

แม้ว่าฉันจะประหลาดใจไม่มีวิธีที่จะได้รับโดยตรงจากFileInfo(หรืออย่างน้อยฉันก็ไม่เห็น)


7
และเพื่อรับส่วนขยาย (เพื่อเพิ่มในภายหลัง) ใช้: Path.GetExtension (fileName);
Justin

2
@Juzzz มันมีประโยชน์ถ้าคุณทำงานกับสตริงเปล่า แต่ถ้าคุณมีวัตถุ FileInfo อยู่แล้วก็ไม่จำเป็นต้องกังวลกับ Path FileInfo ได้จัดเตรียมคุณสมบัติ "ส่วนขยาย" ไว้สำหรับวัตถุประสงค์แล้ว
jmbpiano

ฉันได้รับข้อผิดพลาด "'ผู้สร้าง' ไม่มีอยู่ในบริบทปัจจุบัน" ฉันเพิ่ม 'system.Text' แต่ยังมีข้อผิดพลาดเดียวกัน เหตุผลคืออะไร
ffttyy

@ffttyy builderจะเป็นตัวอย่างของStringBuilderรหัส OP มันเป็นเพียงตัวอย่างของการใช้ GetFileNameWithoutExtension - คุณน่าจะเขียนรหัสของคุณเองได้ดีขึ้น
โฟโต้

9
หนึ่ง gotcha ที่ควรทราบนี่คือว่าถ้าไฟล์ของคุณมีการขยายคู่GetFileNameWithoutExtensionเพียงเอาท้ายนามสกุล ตัวอย่างเช่นชื่อไฟล์example.es6.jsจะกลายเป็นexample.es6
David Roberts

48

โปรดทราบว่า Path.GetFileNameWithoutExtension ไม่ใช่วิธีที่ดีที่สุดเนื่องจากจะตรวจสอบตัวอักษรเส้นทางที่ไม่ถูกต้องและพยายามแยก DirectorySeparatorChar, AltDirectorySeparatorChar หรือ VolumeSeparatorChar ในวงที่ดูเหมือนไม่จำเป็นสำหรับชื่อไฟล์ (ไม่ใช่เส้นทางแบบเต็ม)!
S.Serpooshan

22

วิธีนี้ยังป้องกันการเพิ่มจุลภาคต่อท้าย

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

ฉันไม่ชอบ DirectoryInfo, FileInfo สำหรับสถานการณ์นี้

DirectoryInfo และ FileInfo รวบรวมข้อมูลเพิ่มเติมเกี่ยวกับโฟลเดอร์และไฟล์ที่เกินความจำเป็นเพื่อให้พวกเขาใช้เวลาและหน่วยความจำมากกว่าที่จำเป็น


2
+1 ฉันชอบDirectory.GetFilesมากกว่าทุกDirectoryInfo.GetFilesวันถ้าทั้งหมดที่ฉันต้องการคือชื่อไฟล์
โยเกช

ฉันชอบสิ่งนี้เพราะ String.Join, LINQ, ไม่มี StringBuilder
Csaba Toth

ถ้าคุณดูรหัสต้นฉบับ ตัวสร้างของ FileInfo มีน้ำหนักเบามาก และข้อมูลทั้งหมดที่คุณเห็นจะทำผ่านคุณสมบัติ พวกเขาจะถูกรวบรวมเมื่อคุณเรียกพวกเขาเท่านั้น
fjch1997

@ fjch1997 - ตัวสร้างจะเรียกใช้ Path.GetFileName และตรวจสอบการอนุญาต ดังนั้นดูเหมือนว่าซ้ำซ้อนเล็กน้อย
Erno

@ErnodeWeerd FileIOPermission ไม่ตรวจสอบสิทธิ์กับ ACL แทนที่จะเป็นกลไกบางอย่างใน. NET เพื่อตรวจสอบการอนุญาตสำหรับรหัสที่เชื่อถือได้เพียงบางส่วน ดังนั้นจึงไม่ควรทำการโทรตามจริง มันส่งผลกระทบต่อประสิทธิภาพการทำงานมากแค่ไหน? ฉันไม่สามารถพูดได้หากไม่มีการทดสอบ แต่ฉันคิดว่ามันไม่ยอดเยี่ยมเลย
fjch1997


10
Path.GetFileNameWithoutExtension(file);

ส่งคืนชื่อไฟล์เท่านั้นโดยไม่มีประเภทส่วนขยาย นอกจากนี้คุณยังสามารถเปลี่ยนได้เพื่อให้ได้ทั้งชื่อและประเภทของไฟล์

 Path.GetFileName(FileName);

แหล่งที่มา: https://msdn.microsoft.com/en-us/library/system.io.path(v=vs.110).aspx


ขอบคุณคำตอบที่ดีที่สุดคือคำตอบที่สั้นที่สุดเสมอ
Ashraf Abusada

6

ในฐานะที่เป็นคำตอบเพิ่มเติม (หรือเพื่อประกอบกับคำตอบที่มีอยู่) คุณสามารถเขียนวิธีการขยายเพื่อบรรลุสิ่งนี้ให้คุณภายในคลาส DirectoryInfo นี่คือตัวอย่างที่ฉันเขียนอย่างรวดเร็วพอสมควรซึ่งสามารถนำมาประดับให้ชื่อไดเรกทอรีหรือเกณฑ์อื่น ๆ สำหรับการแก้ไข ฯลฯ :

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

แก้ไข:ฉันคิดว่าวิธีนี้อาจจะง่ายหรือน่ากลัวถ้ามันใช้ LINQ เพื่อสร้างอาร์เรย์ แต่ฉันไม่ได้มีประสบการณ์ใน LINQ ที่จะทำมันเร็วพอสำหรับตัวอย่างประเภทนี้

แก้ไข 2 (เกือบ 4 ปีต่อมา):นี่คือวิธี LINQ-ified ที่ฉันจะใช้:

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

5

FileInfo รู้นามสกุลของตัวเองดังนั้นคุณสามารถลบออกได้

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

หรือหากคุณหวาดระแวงว่ามันอาจปรากฏขึ้นตรงกลางหรือต้องการเพิ่มขนาดเล็ก:

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

4

หากชื่อไฟล์มีไดเรกทอรีและคุณไม่จำเป็นต้องสูญเสียไดเรกทอรี:

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


1

เพียงเพื่อบันทึก:

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

วิธีนี้คุณไม่ได้ใช้แต่StringBuilder String.Join()โปรดสังเกตว่าPath.GetFileNameWithoutExtension()ต้องการเส้นทางที่เต็ม ( fi.FullName) ไม่ใช่fi.Nameอย่างที่ฉันเห็นในคำตอบข้อหนึ่ง


-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
ดูเหมือนคุณจะไม่ทราบว่ามีคลาส Framework ที่ทำให้คุณได้แล้ว
Andrew Barber

3
นอกจากนี้หากมีคนตั้งชื่อไฟล์ของพวกเขา "Current.XLSFiles.xls" สิ่งนี้จะทำให้เกิดปัญหาจริง
Tom Padilla

@ TomPadilla เหตุใดจึงทำให้เกิดปัญหา
Luke101

เพราะวิธีนี้จะนำเสนอ "Current.files" เป็นชื่อไฟล์ เพราะทุกอินสแตนซ์ของ ".xls" จะถูกแทนที่ด้วย "" รวมถึงที่อยู่ตรงกลางของชื่อ
Tom Padilla
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.