Saya ingin memasukkan fungsi mengubah nama file batch dalam aplikasi saya. Seorang pengguna dapat mengetikkan pola nama tujuan dan (setelah mengganti beberapa wildcard dalam pola) Saya perlu memeriksa apakah itu akan menjadi nama file yang sah di Windows. Saya sudah mencoba menggunakan ekspresi reguler seperti [a-zA-Z0-9_]+
tetapi tidak menyertakan banyak karakter khusus nasional dari berbagai bahasa (mis. Umlauts dan sebagainya). Apa cara terbaik untuk melakukan pemeriksaan seperti itu?
c#
windows
file
filesystems
Tomash
sumber
sumber
Jawaban:
Anda bisa mendapatkan daftar karakter yang tidak valid dari
Path.GetInvalidPathChars
danGetInvalidFileNameChars
.UPD: Lihat saran Steve Cooper tentang cara menggunakannya dalam ekspresi reguler.
UPD2: Perhatikan bahwa menurut bagian Catatan di MSDN "Array yang dikembalikan dari metode ini tidak dijamin mengandung set karakter lengkap yang tidak valid dalam nama file dan direktori." Jawaban yang diberikan oleh sixlettervaliables masuk ke rincian lebih lanjut.
sumber
Dari "Penamaan File atau Direktori" MSDN, berikut adalah konvensi umum untuk nama file hukum apa di bawah Windows:
Anda dapat menggunakan karakter apa pun di halaman kode saat ini (Unicode / ANSI di atas 127), kecuali:
<
>
:
"
/
\
|
?
*
Beberapa hal opsional untuk diperiksa:
\?\
awalan)\?\
(perhatikan bahwa awalan dapat memperluas komponen direktori dan menyebabkannya melebihi batas 32.000)sumber
Regex unspupportedRegex = new Regex("(^(PRN|AUX|NUL|CON|COM[1-9]|LPT[1-9]|(\\.+)$)(\\..*)?$)|(([\\x00-\\x1f\\\\?*:\";|/<>])+)|(([\\. ]+)", RegexOptions.IgnoreCase);
^(?!^(?:PRN|AUX|CLOCK\$|NUL|CON|COM\d|LPT\d)(?:\..+)?$)(?:\.*?(?!\.))[^\x00-\x1f\\?*:\";|\/<>]+(?<![\s.])$
Untuk .Net Frameworks sebelum 3.5 ini seharusnya berfungsi:
Pencocokan ekspresi reguler akan membantu Anda. Berikut cuplikan menggunakan
System.IO.Path.InvalidPathChars
konstanta;Untuk .Net Frameworks setelah 3.0 ini seharusnya berfungsi:
http://msdn.microsoft.com/en-us/library/system.io.path.getinvalidpathchars(v=vs.90).aspx
Pencocokan ekspresi reguler akan membantu Anda. Berikut cuplikan menggunakan
System.IO.Path.GetInvalidPathChars()
konstanta;Setelah Anda tahu itu, Anda juga harus memeriksa format yang berbeda, misalnya
c:\my\drive
dan\\server\share\dir\file.ext
sumber
Cobalah untuk menggunakannya, dan jebak kesalahannya. Perangkat yang diizinkan dapat berubah di seluruh sistem file, atau di berbagai versi Windows. Dengan kata lain, jika Anda ingin tahu apakah Windows menyukai namanya, berikan nama itu dan beri tahu.
sumber
Kelas ini membersihkan nama file dan jalur; gunakan seperti
Ini kodenya;
sumber
Inilah yang saya gunakan:
Pola pertama membuat ekspresi reguler yang berisi nama file dan karakter yang tidak valid / ilegal hanya untuk platform Windows. Yang kedua melakukan hal yang sama tetapi memastikan bahwa nama tersebut legal untuk platform apa pun.
sumber
@"^(?!(?:PRN|AUX|CLOCK\$|NUL|CON|COM\d|LPT\d)(?:\..+)?$)[^\x00-\x1F\xA5\\?*:\"";|\/<>]+(?<![\s.])$"
Satu hal yang perlu diingat, yang mengejutkan saya ketika saya pertama kali mengetahuinya: Windows memungkinkan karakter ruang terkemuka dalam nama file! Misalnya, berikut ini semua nama file yang sah dan berbeda pada Windows (minus tanda kutip):
Satu hal yang bisa diambil dari ini: Berhati-hatilah saat menulis kode yang memotong spasi spasi awal / akhir dari string nama file.
sumber
Menyederhanakan jawaban Eugene Katz:
Atau
sumber
Path.GetInvalidFileNameChars
. Lihatlah di sini: Referenceource.microsoft.com/#mscorlib/system/io/path.cs,299 - untuk setiap karakter AndafileName
, klon dari array dibuat.Microsoft Windows: Kernel Windows melarang penggunaan karakter dalam rentang 1-31 (yaitu, 0x01-0x1F) dan karakter "*: <>? \ |. Meskipun NTFS memungkinkan setiap komponen jalur (direktori atau nama file) panjangnya 255 karakter dan panjang jalur hingga sekitar 32.767 karakter, kernel Windows hanya mendukung jalur hingga 259 karakter. Selain itu, Windows melarang penggunaan nama perangkat MS-DOS AUX, CLOCK $, COM1, COM2, COM3, COM4, COM5, COM6, COM7, COM8, COM9, CON, LPT1, LPT2, LPT3, LPT4, LPT5, LPT6, LPT7, LPT8, LPT9, NUL dan PRN, serta nama-nama ini dengan ekstensi apa pun (misalnya, AUX.txt), kecuali saat menggunakan Lintasan UNC panjang (mis. \. \ C: \ nul.txt atau \? \ D: \ aux \ con). (Faktanya, CLOCK $ dapat digunakan jika ekstensi diberikan.) Pembatasan ini hanya berlaku untuk Windows - Linux, misalnya, memungkinkan penggunaan "*: <>? \ | bahkan dalam NTFS.
Sumber: http://en.wikipedia.org/wiki/Filename
sumber
Daripada secara eksplisit memasukkan semua karakter yang mungkin, Anda bisa melakukan regex untuk memeriksa keberadaan karakter ilegal, dan melaporkan kesalahan saat itu. Idealnya aplikasi Anda harus memberi nama file persis seperti yang diinginkan pengguna, dan hanya menangis busuk jika menemukan kesalahan.
sumber
Pertanyaannya adalah apakah Anda mencoba menentukan apakah nama jalur adalah jalur jendela yang sah, atau apakah itu sah pada sistem tempat kode tersebut berjalan.? Saya pikir yang terakhir lebih penting, jadi secara pribadi, saya mungkin akan menguraikan path lengkap dan mencoba menggunakan _mkdir untuk membuat direktori milik file, kemudian mencoba untuk membuat file.
Dengan cara ini Anda tahu tidak hanya jika path hanya berisi karakter windows yang valid, tetapi jika itu benar-benar mewakili path yang dapat ditulis oleh proses ini.
sumber
Saya menggunakan ini untuk menyingkirkan karakter yang tidak valid dalam nama file tanpa memberikan pengecualian:
sumber
Juga CON, PRN, AUX, NUL, COM # dan beberapa lainnya tidak pernah nama file hukum dalam direktori apa pun dengan ekstensi apa pun.
sumber
Untuk melengkapi jawaban lain, berikut adalah beberapa kasus tepi tambahan yang mungkin ingin Anda pertimbangkan.
Excel dapat mengalami masalah jika Anda menyimpan buku kerja dalam file yang namanya berisi karakter '[' atau ']'. Lihat http://support.microsoft.com/kb/215205 untuk detailnya.
Sharepoint memiliki serangkaian batasan tambahan. Lihat http://support.microsoft.com/kb/905231 untuk detailnya.
sumber
Dari MSDN , berikut daftar karakter yang tidak diizinkan:
sumber
Sistem file tujuan juga penting.
Di bawah NTFS, beberapa file tidak dapat dibuat di direktori tertentu. EG $ Boot di root
sumber
$Boot
sudah ada di direktori?Ini adalah pertanyaan yang sudah dijawab, tetapi hanya demi "Pilihan lain", berikut ini adalah pertanyaan yang tidak ideal:
(tidak ideal karena menggunakan Pengecualian sebagai kontrol aliran adalah "Hal Buruk", umumnya)
sumber
true
.Ekspresi reguler berlebihan untuk situasi ini. Anda dapat menggunakan
String.IndexOfAny()
metode ini dalam kombinasi denganPath.GetInvalidPathChars()
danPath.GetInvalidFileNameChars()
.Perhatikan juga bahwa kedua
Path.GetInvalidXXX()
metode mengkloning array internal dan mengembalikan clone. Jadi, jika Anda akan sering melakukan ini (ribuan dan ribuan kali), Anda dapat menyimpan salinan array chars array yang tidak valid untuk digunakan kembali.sumber
Jika Anda hanya mencoba memeriksa apakah string yang menyimpan nama / jalur file Anda memiliki karakter yang tidak valid, metode tercepat yang saya temukan adalah menggunakan
Split()
untuk memecah nama file menjadi array bagian di mana pun ada karakter yang tidak valid. Jika hasilnya hanya array 1, tidak ada karakter yang tidak valid. :-)Saya mencoba menjalankan ini dan metode lain yang disebutkan di atas pada nama file / path 1.000.000 kali di LinqPad.
Menggunakan
Split()
hanya ~ 850ms.Penggunaannya
Regex("[" + Regex.Escape(new string(System.IO.Path.GetInvalidPathChars())) + "]")
sekitar 6 detik.Ekspresi reguler yang lebih rumit jauh lebih buruk, seperti halnya beberapa opsi lain, seperti menggunakan berbagai metode di
Path
kelas untuk mendapatkan nama file dan membiarkan validasi internal mereka melakukan pekerjaan (kemungkinan besar karena overhead penanganan pengecualian).Memang tidak terlalu sering Anda perlu memvalidasi 1 juta nama file, jadi iterasi tunggal tidak masalah untuk sebagian besar metode ini. Tapi itu masih cukup efisien dan efektif jika Anda hanya mencari karakter yang tidak valid.
sumber
banyak dari jawaban ini tidak akan berfungsi jika nama file terlalu panjang & berjalan di lingkungan pra Windows 10. Demikian pula, pikirkan tentang apa yang ingin Anda lakukan dengan titik - memungkinkan memimpin atau mengekor secara teknis valid, tetapi dapat membuat masalah jika Anda tidak ingin file menjadi sulit dilihat atau dihapus masing-masing.
Ini adalah atribut validasi yang saya buat untuk memeriksa nama file yang valid.
dan tes
sumber
Usaha saya:
Ini tidak sempurna karena
Path.GetInvalidPathChars
tidak mengembalikan set karakter lengkap yang tidak valid dalam nama file dan direktori dan tentu saja ada banyak lagi kehalusan.Jadi saya menggunakan metode ini sebagai pelengkap:
Mencoba membuat file dan mengembalikan false jika ada pengecualian. Tentu saja, saya perlu membuat file tetapi saya pikir itu cara paling aman untuk melakukannya. Harap perhatikan juga bahwa saya tidak menghapus direktori yang telah dibuat.
Anda juga dapat menggunakan metode pertama untuk melakukan validasi dasar, dan kemudian menangani dengan hati-hati pengecualian saat jalur digunakan.
sumber
Saya sarankan gunakan saja Path.GetFullPath ()
sumber
Saya mendapat ide ini dari seseorang. - tidak tahu siapa. Biarkan OS melakukan angkat berat.
sumber
Cek ini
filter nama-nama dengan karakter yang tidak valid (
<>:"/\|?*
dan ASCII 0-31), serta perangkat DOS dilindungi (CON
,NUL
,COMx
). Ini memungkinkan spasi dan semua nama titik terkemuka, konsisten denganPath.GetFullPath
. (Membuat file dengan spasi terdepan berhasil di sistem saya).Digunakan .NET Framework 4.7.1, diuji pada Windows 7.
sumber
Satu liner untuk memverifikasi karakter ilegal di string:
sumber
Menurut pendapat saya, satu-satunya jawaban yang tepat untuk pertanyaan ini adalah mencoba menggunakan path dan membiarkan OS dan sistem file memvalidasinya. Kalau tidak, Anda hanya mengimplementasikan ulang (dan mungkin buruk) semua aturan validasi yang sudah digunakan OS dan sistem file dan jika aturan itu diubah di masa depan Anda harus mengubah kode Anda agar cocok dengan mereka.
sumber
Jendela nama file cukup unrestrictive, sehingga benar-benar bahkan tidak mungkin bahwa banyak masalah. Karakter yang dilarang oleh Windows adalah:
Anda dapat dengan mudah menulis ekspresi untuk memeriksa apakah karakter tersebut ada. Solusi yang lebih baik adalah dengan mencoba dan memberi nama file sesuai keinginan pengguna, dan mengingatkan mereka ketika nama file tidak menempel.
sumber