ตอนนี้ฉันสับสนไปหมด - ส่วนใหญ่เป็นเพราะคำศัพท์ฉันเดา ใครช่วยแนะนำฉันเกี่ยวกับความแตกต่างหรือให้ลิงค์ไปยังวัสดุป้องกันดัมมี่ได้บ้าง โดยเฉพาะ URI เป็น URL และ Resource to File? สำหรับฉันแล้วรู้สึกว่าพวกเขาควรจะเป็นสิ่งเดียวกันตามลำดับ ...
คำศัพท์มีความสับสนและบางครั้งก็ทำให้สับสนและส่วนใหญ่เกิดจากวิวัฒนาการของ Java ทั้งในรูปแบบ API และเป็นแพลตฟอร์มเมื่อเวลาผ่านไป เพื่อให้เข้าใจว่าคำศัพท์เหล่านี้มีความหมายอย่างไรสิ่งสำคัญคือต้องตระหนักถึงสองสิ่งที่มีอิทธิพลต่อการออกแบบของ Java:
- ความเข้ากันได้ย้อนหลัง แอปพลิเคชันเก่าควรทำงานบนการติดตั้งที่ใหม่กว่าโดยไม่ต้องแก้ไข ซึ่งหมายความว่า API เก่า (พร้อมชื่อและคำศัพท์) จะต้องได้รับการดูแลผ่านเวอร์ชันที่ใหม่กว่าทั้งหมด
- ข้ามแพลตฟอร์ม API ควรให้สิ่งที่เป็นนามธรรมที่ใช้งานได้ของแพลตฟอร์มพื้นฐานไม่ว่าจะเป็นระบบปฏิบัติการหรือเบราว์เซอร์
ฉันจะอธิบายแนวคิดและความเป็นมาของพวกเขา ฉันจะตอบคำถามอื่น ๆ ของคุณหลังจากนั้นเพราะฉันอาจต้องอ้างถึงบางสิ่งในส่วนแรก
"ทรัพยากร" คืออะไร?
ข้อมูลทั่วไปที่เป็นนามธรรมซึ่งสามารถระบุและอ่านได้ กล่าวอย่างหลวม ๆ Java ใช้สิ่งนี้เพื่ออ้างถึง "ไฟล์" ที่อาจไม่ใช่ไฟล์ แต่เป็นตัวแทนของข้อมูลที่มีชื่อ ไม่มีการแสดงคลาสโดยตรงหรืออินเทอร์เฟซใน Javaแต่เนื่องจากคุณสมบัติ (ระบุตำแหน่งได้, อ่านได้) จึงมักแสดงด้วย URL
เนื่องจากเป้าหมายการออกแบบแรกเริ่มของ Java คือการทำงานภายในเบราว์เซอร์เป็นแอปพลิเคชันแซนด์บ็อกซ์ (แอพเพล็ต!) ที่มีสิทธิ์ / สิทธิ์ / การรักษาความปลอดภัยที่ จำกัด มากJava จึงสร้างความแตกต่างที่ชัดเจน (ทางทฤษฎี) ระหว่างไฟล์ (บางอย่างในโลคัล ระบบไฟล์) และทรัพยากร (สิ่งที่ต้องอ่าน) นี่คือเหตุผลที่การอ่านบางสิ่งที่เกี่ยวข้องกับแอปพลิเคชัน (ไอคอนไฟล์คลาสและอื่น ๆ ) เสร็จสิ้นClassLoader.getResource
และไม่ผ่านคลาสไฟล์
น่าเสียดายเนื่องจาก "ทรัพยากร" เป็นคำทั่วไปที่มีประโยชน์นอกเหนือจากการตีความนี้จึงยังใช้เพื่อตั้งชื่อสิ่งที่เฉพาะเจาะจงมาก (เช่นคลาสResourceBundle , UIResource , Resource ) ที่ไม่ใช่ทรัพยากรในแง่นี้
คลาสหลักที่แสดง (เส้นทางไปยัง) ทรัพยากรคือjava.nio.file.Path , java.io.File , java.net.URIและjava.net.URL java.net.URL
ไฟล์ (java.io, 1.0)
การแสดงนามธรรมของชื่อพา ธ ไฟล์และไดเร็กทอรี
ชั้นไฟล์หมายถึงทรัพยากรที่เป็นความสามารถเข้าถึงได้ผ่านระบบไฟล์แพลตฟอร์มพื้นเมือง มันมีเฉพาะชื่อของไฟล์ดังนั้นจึงเป็นพา ธ จริงๆ (ดูในภายหลัง) ที่แพลตฟอร์มโฮสต์ตีความตามการตั้งค่ากฎและไวยากรณ์ของมันเอง
โปรดทราบว่าไฟล์ไม่จำเป็นต้องชี้ไปที่สิ่งที่อยู่ในเครื่องเพียงแค่สิ่งที่แพลตฟอร์มโฮสต์เข้าใจในบริบทของการเข้าถึงไฟล์เช่นเส้นทาง UNC ใน Windows หากคุณติดตั้งไฟล์ ZIP เป็นระบบไฟล์ในระบบปฏิบัติการของคุณไฟล์จะอ่านรายการที่มีอยู่ได้ดี
URL (java.net, 1.0)
Class URL แสดงถึง Uniform Resource Locator ซึ่งเป็นตัวชี้ไปยัง "ทรัพยากร" บนเวิลด์ไวด์เว็บ ทรัพยากรอาจเป็นสิ่งที่เรียบง่ายเหมือนไฟล์หรือไดเร็กทอรีหรืออาจเป็นการอ้างอิงถึงออบเจ็กต์ที่ซับซ้อนมากขึ้นเช่นแบบสอบถามไปยังฐานข้อมูลหรือไปยังเครื่องมือค้นหา
ควบคู่ไปกับแนวคิดของทรัพยากร URL แสดงถึงทรัพยากรนั้นในลักษณะเดียวกับที่คลาส File แสดงถึงไฟล์ในแพลตฟอร์มโฮสต์: เป็นสตริงที่มีโครงสร้างซึ่งชี้ไปยังทรัพยากร นอกจากนี้ URL ยังมีรูปแบบที่บอกถึงวิธีการเข้าถึงทรัพยากร (โดยมี "file:" being "ask the host platform") และอนุญาตให้ชี้ไปที่ทรัพยากรผ่าน HTTP, FTP, ภายใน JAR และอะไรก็ได้
ขออภัย URL มาพร้อมกับไวยากรณ์และคำศัพท์เฉพาะของตนเองรวมถึงการใช้ "file" และ "path" ในกรณีที่ URL เป็น URL ของไฟล์ URL.getFile จะส่งคืนสตริงที่เหมือนกับสตริงพา ธ ของไฟล์ที่อ้างอิง
Class.getResource
ส่งคืน URL: มีความยืดหยุ่นมากกว่าการส่งคืนไฟล์และตอบสนองความต้องการของระบบตามที่จินตนาการไว้ในช่วงต้นทศวรรษ 1990
URI (java.net, 1.4)
แสดงการอ้างอิง Uniform Resource Identifier (URI)
URI เป็นนามธรรม (เล็กน้อย) เหนือ URL ความแตกต่างระหว่าง URI และ URL เป็นแนวคิดและส่วนใหญ่เป็นเชิงวิชาการ แต่ URI มีความหมายที่เป็นทางการได้ดีกว่าและครอบคลุมกรณีการใช้งานที่หลากหลายกว่า เนื่องจาก URL และ URI ไม่ใช่สิ่งเดียวกันจึงมีการนำคลาสใหม่มาใช้แทนโดยมีเมธอด URI.toURL และ URL.toURI เพื่อย้ายไปมาระหว่างหนึ่งและอีกอัน
ใน Java ข้อแตกต่างที่สำคัญระหว่าง URL และ URI คือURL มีความคาดหวังว่าจะสามารถแก้ไขได้บางสิ่งที่แอปพลิเคชันอาจต้องการ InputStream จาก URI ได้รับการปฏิบัติเหมือนสิ่งนามธรรมมากกว่า amajig ที่อาจชี้ไปที่บางสิ่งที่แก้ไขได้ (และมักจะทำได้) แต่ความหมายและวิธีการเข้าถึงนั้นเปิดกว้างต่อบริบทและการตีความมากกว่า
เส้นทาง (java.nio.file, 1.7)
อ็อบเจ็กต์ที่อาจใช้เพื่อค้นหาไฟล์ในระบบไฟล์ โดยทั่วไปจะแสดงเส้นทางไฟล์ที่ขึ้นกับระบบ
API ไฟล์ใหม่ซึ่งเป็นสัญลักษณ์ในอินเทอร์เฟซ Path ช่วยให้มีความยืดหยุ่นมากกว่าที่คลาส File จะมีให้ อินเตอร์เฟซที่เส้นทางเป็นนามธรรมของคลาแฟ้มและเป็นส่วนหนึ่งของใหม่ IO ไฟล์ API โดยที่ File จำเป็นต้องชี้ไปที่ "ไฟล์" ตามที่แพลตฟอร์มโฮสต์เข้าใจ Path นั้นเป็นแบบทั่วไปมากกว่า: แสดงถึงไฟล์ (ทรัพยากร) ในระบบไฟล์โดยพลการ
พา ธ นำไปใช้กับแนวคิดของแพลตฟอร์มโฮสต์ของไฟล์ อาจเป็นรายการในไฟล์ ZIP ไฟล์ที่เข้าถึงได้ผ่าน FTP หรือ SSH-FS การแสดงคลาสพา ธ ของแอปพลิเคชันหลายรูทหรืออะไรก็ได้ที่สามารถแสดงความหมายผ่านอินเทอร์เฟซ FileSystem และไดรเวอร์ FileSystemProvider นำพลังของระบบไฟล์ "การติดตั้ง" เข้ามาในบริบทของแอ็พพลิเคชัน Java
แพลตฟอร์มโฮสต์แสดงผ่าน "ระบบไฟล์เริ่มต้น"; เมื่อคุณโทรFile.toPath
คุณจะได้รับ Path บนระบบไฟล์เริ่มต้น
ตอนนี้ถ้าฉันมีตัวระบุตำแหน่งที่อ้างอิงคลาสหรือแพ็คเกจในไฟล์ jar ทั้งสอง (เช่นพา ธ สตริงไฟล์) จะแตกต่างกันหรือไม่
ไม่น่าเป็นไปได้ หากไฟล์ jar อยู่ในระบบไฟล์ภายในเครื่องคุณไม่ควรมีคอมโพเนนต์เคียวรีดังนั้นURL.getPath
และURL.getFile
ควรส่งคืนผลลัพธ์เดียวกัน อย่างไรก็ตามเลือกสิ่งที่คุณต้องการ: โดยทั่วไปแล้ว URL ของไฟล์อาจไม่มีส่วนประกอบการสืบค้น แต่ฉันสามารถเพิ่มได้อย่างแน่นอน
สุดท้าย - และที่สำคัญที่สุด - ทำไมฉันถึงต้องการ File object; เหตุใดทรัพยากร (URL) จึงไม่เพียงพอ
URL อาจไม่เพียงพอเนื่องจาก File ให้คุณเข้าถึงข้อมูลการดูแลระบบเช่นสิทธิ์ (อ่านได้เขียนได้ปฏิบัติการได้) ประเภทไฟล์ (ฉันเป็นไดเร็กทอรีหรือไม่) และความสามารถในการค้นหาและจัดการระบบไฟล์ภายในเครื่อง หากเป็นคุณสมบัติที่คุณต้องการไฟล์หรือเส้นทางจะจัดเตรียมให้
คุณไม่จำเป็นต้องใช้ไฟล์หากคุณสามารถเข้าถึงเส้นทางได้ API รุ่นเก่าบางตัวอาจต้องการไฟล์
(และมีวัตถุทรัพยากรหรือไม่)
ไม่มีไม่มี มีหลายสิ่งที่ชื่อเหมือนมันมี ClassLoader.getResource
แต่พวกเขาไม่ได้เป็นทรัพยากรในแง่ของการเป็น
Path
และ FileSystem จาก NIO :)