ห้ามใช้อักขระใดในชื่อไดเรกทอรี Windows และ Linux


356

ฉันรู้ว่า / ผิดกฎหมายใน Linux และต่อไปนี้ผิดกฎหมายใน Windows (ฉันคิดว่า) * . " / \ [ ] : ; | ,

มีอะไรอีกบ้างที่ขาดหายไป?

ฉันต้องการคู่มือที่ครอบคลุมและสิ่งที่ต้องคำนึงถึงอักขระแบบไบต์คู่ การเชื่อมโยงไปยังแหล่งข้อมูลภายนอกเป็นสิ่งที่ดีสำหรับฉัน

ฉันต้องสร้างไดเรกทอรีบนระบบแฟ้มก่อนโดยใช้ชื่อที่อาจมีอักขระต้องห้ามดังนั้นฉันวางแผนที่จะแทนที่อักขระเหล่านั้นด้วยเครื่องหมายขีดล่าง ฉันต้องเขียนไดเรกทอรีนี้และเนื้อหาในไฟล์ zip (โดยใช้ Java) ดังนั้นคำแนะนำเพิ่มเติมใด ๆ ที่เกี่ยวข้องกับชื่อของไดเรกทอรี zip จะได้รับการชื่นชม


13
ตัวละครบางตัวที่คุณพูดถึงนั้นได้รับอนุญาตใน Windows ตรวจสอบสิ่งนี้:echo abc > "ab.;,=[1]"
dolmen

3
นอกจากนี้อย่าลืม <และ> ผิดกฎหมายใน Windows
AnotherParker

4
/ ไม่ผิดกฎหมายใน Linux คุณต้องหนีมันด้วย a \ เมื่อพิมพ์เข้าไป
เดวิดซีบิชอป

5
@ DavidC.Bishop: ข้อความนี้ยืนยันว่าเคอร์เนล Linux จะป้องกันไม่ให้คุณทำงานกับชื่อไฟล์ที่มีเครื่องหมายทับ คุณสามารถใช้งานได้หรือไม่
Soren Bjornstad

15
"/ ไม่ใช่สิ่งผิดกฎหมายใน Linux คุณเพียง แต่ต้องใช้เครื่องหมาย \ เมื่อพิมพ์ลงใน" - คำสั่งนี้ผิดอย่างสมบูรณ์ องค์ประกอบชื่อไฟล์ไม่สามารถมี / และการหลบหนีไม่มีผลกระทบ
Jim Balter

คำตอบ:


216

"คำแนะนำที่ครอบคลุม" ของตัวอักษรชื่อไฟล์ต้องห้ามจะไม่สามารถใช้งานได้บน Windows เพราะมันจะสงวนชื่อไฟล์และตัวละคร ใช่* " ?มีการห้ามไม่ให้ใช้อักขระเช่น และอื่น ๆ แต่มีชื่อไม่ จำกัด จำนวนซึ่งประกอบด้วยอักขระที่ถูกต้องเท่านั้นที่ต้องห้าม ตัวอย่างเช่นช่องว่างและจุดเป็นอักขระชื่อไฟล์ที่ถูกต้อง แต่ห้ามใช้ชื่อที่ประกอบด้วยอักขระเหล่านั้นเท่านั้น

Windows ไม่แยกความแตกต่างระหว่างอักขระตัวพิมพ์ใหญ่และตัวพิมพ์เล็กดังนั้นคุณจึงไม่สามารถสร้างโฟลเดอร์ที่มีชื่อAหากมีชื่อaอยู่แล้ว ชื่อที่ดูเหมือนอนุญาตPRNและแย่กว่านั้นและชื่อCONอื่น ๆ อีกมากมายถูกสงวนไว้และไม่ได้รับอนุญาต Windows มีข้อจำกัดความยาวหลายประการเช่นกัน ชื่อไฟล์ที่ถูกต้องในโฟลเดอร์หนึ่งอาจไม่ถูกต้องหากย้ายไปยังโฟลเดอร์อื่น กฎสำหรับ การตั้งชื่อไฟล์และโฟลเดอร์ อยู่ในเอกสารของ Microsoft

โดยทั่วไปคุณไม่สามารถใช้ข้อความที่ผู้ใช้สร้างขึ้นเพื่อสร้างชื่อไดเรกทอรี Windows ได้ หากคุณต้องการที่จะช่วยให้ผู้ใช้เพื่ออะไรชื่อที่พวกเขาต้องการที่คุณต้องสร้างชื่อที่ปลอดภัยเช่นA, AB, A2et al., ร้านค้าชื่อที่ผู้ใช้สร้างและรายการเทียบเท่าเส้นทางของพวกเขาในแฟ้มข้อมูลใบสมัครและดำเนินการทำแผนที่เส้นทางในการประยุกต์ใช้ของคุณ

