Saya mencoba menggunakan Directory.GetFiles()
metode ini untuk mengambil daftar file dari berbagai jenis, seperti mp3
's dan jpg
' s. Saya telah mencoba kedua hal berikut tanpa hasil:
Directory.GetFiles("C:\\path", "*.mp3|*.jpg", SearchOption.AllDirectories);
Directory.GetFiles("C:\\path", "*.mp3;*.jpg", SearchOption.AllDirectories);
Apakah ada cara untuk melakukan ini dalam satu panggilan?
c#
filesystems
.net
Jason Z
sumber
sumber
Jawaban:
Untuk .NET 4.0 dan yang lebih baru,
Untuk versi .NET yang lebih lama,
sunting: Silakan baca komentar. Peningkatan yang disarankan Paul Farry , dan masalah memori / kinerja yang ditunjukkan Christian.K sama-sama sangat penting.
sumber
s.ToLower().Endswith...
s.EndsWith(".mp3", StringComparison.OrdinalIgnoreCase)
Directory.GetFiles
denganDirectory.EnumerateFiles
, msdn.microsoft.com/en-us/library/dd383571.aspx , yang akan menghindari masalah memori yang disebutkan @ Christian.K.Bagaimana dengan ini:
Saya menemukannya di sini (dalam komentar): http://msdn.microsoft.com/en-us/library/wz42302f.aspx
sumber
Parallel.ForEach
untuk membuatnya secara paralelJika Anda memiliki daftar ekstensi yang besar untuk diperiksa, Anda dapat menggunakan yang berikut ini. Saya tidak ingin membuat banyak pernyataan ATAU jadi saya memodifikasi apa yang ditulis lette.
sumber
Path.GetExtension
mengembalikan '.ext', bukan '* .ext' (setidaknya dalam 3,5+)..abc
, dan didukung oleh Exttensions.abcd
. Akan cocok, meskipun seharusnya tidak. Untuk memperbaiki:supportedExtensions = ".jpg|.abcd|";
dengan.Contains(Path.GetExtension(s).ToLower() + "|")
. Artinya, sertakan karakter pemisah Anda dalam ujian. PENTING: karakter pemisah Anda juga harus setelah entri TERAKHIR di didukungExceptions.untuk
Anda bisa:
Directory.EnumerateFiles
untuk peningkatan kinerja ( Apa perbedaan antara Directory.EnumerateFiles vs Directory.GetFiles? ).EndsWith("aspx", StringComparison.OrdinalIgnoreCase)
daripada.ToLower().EndsWith("aspx")
)Tetapi manfaat nyata dari
EnumerateFiles
muncul ketika Anda membagi filter dan menggabungkan hasilnya:Ini akan menjadi sedikit lebih cepat jika Anda tidak harus mengubahnya menjadi gumpalan (yaitu
exts = new[] {"*.mp3", "*.jpg"}
sudah).Evaluasi kinerja berdasarkan tes LinqPad berikut (catatan:
Perf
cukup ulangi delegasi 10.000 kali) https://gist.github.com/zaus/7454021(mem-posting ulang dan meluas dari 'duplikat' karena pertanyaan itu secara khusus tidak meminta LINQ: Beberapa file-ekstensi searchPattern untuk System.IO.Directory.GetFiles )
sumber
.FilterFiles(path, "jpg", "gif")
) lebih baik daripada "gumpalan eksplisit" (yaitu.FilterFiles(path, "*.jpg", "*.gif")
).Saya tahu ini pertanyaan lama tapi LINQ: (.NET40 +)
sumber
file.ToLower()
untuk menggunakan dengan mudah mencocokkan ekstensi huruf besar. Dan mengapa tidak mengekstrak ekstensi terlebih dahulu, jadi Regex tidak harus memeriksa seluruh jalur:Regex.IsMatch(Path.GetExtension(file).ToLower(), @"\.(wav|mp3|txt)");
Ada juga solusi keturunan yang tampaknya tidak memiliki memori atau kinerja overhead dan cukup elegan:
sumber
Cara lain untuk menggunakan Linq, tetapi tanpa harus mengembalikan semuanya dan memfilternya dalam memori.
Ini sebenarnya 2 panggilan untuk
GetFiles()
, tetapi saya pikir itu konsisten dengan semangat pertanyaan dan mengembalikannya dalam satu enumerable.sumber
Nggak. Coba yang berikut ini:
Diambil dari: http://blogs.msdn.com/markda/archive/2006/04/20/580075.aspx
sumber
Membiarkan
Kemudian
atau
sumber
Saya tidak dapat menggunakan
.Where
metode karena saya pemrograman dalam .NET Framework 2.0 (Linq hanya didukung dalam .NET Framework 3.5+).Kode di bawah ini tidak peka huruf besar-kecil (jadi
.CaB
atau.cab
akan dicantumkan juga).sumber
Fungsi berikut mencari beberapa pola, dipisahkan dengan koma. Anda juga dapat menentukan pengecualian, misalnya: "! Web.config" akan mencari semua file dan mengecualikan "web.config". Pola bisa dicampur.
Pemakaian:
sumber
sumber
file.Extension.ToLower()
adalah praktik yang buruk.String.Equals(a, b, StringComparison.OrdinalIgnoreCase)
di .NET 2.0 (tanpa Linq):
Kemudian gunakan:
sumber
sumber
Baru saja menemukan cara lain untuk melakukannya. Masih bukan satu operasi, tetapi membuangnya untuk melihat apa yang dipikirkan orang lain tentang itu.
sumber
Bagaimana dengan
sumber
Buat ekstensi yang Anda inginkan satu string yaitu ".mp3.jpg.wma.wmf" dan kemudian periksa apakah setiap file berisi ekstensi yang Anda inginkan. Ini berfungsi dengan .net 2.0 karena tidak menggunakan LINQ.
Keuntungan dengan pendekatan ini adalah Anda dapat menambah atau menghapus ekstensi tanpa mengedit kode yaitu untuk menambahkan gambar png, cukup tulis myExtensions = ". Jpg.mp3.png".
sumber
s
sumber
Tidak ... Saya yakin Anda harus membuat panggilan sebanyak jenis file yang Anda inginkan.
Saya akan membuat fungsi sendiri mengambil array pada string dengan ekstensi yang saya butuhkan dan kemudian beralih pada array yang membuat semua panggilan yang diperlukan. Fungsi itu akan mengembalikan daftar umum file yang cocok dengan ekstensi yang saya kirim.
Semoga ini bisa membantu.
sumber
Saya memiliki masalah yang sama dan tidak dapat menemukan solusi yang tepat jadi saya menulis fungsi yang disebut GetFiles:
Fungsi ini akan memanggil
Directory.Getfiles()
hanya satu kali.Misalnya, panggil fungsi seperti ini:
EDIT: Untuk mendapatkan satu file dengan banyak ekstensi gunakan yang ini:
Misalnya, panggil fungsi seperti ini:
sumber
Saya bertanya-tanya mengapa ada begitu banyak "solusi" yang diposting?
Jika pemahaman pemula saya tentang cara kerja GetFiles benar, hanya ada dua opsi dan salah satu solusi di atas dapat dibawa ke ini:
GetFiles, lalu filter: Cepat, tetapi seorang pembunuh memori karena menyimpan overhead sampai filter diterapkan
Saring sementara GetFiles: Lebih lambat filter lebih banyak ditetapkan, tetapi penggunaan memori rendah karena tidak ada overhead yang disimpan.
Ini dijelaskan dalam salah satu posting di atas dengan patokan yang mengesankan: Setiap opsi filter menyebabkan operasi GetFile yang terpisah sehingga bagian yang sama dari harddisk dibaca beberapa kali.
Menurut pendapat saya Opsi 1) lebih baik, tetapi menggunakan Direktori SearchOption.AllDirectories pada folder seperti C: \ akan menggunakan memori dalam jumlah besar.
Oleh karena itu saya hanya akan membuat sub-metode rekursif yang melewati semua subfolder menggunakan opsi 1)
Ini seharusnya menyebabkan hanya 1 GetFiles-operasi pada setiap folder dan karenanya menjadi cepat (Opsi 1), tetapi hanya menggunakan sedikit memori karena filter diterapkan setelah pembacaan masing-masing subfolder -> overhead dihapus setelah masing-masing subfolder.
Tolong koreksi saya jika saya salah. Saya seperti yang saya katakan cukup baru untuk pemrograman tetapi ingin mendapatkan pemahaman yang lebih mendalam tentang hal-hal yang akhirnya menjadi baik dalam hal ini :)
sumber
Jika Anda menggunakan VB.NET (atau mengimpor ketergantungan ke proyek C # Anda), sebenarnya ada metode kenyamanan yang memungkinkan untuk memfilter beberapa ekstensi:
Di VB.NET ini dapat diakses melalui My-namespace:
Sayangnya, metode kenyamanan ini tidak mendukung varian malas yang dievaluasi seperti
Directory.EnumerateFiles()
halnya.sumber
saya tidak tahu solusi apa yang lebih baik, tetapi saya menggunakan ini:
sumber
Berikut adalah cara sederhana dan elegan untuk mendapatkan file yang difilter
sumber
Atau Anda bisa mengonversi string ekstensi ke String ^
sumber
Menggunakan pola pencarian GetFiles untuk memfilter ekstensi tidak aman !! Misalnya Anda memiliki dua file Test1.xls dan Test2.xlsx dan Anda ingin memfilter file xls menggunakan pola pencarian * .xls, tetapi GetFiles mengembalikan kedua Test1.xls dan Test2.xlsx Saya tidak mengetahui hal ini dan mendapatkan kesalahan dalam produksi lingkungan ketika beberapa file sementara tiba-tiba ditangani sebagai file yang benar. Pola pencarian adalah * .txt dan file temp bernama * .txt20181028_100753898 Jadi pola pencarian tidak dapat dipercaya, Anda harus menambahkan pemeriksaan tambahan pada nama file juga.
sumber