มีความแตกต่างเล็กน้อยเกี่ยวกับวิธีการfileName
ตีความของคุณผ่าน โดยทั่วไปคุณมี 2 วิธีที่แตกต่างกันและClassLoader.getResourceAsStream()
Class.getResourceAsStream()
วิธีการทั้งสองนี้จะค้นหาทรัพยากรที่แตกต่างกัน
ในClass.getResourceAsStream(path)
เส้นทางถูกตีความว่าเป็นเส้นทางท้องถิ่นไปยังแพคเกจของชั้นเรียนที่คุณกำลังเรียกมันจาก ยกตัวอย่างเช่นโทรString.getResourceAsStream("myfile.txt")
จะมองหาไฟล์ใน classpath "java/lang/myfile.txt"
ของคุณในสถานที่ต่อไปนี้: หากเส้นทางของคุณเริ่มต้นด้วย a /
ก็จะถือว่าเป็นเส้นทางที่แน่นอนและจะเริ่มค้นหาจากรูทของ classpath ดังนั้นการเรียกจะดูที่ตำแหน่งต่อไปในเส้นทางการเรียนของคุณString.getResourceAsStream("/myfile.txt")
./myfile.txt
ClassLoader.getResourceAsStream(path)
จะพิจารณาเส้นทางทั้งหมดให้เป็นเส้นทางที่แน่นอน ดังนั้นการโทรString.getClassLoader().getResourceAsStream("myfile.txt")
และString.getClassLoader().getResourceAsStream("/myfile.txt")
ทั้งสองจะค้นหาไฟล์ใน classpath ของคุณที่ตำแหน่งต่อไปนี้: ./myfile.txt
.
ทุกครั้งที่ฉันพูดถึงตำแหน่งในโพสต์นี้อาจเป็นตำแหน่งในระบบไฟล์ของคุณเองหรือภายในไฟล์ jar ที่เกี่ยวข้องทั้งนี้ขึ้นอยู่กับ Class และ / หรือ ClassLoader ที่คุณโหลดทรัพยากรจาก
ในกรณีของคุณคุณจะโหลดจากระดับ Application Server ดังนั้นคุณควรใช้แทนThread.currentThread().getContextClassLoader().getResourceAsStream(fileName)
ยังจะทำงานthis.getClass().getClassLoader().getResourceAsStream(fileName)
this.getClass().getResourceAsStream()
อ่านบทความนี้สำหรับข้อมูลโดยละเอียดเพิ่มเติมเกี่ยวกับปัญหานั้น ๆ
คำเตือนสำหรับผู้ใช้ Tomcat 7 และด้านล่าง
หนึ่งในคำตอบของคำถามนี้ระบุว่าคำอธิบายของฉันดูเหมือนจะไม่ถูกต้องสำหรับ Tomcat 7 ฉันพยายามตรวจดูว่าทำไมมันถึงเป็นเช่นนั้น
ดังนั้นฉันได้ดูซอร์สโค้ดของ Tomcat WebAppClassLoader
สำหรับTomcat หลายเวอร์ชัน การนำไปปฏิบัติของfindResource(String name)
(ซึ่งรับผิดชอบการผลิต URL ไปยังทรัพยากรที่ร้องขอ) จะเหมือนกันใน Tomcat 6 และ Tomcat 7 แต่แตกต่างกันใน Tomcat 8
ในเวอร์ชัน 6 และ 7 การใช้งานไม่ได้พยายามทำให้ชื่อทรัพยากรเป็นมาตรฐาน ซึ่งหมายความว่าในเวอร์ชันเหล่านี้classLoader.getResourceAsStream("/resource.txt")
อาจไม่สร้างผลลัพธ์เดียวกันกับclassLoader.getResourceAsStream("resource.txt")
เหตุการณ์แม้ว่าควร (เนื่องจากสิ่งที่ Javadoc ระบุ) [รหัสแหล่งที่มา]
ในเวอร์ชัน 8 แม้ว่าชื่อทรัพยากรจะได้รับการทำให้เป็นมาตรฐานเพื่อรับรองว่าชื่อของทรัพยากรนั้นเป็นรุ่นที่ใช้จริง ดังนั้นใน Tomcat 8 การเรียกสองสายที่อธิบายไว้ข้างต้นควรส่งคืนผลลัพธ์เดียวกันเสมอ [รหัสแหล่งที่มา]
เป็นผลให้คุณต้องระมัดระวังเป็นพิเศษเมื่อใช้ClassLoader.getResourceAsStream()
หรือClass.getResourceAsStream()
บน Tomcat เวอร์ชันก่อนหน้านี้ 8 และคุณต้องจำไว้ว่าclass.getResourceAsStream("/resource.txt")
สายจริงclassLoader.getResourceAsStream("resource.txt")
( สายนำ/
ถูกปล้น)
getClass().getResourceAsStream("/myfile.txt")
getClassLoader().getResourceAsStream("/myfile.txt")