หากคุณต้องอนุญาตชื่อโฟลเดอร์ที่ผู้ใช้สร้างขึ้นวิธีเดียวที่จะบอกได้ว่าชื่อโฟลเดอร์นั้นไม่ถูกต้องคือการตรวจจับข้อยกเว้นและถือว่าชื่อนั้นไม่ถูกต้อง แม้จะเต็มไปด้วยอันตรายเนื่องจากข้อยกเว้นที่เกิดจากการเข้าถึงที่ถูกปฏิเสธไดรฟ์ออฟไลน์และพื้นที่ว่างบนไดรฟ์ทับซ้อนกับที่สามารถโยนทิ้งได้สำหรับชื่อที่ไม่ถูกต้อง คุณกำลังเปิดรับความเจ็บปวดอย่างมาก


11
วลีสำคัญจากลิงก์ MSDN คือ "[และ] อักขระอื่น ๆ ที่ระบบไฟล์เป้าหมายไม่อนุญาต" อาจมีระบบไฟล์ต่างกันใน Windows บางคนอาจอนุญาตให้ Unicode บางคนอาจไม่ โดยทั่วไปวิธีเดียวที่ปลอดภัยในการตรวจสอบชื่อคือลองใช้กับอุปกรณ์เป้าหมาย
Adrian McCarthy

72
มีแนวทางบางอย่างและ“ มีชื่อไม่ จำกัด จำนวนที่ประกอบด้วยอักขระที่ถูกต้องซึ่งต้องห้ามเท่านั้น”นั้นไม่สร้างสรรค์ ในทำนองเดียวกัน“Windows ไม่แยกแยะระหว่างกรณีบนและล่างกรณีตัวละคร”เป็นข้อยกเว้นที่โง่ - OP จะขอเกี่ยวกับไวยากรณ์และไม่ได้ความหมายและไม่มีคนที่เหมาะสมที่มีใจจะบอกว่าชื่อไฟล์เช่นA.txtเป็นที่ไม่ถูกต้องเพราะa.TXTอาจมีอยู่
Borodin

9
COPY CON PRNหมายถึงอ่านจากอินพุตคีย์บอร์ดหรือ stdin ที่เป็นไปได้และคัดลอกไปยังอุปกรณ์เครื่องพิมพ์ ไม่แน่ใจว่ายังคงใช้ได้กับหน้าต่างที่ทันสมัย ​​แต่แน่นอนว่าเป็นเวลานาน ในสมัยก่อนคุณสามารถใช้มันเพื่อพิมพ์ข้อความและมีเครื่องพิมพ์ดอทเมทริกซ์ก็เอาท์พุทมัน
AntonPiatek

6
"ไม่สร้างสรรค์" - ตรงกันข้ามมันเป็นความจริง สิ่งที่ไม่สร้างสรรค์คือความทะนงของ Borodin
Jim Balter

3
"โดยทั่วไปคุณไม่สามารถใช้ข้อความที่ผู้ใช้สร้างขึ้นเพื่อสร้างชื่อไดเรกทอรี Windows ได้" <- หากคุณต้องการทำสิ่งนี้คุณสามารถมีบัญชีตัวละครที่ได้รับอนุญาตและส่วนใหญ่จะใช้ได้ถ้าคุณสามารถเพิกเฉยต่อปัญหาที่มีอยู่แล้วได้
Casey

534

ให้มันง่ายและตอบคำถามก่อน

  1. ห้ามใช้อักขระ ASCII ที่พิมพ์ได้:

    • Linux / Unix:

      / (forward slash)
      
    • ของ windows:

      < (less than)
      > (greater than)
      : (colon - sometimes works, but is actually NTFS Alternate Data Streams)
      " (double quote)
      / (forward slash)
      \ (backslash)
      | (vertical bar or pipe)
      ? (question mark)
      * (asterisk)
      
  2. อักขระที่ไม่สามารถพิมพ์ได้

    หากข้อมูลของคุณมาจากแหล่งที่จะอนุญาตให้ใช้อักขระที่ไม่สามารถพิมพ์ได้จะมีการตรวจสอบอีกมาก

    • Linux / Unix:

      0 (NULL byte)
      
    • ของ windows:

      0-31 (ASCII control characters)
      

    บันทึก:ขณะที่มันเป็นกฎหมายภายใต้ระบบไฟล์ Linux / Unix เพื่อสร้างไฟล์ที่มีการควบคุมตัวอักษรในชื่อไฟล์, มันอาจจะเป็นฝันร้ายสำหรับผู้ใช้ในการจัดการกับไฟล์ดังกล่าว

  3. ชื่อไฟล์ที่สงวนไว้

    สงวนชื่อไฟล์ต่อไปนี้:

    • ของ windows:

      CON, PRN, AUX, NUL 
      COM1, COM2, COM3, COM4, COM5, COM6, COM7, COM8, COM9
      LPT1, LPT2, LPT3, LPT4, LPT5, LPT6, LPT7, LPT8, LPT9
      

      (ทั้งของตัวเองและนามสกุลไฟล์โดยพลการเช่นLPT1.txt)

  4. กฎอื่น ๆ

    • ของ windows:

      ชื่อไฟล์ต้องไม่ลงท้ายด้วยช่องว่างหรือจุด


5
ระบบไฟล์ Windows ส่วนใหญ่ไม่ได้ จำกัด อยู่ที่ 8 บิต มีอักขระ 8 บิตอื่น ๆ อีกมากมาย (NUL อักขระควบคุม) ซึ่งถูกห้ามบน Windows แม้การพิจารณาสิ่งเหล่านั้นจะไม่อนุญาตให้ผู้ถาม“ สร้างไดเรกทอรีบนระบบไฟล์” เนื่องจากเขาถามเพราะมีชื่อไดเรกทอรีที่ไม่ถูกต้องซึ่งประกอบด้วยอักขระที่ไม่ได้รับอนุญาตจำนวนนับไม่ถ้วน
Dour High Arch

38
คนอื่น ๆ บอกไปแล้วและมันก็ไม่ได้สร้างสรรค์ เมื่อฉันมาที่นี่เพื่อค้นหาคำตอบฉันต้องการรายการที่ฉันต้องรวบรวมที่อื่น: ตัวอักษรใดที่จะกรองออกจากการป้อนข้อมูลของผู้ใช้เมื่อสร้างความพยายามที่ดีในชื่อไฟล์ที่ถูกต้อง คำถามที่ว่าตัวละครด้วยกันกลายเป็นไม่ถูกต้องก็ต้องมีรายละเอียดบางอย่าง
Christopher Oezbek

5
ห้ามใช้อักขระ NULL บน Linux
Dan Jones

3
บรรทัดใหม่ไม่ถูกแบนบน Linux ฉันเถียงว่ามันควรจะเป็นแม้ว่า ... และถ้า NUL ถูกแบนบนลีนุกซ์มันก็ถูกแบนบน Windows มันเติมเต็มจุดประสงค์เดียวกัน
Alcaro

11
@Soaku: แน่นอนไม่ใช่เพราะโลกไม่ได้หมุนรอบ Microsoft ทำไมต้องเพิ่มข้อ จำกัด ที่ไม่จำเป็นเมื่อมีเพียงสองตัวอักษรที่จำเป็นต้องห้ามอย่างยิ่ง?
firegurafiku

68

ภายใต้ Linux และระบบอื่น ๆ ที่เกี่ยวข้องกับ Unix มีเพียงสองตัวอักษรที่ไม่สามารถปรากฏในชื่อของไฟล์หรือไดเรกทอรีและเป็น NUL '\0'และเครื่องหมายทับ'/'และเฉือนสแลชแน่นอนสามารถปรากฏในชื่อพา ธ การแยกส่วนประกอบไดเรกทอรี

ข่าวลือ1บอกว่า Steven Bourne (จาก 'shell' fame) มีไดเรกทอรีที่มีไฟล์ 254 ไฟล์หนึ่งไฟล์สำหรับตัวอักษรเดี่ยวทุกตัว (รหัสอักขระ) ที่สามารถปรากฏในชื่อไฟล์ (ยกเว้น/, '\0'; ชื่อ.เป็นไดเรกทอรีปัจจุบันแน่นอน ) มันถูกใช้เพื่อทดสอบบอร์นเชลล์และความเสียหายที่เกิดขึ้นเป็นประจำบนโปรแกรมที่ไม่ระวังเช่นโปรแกรมสำรองข้อมูล

คนอื่น ๆ ได้ครอบคลุมกฎ Windows

โปรดทราบว่า MacOS X มีระบบไฟล์แบบไม่ตรงตามตัวพิมพ์ใหญ่และตัวพิมพ์เล็ก


1มันเป็น Kernighan & Pike ในการฝึกเขียนโปรแกรมซึ่งพูดมากในบทที่ 6 การทดสอบ§6.5การทดสอบความเครียด:

เมื่อ Steve Bourne เขียน Unix shell ของเขา (ซึ่งรู้จักกันในชื่อ Bourne shell) เขาสร้างไดเรคทอรี่ของไฟล์จำนวน 254 ไฟล์ที่มีชื่อตัวละครหนึ่งตัวสำหรับแต่ละค่าไบต์ยกเว้น'\0'และเครื่องหมายทับอักขระสองตัวที่ไม่ปรากฏใน Unix ชื่อไฟล์ เขาใช้ไดเรกทอรีนั้นสำหรับการทดสอบรูปแบบการจับคู่รูปแบบและโทเค็นทั้งหมด (ไดเรกทอรีทดสอบนั้นแน่นอนสร้างขึ้นโดยโปรแกรม) สำหรับปีต่อ ๆ มาไดเรกทอรีนั้นคือความหายนะของโปรแกรมการเดินไฟล์ มันทดสอบพวกเขาถึงการทำลาย

โปรดทราบว่าไดเรกทอรีจะต้องมีรายการ.และ..ดังนั้นจึงเป็นเนื้อหา 253 ไฟล์ (และ 2 ไดเรกทอรี) หรือ 255 รายการชื่อมากกว่า 254 ไฟล์ สิ่งนี้จะไม่ส่งผลต่อประสิทธิภาพของเกร็ดเล็กเกร็ดน้อยหรือการทดสอบอย่างละเอียดที่อธิบาย


1
254 ไฟล์ แล้ว utf8 ล่ะ
j_kubik

20
ไฟล์ 254 เป็นชื่อไฟล์อักขระเดี่ยวทั้งหมดหนึ่งตัวต่ออักขระที่อนุญาตให้ใช้ในชื่อไฟล์ UTF-8 ไม่ได้เป็นประกายในสายตาเมื่อ Steve Bourne เขียน Bourne shell UTF-8 กำหนดกฎเกี่ยวกับลำดับที่ถูกต้องของไบต์ (และไม่อนุญาตให้ใช้ไบต์ 0xC0, 0xC1, 0xF5-0xFF พร้อมกัน) ไม่อย่างนั้นก็ไม่แตกต่างกันมากนัก - ในระดับรายละเอียดที่ฉันกำลังพูดถึง
Jonathan Leffler

1
ตัวแยกไดเรกทอรีบนดิสก์สำหรับระบบไฟล์ MacOS HFS + เป็นจริง ':' มากกว่า '/' ระบบปฏิบัติการมักจะ (อาจเสมอ) ทำสิ่งที่ถูกต้องเมื่อคุณทำงานกับ * nix API แต่อย่าคาดหวังว่าสิ่งนี้จะเกิดขึ้นอย่างน่าเชื่อถือหากคุณกำลังจะย้ายไปยังโลก OSX เช่นกับ applescript ดูเหมือนว่า Cocoa API อาจใช้ / และซ่อน: จากคุณเช่นกัน แต่ฉันค่อนข้างมั่นใจว่า Carbon API เก่าไม่ได้
Dan Pritts

@DanPritts ฉันสร้างรูปแบบตัวอักษร / สีที่กำหนดเองในการตั้งค่าของ Xcode โดยตั้งชื่อด้วย/ชื่อ ที่ก่อให้เกิดปัญหาบางอย่างตามที่มันสร้างไดเรกทอรีใหม่กับโครงการใน.
อันเดรีย

โปรดทราบว่าหากไดเรกทอรีมีเครื่องหมายโคลอนในชื่อคุณจะไม่สามารถเพิ่มไดเรกทอรีลงในPATHตัวแปรUnix ได้เนื่องจากมีการใช้โคลอนเป็นตัวคั่น (เครื่องหมายอัฒภาคบน Windows) ดังนั้นโปรแกรมในไดเรกทอรีดังกล่าวจะต้องเรียกใช้ด้วยชื่อพา ธ ที่ระบุว่ามันอยู่ที่ไหน (อาจเป็นแบบสัมพัทธ์หรือสัมบูรณ์) หรือคุณจะต้องอยู่ในไดเรกทอรีและมีจุด ( .ซึ่งเป็นไดเรกทอรีปัจจุบัน) ในPATHซึ่งได้รับการยอมรับอย่างกว้างขวางว่า ไม่ปลอดภัย
Jonathan Leffler

36

แทนที่จะสร้างบัญชีดำของตัวละครคุณสามารถใช้บัญชีขาวรายการที่อนุญาตทุกสิ่งที่พิจารณาช่วงของอักขระที่เหมาะสมในบริบทของไฟล์หรือชื่อไดเรกทอรีนั้นค่อนข้างสั้นและถ้าคุณมีข้อกำหนดการตั้งชื่อที่เฉพาะเจาะจงผู้ใช้ของคุณจะไม่เก็บมันไว้กับแอปพลิเคชันของคุณหากพวกเขาไม่สามารถใช้ตาราง ASCII ทั้งหมด

มันไม่ได้แก้ปัญหาชื่อที่สงวนไว้ในระบบไฟล์เป้าหมาย แต่ด้วยบัญชีขาวมันง่ายที่จะลดความเสี่ยงที่แหล่งที่มา

ในจิตวิญญาณนั้นนี่คือช่วงของตัวละครที่สามารถพิจารณาได้ว่าปลอดภัย:

  • ตัวอักษร (az AZ) - ตัวอักษร Unicode เช่นกันหากจำเป็น
  • ตัวเลข (0-9)
  • ขีดล่าง (_)
  • เครื่องหมายขีดกลาง (-)
  • ช่องว่าง
  • จุด (.)

และตัวละครที่ปลอดภัยเพิ่มเติมใด ๆ ที่คุณต้องการอนุญาต นอกเหนือจากนี้คุณก็ต้องบังคับใช้บางกฎระเบียบเพิ่มเติมเกี่ยวกับช่องว่างและจุด ซึ่งมักจะเพียงพอ:

  • ชื่อต้องมีตัวอักษรหรือตัวเลขอย่างน้อยหนึ่งตัว (เพื่อหลีกเลี่ยงจุด / ช่องว่างเท่านั้น)
  • ชื่อต้องเริ่มต้นด้วยตัวอักษรหรือตัวเลข (เพื่อหลีกเลี่ยงจุด / ช่องว่างนำหน้า)
  • ชื่ออาจไม่ลงท้ายด้วยจุดหรือช่องว่าง (เพียงตัดแต่งถ้ามีเช่น Explorer)

ชื่อนี้มีความซับซ้อนและไม่มีชื่ออยู่แล้ว ตัวอย่างเช่นชื่อเหล่านี้จะเป็นไปได้กับกฎเหล่านี้และเป็นชื่อไฟล์ที่ถูกต้องใน Windows / Linux:

  • A...........ext
  • B -.- .ext

ในสาระสำคัญแม้จะมีตัวละครที่อยู่ในบัญชีขาวเพียงไม่กี่ตัว แต่คุณก็ควรตัดสินใจว่าสิ่งใดสมเหตุสมผลและควรตรวจสอบ / ปรับชื่อให้เหมาะสม ในแอปพลิเคชันของฉันฉันใช้กฎเดียวกันกับข้างบน แต่ลอกจุดและช่องว่างที่ซ้ำกันออก


15
และสิ่งที่เกี่ยวกับผู้ใช้ที่ไม่พูดภาษาอังกฤษของฉันที่ทุกคนจะได้รับการเมาโดยนี้
pkh

2
@pkh: ตามที่ฉันพูดถึงในโพสต์ของฉันคุณจะต้องใส่อักขระ Unicode ที่จำเป็นในรายการที่อนุญาตของคุณ โดยปกติแล้วช่วงของอักขระสามารถระบุได้ค่อนข้างง่ายโดยเฉพาะถ้าคุณใช้นิพจน์ทั่วไป
AeonOfTime

2
เราใช้วิธี whitelist แต่อย่าลืมใน Windows คุณต้องจัดการสตริงที่สงวนและตัวพิมพ์เล็ก - ใหญ่เช่นชื่ออุปกรณ์ (prn, lpt1, con) และ และ ..
tahoar

2
คุณไม่ได้รับการ จำกัด Windows: ต้องไม่ลงท้ายด้วย dot หรือ space
Martin Bonner สนับสนุนโมนิก้า

1
"ทุกสิ่งที่ถูกพิจารณาช่วงของตัวละครที่สมเหตุสมผลในบริบทของไฟล์หรือชื่อไดเรกทอรีนั้นค่อนข้างสั้น" บางทีสำหรับกรณีการใช้งานบางอย่าง ฉันกำลังทำงานในโครงการที่เกี่ยวข้องกับไฟล์สื่อใน 20 ภาษาและชื่อไฟล์จำเป็นต้องสะท้อนถึงชื่อของรายการสื่อเพราะผู้ใช้จะค้นหาเนื้อหาในแบบนั้น ชื่อจำนวนมากใช้เครื่องหมายวรรคตอน ข้อ จำกัด ใด ๆ ของตัวละครชื่อไฟล์มีราคาดังนั้นในกรณีนี้เราต้องลดข้อ จำกัด ให้น้อยที่สุด ในกรณีที่ใช้งานนี้ช่วงของตัวละครที่ไม่สมเหตุสมผลในชื่อไฟล์นั้นสั้นกว่าและง่ายกว่าที่ทำ
LarsH

30

วิธีง่าย ๆ ในการทำให้ Windows บอกคำตอบคือพยายามเปลี่ยนชื่อไฟล์ผ่าน Explorer และพิมพ์ชื่อ / ใหม่ Windows จะป๊อปอัพกล่องข้อความบอกรายชื่อตัวละครที่ผิดกฎหมาย

A filename cannot contain any of the following characters:
    \ / : * ? " < > | 

https://support.microsoft.com/en-us/kb/177506


28

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

หากคุณต้องการที่จะเขียนฟังก์ชั่นแบบพกพาท่านผู้ใช้ตรวจสอบและสร้างชื่อไฟล์ขึ้นอยู่กับว่าคำตอบสั้น ๆไม่ได้ ลองดูโมดูลพกพาเช่น Perl's File :: Specเพื่อเหลือบไปที่ฮ็อพทั้งหมดที่จำเป็นในการทำภารกิจ "ง่าย ๆ " ให้สำเร็จ


5

สำหรับ Windows คุณสามารถตรวจสอบได้โดยใช้ PowerShell

$PathInvalidChars = [System.IO.Path]::GetInvalidPathChars() #36 chars

ในการแสดงรหัส UTF-8 คุณสามารถแปลงได้

$enc = [system.Text.Encoding]::UTF8
$PathInvalidChars | foreach { $enc.GetBytes($_) }

$FileNameInvalidChars = [System.IO.Path]::GetInvalidFileNameChars() #41 chars

$FileOnlyInvalidChars = @(':', '*', '?', '\', '/') #5 chars - as a difference

สำหรับผู้ที่ไม่พูด PowershelI, $ FileNameInvalidChars คือ 0x00 ถึง 0x1F และ: "<> | *? \ /
Robin Davies

4

ใน Windows 10 (2019) ห้ามใช้อักขระต่อไปนี้โดยมีข้อผิดพลาดเมื่อคุณพยายามพิมพ์:

ชื่อไฟล์ต้องไม่มีอักขระใด ๆ ต่อไปนี้:

\ / : * ? " < > |


3

นี่คือการติดตั้ง ac # สำหรับ windows ตามคำตอบของ Christopher Oezbek

มันถูกทำให้ซับซ้อนมากขึ้นโดยบูลีน containFolder แต่หวังว่าจะครอบคลุมทุกอย่าง

/// <summary>
/// This will replace invalid chars with underscores, there are also some reserved words that it adds underscore to
/// </summary>
/// <remarks>
/// /programming/1976007/what-characters-are-forbidden-in-windows-and-linux-directory-names
/// </remarks>
/// <param name="containsFolder">Pass in true if filename represents a folder\file (passing true will allow slash)</param>
public static string EscapeFilename_Windows(string filename, bool containsFolder = false)
{
    StringBuilder builder = new StringBuilder(filename.Length + 12);

    int index = 0;

    // Allow colon if it's part of the drive letter
    if (containsFolder)
    {
        Match match = Regex.Match(filename, @"^\s*[A-Z]:\\", RegexOptions.IgnoreCase);
        if (match.Success)
        {
            builder.Append(match.Value);
            index = match.Length;
        }
    }

    // Character substitutions
    for (int cntr = index; cntr < filename.Length; cntr++)
    {
        char c = filename[cntr];

        switch (c)
        {
            case '\u0000':
            case '\u0001':
            case '\u0002':
            case '\u0003':
            case '\u0004':
            case '\u0005':
            case '\u0006':
            case '\u0007':
            case '\u0008':
            case '\u0009':
            case '\u000A':
            case '\u000B':
            case '\u000C':
            case '\u000D':
            case '\u000E':
            case '\u000F':
            case '\u0010':
            case '\u0011':
            case '\u0012':
            case '\u0013':
            case '\u0014':
            case '\u0015':
            case '\u0016':
            case '\u0017':
            case '\u0018':
            case '\u0019':
            case '\u001A':
            case '\u001B':
            case '\u001C':
            case '\u001D':
            case '\u001E':
            case '\u001F':

            case '<':
            case '>':
            case ':':
            case '"':
            case '/':
            case '|':
            case '?':
            case '*':
                builder.Append('_');
                break;

            case '\\':
                builder.Append(containsFolder ? c : '_');
                break;

            default:
                builder.Append(c);
                break;
        }
    }

    string built = builder.ToString();

    if (built == "")
    {
        return "_";
    }

    if (built.EndsWith(" ") || built.EndsWith("."))
    {
        built = built.Substring(0, built.Length - 1) + "_";
    }

    // These are reserved names, in either the folder or file name, but they are fine if following a dot
    // CON, PRN, AUX, NUL, COM0 .. COM9, LPT0 .. LPT9
    builder = new StringBuilder(built.Length + 12);
    index = 0;
    foreach (Match match in Regex.Matches(built, @"(^|\\)\s*(?<bad>CON|PRN|AUX|NUL|COM\d|LPT\d)\s*(\.|\\|$)", RegexOptions.IgnoreCase))
    {
        Group group = match.Groups["bad"];
        if (group.Index > index)
        {
            builder.Append(built.Substring(index, match.Index - index + 1));
        }

        builder.Append(group.Value);
        builder.Append("_");        // putting an underscore after this keyword is enough to make it acceptable

        index = group.Index + group.Length;
    }

    if (index == 0)
    {
        return built;
    }

    if (index < built.Length - 1)
    {
        builder.Append(built.Substring(index));
    }

    return builder.ToString();
}

ฉันมีสามคำถาม: 1. ทำไมคุณเริ่มต้นStringBuilderด้วยค่าความจุเริ่มต้น? 2. ทำไมคุณเพิ่ม 12 ลงไปจนถึงความยาวของfilename? 3. มีการเลือก 12 ข้อโดยพลการหรือมีความคิดบางอย่างอยู่เบื้องหลังหมายเลขนี้?
iiminov

2

ในวันที่ 18/4/2560 ไม่มีรายการตัวละครและชื่อไฟล์สีดำหรือสีขาวที่เห็นได้ชัดเจนในบรรดาคำตอบของหัวข้อนี้ - และมีคำตอบมากมาย

คำแนะนำที่ดีที่สุดที่ฉันสามารถทำได้คือให้ชื่อผู้ใช้กับไฟล์ตามที่เขาต้องการ การใช้ตัวจัดการข้อผิดพลาดเมื่อแอปพลิเคชันพยายามบันทึกไฟล์ตรวจจับข้อยกเว้นใด ๆ ถือว่าชื่อไฟล์นั้นเป็นโทษ เพื่อผลลัพธ์ที่ดีที่สุดให้วางขั้นตอนการตรวจสอบนี้ภายในลูปที่ดำเนินการต่อไปจนกว่าผู้ใช้จะทำให้ถูกต้องหรือเลิก ทำงานได้ดีที่สุดสำหรับฉัน (อย่างน้อยใน VBA)


1
คำตอบ @FCastro ของคุณถูกต้องจากมุมมองทางเทคนิค อย่างไรก็ตามจากมุมมองของ UX มันเป็นฝันร้าย - ผู้ใช้ถูกบังคับให้เล่น "พิมพ์บางอย่างและฉันจะบอกคุณว่าคุณประสบความสำเร็จ" เกมซ้ำแล้วซ้ำอีก ฉันอยากเห็นข้อความ (รูปแบบคำเตือน) บอกผู้ใช้ว่าพวกเขาป้อนอักขระผิดกฎหมายซึ่งจะถูกแปลงในภายหลัง
Mike

Christopher Oezbek ให้รายชื่อสีดำเช่นนี้ในปี 2015
Jim Balter

1

แม้ว่าตัวอักษร Unix ที่ผิดกฎหมายเท่านั้นที่อาจเป็น/และNULLแม้ว่าการพิจารณาบางอย่างสำหรับการตีความบรรทัดคำสั่งควรรวมอยู่ด้วย

ตัวอย่างเช่นในขณะที่อาจถูกกฎหมายในการตั้งชื่อไฟล์1>&2หรือ2>&1ใน Unix ชื่อไฟล์เช่นนี้อาจตีความผิดเมื่อใช้กับบรรทัดคำสั่ง

ในทำนองเดียวกันอาจเป็นไปได้ที่จะตั้งชื่อไฟล์$PATHแต่เมื่อพยายามเข้าถึงจากบรรทัดคำสั่งเชลล์จะแปล$PATHเป็นค่าตัวแปร


สำหรับตัวอักษรในทุบตีวิธีที่ดีที่สุดที่ฉันได้พบในการประกาศตัวอักษรโดยไม่ต้องแก้ไขคือ$'myvalueis'อดีต: $ echo 'hi' > $'2>&1', cat 2\>\&1"สวัสดี"
ThorSummoner

1

ปัญหาเกี่ยวกับการกำหนดสิ่งที่ถูกต้องตามกฎหมายและไม่ถูกadressed แล้วและบัญชีขาวแนะ แต่ Windows รองรับอักขระที่มากกว่า 8 บิต รัฐ Wikipediaว่า (ตัวอย่าง)

โคลอนตัวดัดแปลงจดหมาย[( ดู 7. ด้านล่าง ) คือ] บางครั้งใช้ในชื่อไฟล์ Windows เนื่องจากเหมือนกับโคลอนในฟอนต์ Segoe UI ที่ใช้สำหรับชื่อไฟล์ โคลอน [ASCII ที่สืบทอด] ไม่ได้รับอนุญาต

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

  1. แทนที่จะเป็น*( U+002A * ASTERISK) คุณสามารถใช้หนึ่งในหลาย ๆตัวอย่างเช่นU+2217 ∗ (ASTERISK OPERATOR)หรือFull Width Asterisk U+FF0A *
  2. แทนที่จะ.คุณสามารถใช้หนึ่งในเหล่านี้ยกตัวอย่างเช่น⋅ U+22C5 dot operator
  3. แทนที่จะ"ใช้คุณสามารถใช้“ U+201C english leftdoublequotemark(ทางเลือกดูที่นี่ )
  4. แทนที่จะเป็น/( / SOLIDUS U+002F) คุณสามารถใช้∕ DIVISION SLASH U+2215(คนอื่น ๆที่นี่ )
  5. แทนที่จะเป็น\( \ U+005C Reverse solidus) คุณสามารถใช้⧵ U+29F5 Reverse solidus operator( เพิ่มเติม )
  6. แทน[( U+005B Left square bracket) และ]( U+005D Right square bracket) คุณสามารถใช้ตัวอย่างU+FF3B[ FULLWIDTH LEFT SQUARE BRACKETและU+FF3D ]FULLWIDTH RIGHT SQUARE BRACKET(จากที่นี่มีความเป็นไปได้มากขึ้นที่นี่ )
  7. แทนที่จะ:ใช้คุณสามารถใช้U+2236 ∶ RATIO (for mathematical usage)หรือU+A789 ꞉ MODIFIER LETTER COLON(ดูเครื่องหมายจุดคู่ (ตัวอักษร)ซึ่งบางครั้งใช้ในชื่อไฟล์ Windows เนื่องจากเป็นชื่อเดียวกับเครื่องหมายโคลอนในแบบอักษรSegoe UI ที่ใช้สำหรับชื่อไฟล์ไม่อนุญาตให้ใช้เครื่องหมายโคลอน) (ดูที่นี่ )
  8. แทนที่จะ;ใช้คุณสามารถใช้U+037E ; GREEK QUESTION MARK(ดูที่นี่ )
  9. สำหรับ|มีบางทดแทนที่ดีเช่นU+0964 । DEVANAGARI DANDA, U+2223 ∣ DIVIDESหรือU+01C0 ǀ LATIN LETTER DENTAL CLICK( วิกิพีเดีย ) นอกจากนี้ตัวละครวาดกล่องมีตัวเลือกอื่น ๆ อีกมากมาย
  10. แทน,( , U+002C COMMA) คุณสามารถใช้ตัวอย่าง‚ U+201A SINGLE LOW-9 QUOTATION MARK(ดูที่นี่ )
  11. สำหรับ?( U+003F ? QUESTION MARK) สิ่งเหล่านี้คือผู้สมัครที่ดี: U+FF1F ? FULLWIDTH QUESTION MARKหรือU+FE56 ﹖ SMALL QUESTION MARK(จากเขาอีกสองคนจากบล็อก Dingbatsค้นหา "คำถาม")

0

เมื่อสร้างทางลัดอินเทอร์เน็ตใน Windows เพื่อสร้างชื่อไฟล์มันจะข้ามอักขระที่ผิดกฎหมายยกเว้นเครื่องหมายสแลชซึ่งจะถูกแปลงเป็นลบ


3
"ไม่ใช่คำตอบ ... ถูกปฏิเสธ - ผู้ควบคุมตรวจสอบการตั้งค่าสถานะของคุณ แต่ไม่พบหลักฐานที่สนับสนุน" คุณต้องล้อเล่นฉัน ดีกว่าผู้ดูแลโปรด
Jim Balter

-1

ในเปลือกหอย Unix, 'คุณสามารถพูดเกือบทุกตัวละครในราคาเดียว ยกเว้นเครื่องหมายคำพูดเดี่ยวและคุณไม่สามารถแสดงอักขระควบคุมได้เนื่องจาก\ไม่ได้ขยาย การเข้าถึงเครื่องหมายคำพูดเดี่ยวจากภายในสตริงที่ยกมานั้นเป็นไปได้เนื่องจากคุณสามารถเชื่อมสตริงด้วยเครื่องหมายคำพูดเดี่ยวและคู่เช่น'I'"'"'m'ที่สามารถใช้เพื่อเข้าถึงไฟล์ที่เรียกว่า"I'm" (อัญประกาศคู่ก็เป็นไปได้ที่นี่)

ดังนั้นคุณควรหลีกเลี่ยงอักขระควบคุมทั้งหมดเพราะมันยากเกินไปที่จะใส่ในเปลือก ส่วนที่เหลือยังคงตลกโดยเฉพาะไฟล์ที่ขึ้นต้นด้วยเส้นประเพราะคำสั่งส่วนใหญ่จะอ่านเป็นตัวเลือกเว้นแต่ว่าคุณมีเครื่องหมายขีดคั่นสองอัน--มาก่อนหรือคุณระบุด้วย./ซึ่งจะซ่อนจุดเริ่มต้น-ด้วย

หากคุณต้องการเป็นคนดีอย่าใช้ตัวอักษรใด ๆ ที่เชลล์และคำสั่งทั่วไปใช้เป็นองค์ประกอบทางไวยากรณ์บางครั้งก็ขึ้นอยู่กับตำแหน่งดังนั้นเช่นคุณสามารถใช้งาน-ได้ แต่ไม่ใช่อักขระตัวแรก เช่นเดียวกับ.คุณสามารถใช้มันเป็นอักขระตัวแรกเฉพาะเมื่อคุณหมายถึงมัน ("ไฟล์ที่ซ่อน") เมื่อคุณหมายถึงชื่อไฟล์ของคุณคือ VT100 escape sequences ;-) เพื่อให้ ls อ่านไม่ออก


คำถามไม่ได้เกี่ยวกับเปลือกหอย
Jim Balter

-8

ฉันมีความต้องการเดียวกันและกำลังมองหาคำแนะนำหรือการอ้างอิงมาตรฐานและพบกับกระทู้นี้ บัญชีดำของฉันปัจจุบันของตัวละครที่ควรหลีกเลี่ยงในชื่อไฟล์และไดเรกทอรีคือ:

$CharactersInvalidForFileName = {
    "pound" -> "#",
    "left angle bracket" -> "<",
    "dollar sign" -> "$",
    "plus sign" -> "+",
    "percent" -> "%",
    "right angle bracket" -> ">",
    "exclamation point" -> "!",
    "backtick" -> "`",
    "ampersand" -> "&",
    "asterisk" -> "*",
    "single quotes" -> "“",
    "pipe" -> "|",
    "left bracket" -> "{",
    "question mark" -> "?",
    "double quotes" -> "”",
    "equal sign" -> "=",
    "right bracket" -> "}",
    "forward slash" -> "/",
    "colon" -> ":",
    "back slash" -> "\\",
    "lank spaces" -> "b",
    "at sign" -> "@"
};

4
คุณจะแสดงความคิดเห็น@ในรายการหรือไม่?
PypeBros

8
คำถามคือตัวละครใดผิดกฎหมาย อักขระส่วนใหญ่ในรายการของคุณถูกกฎหมาย
Nigel Alderton

6
ตัวอักษรb? ฮ่า ๆ ฉันคิดว่านั่นเป็นขจากlank spaces... ก็ยังเหลืออีกไม่กี่ ... ฉันเปลี่ยนชื่อรูปภาพ(),-.;[]^_~€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ.jpgแต่ต้องเปลี่ยนกลับเพราะมันดูโกรธ ...
ashleedawg
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.