go get github.com/gabriel-vasile/mimetype
mtype := mimetype . Detect ([] byte )
// OR
mtype , err := mimetype . DetectReader ( io . Reader )
// OR
mtype , err := mimetype . DetectFile ( "/path/to/file" )
fmt . Println ( mtype . String (), mtype . Extension ())
ดูตัวอย่าง Go Playground ที่รันได้
ใช้ไลบรารีเช่น mimetype เป็นทางเลือกสุดท้ายเท่านั้น การตรวจจับประเภทเนื้อหาโดยใช้ตัวเลขมหัศจรรย์นั้นช้า ไม่ถูกต้อง และไม่ได้มาตรฐาน โปรโตคอลส่วนใหญ่มีวิธีในการระบุข้อมูลเมตาดังกล่าว เช่น ส่วนหัว Content-Type
ใน HTTP และ SMTP
ถาม: ไฟล์ของฉันอยู่ในรายการประเภท MIME ที่รองรับ แต่ตรวจไม่พบอย่างถูกต้อง ฉันควรทำอย่างไร?
ตอบ: ไฟล์บางรูปแบบ (มักจะเป็นเอกสาร Microsoft Office) จะเก็บลายเซ็นไว้ที่ส่วนท้ายของไฟล์ ลองเพิ่มจำนวนไบต์ที่ใช้ในการตรวจจับด้วย:
mimetype . SetLimit ( 1024 * 1024 ) // Set limit to 1MB.
// or
mimetype . SetLimit ( 0 ) // No limit, whole file content used.
mimetype . DetectFile ( "file.doc" )
หากการเพิ่มขีดจำกัดไม่ช่วย โปรดเปิดปัญหา
mimetype ใช้โครงสร้างแบบลำดับชั้นเพื่อรักษาตรรกะการตรวจจับประเภท MIME ซึ่งจะช่วยลดจำนวนการโทรที่จำเป็นสำหรับการตรวจจับประเภทไฟล์ เหตุผลเบื้องหลังตัวเลือกนี้คือ มีรูปแบบไฟล์ที่ใช้เป็นคอนเทนเนอร์สำหรับรูปแบบไฟล์อื่นๆ ตัวอย่างเช่น ไฟล์ Microsoft Office เป็นเพียงไฟล์ ZIP ที่มีไฟล์ข้อมูลเมตาเฉพาะ เมื่อระบุไฟล์เป็น zip แล้ว ไม่จำเป็นต้องตรวจสอบว่าเป็นไฟล์ข้อความหรือไม่ แต่ควรตรวจสอบว่าเป็นไฟล์ Microsoft Office หรือไม่
เพื่อป้องกันการโหลดไฟล์ทั้งหมดลงในหน่วยความจำ เมื่อตรวจพบจากเครื่องอ่านหรือจากประเภทไฟล์ mimetype จะจำกัดตัวเองให้อ่านเฉพาะส่วนหัวของอินพุตเท่านั้น
ด้วยโครงสร้างแบบลำดับชั้น การค้นหารูปแบบทั่วไปก่อน และจำกัดตัวเองไว้ที่ส่วนหัวของไฟล์ mimetype จึงตรงกับประสิทธิภาพของ stdlib http.DetectContentType
ในขณะที่มีประสิทธิภาพเหนือกว่าแพ็คเกจทางเลือก
mimetype http.DetectContentType filetype
BenchmarkMatchTar-24 250 ns/op 400 ns/op 3778 ns/op
BenchmarkMatchZip-24 524 ns/op 351 ns/op 4884 ns/op
BenchmarkMatchJpeg-24 103 ns/op 228 ns/op 839 ns/op
BenchmarkMatchGif-24 139 ns/op 202 ns/op 751 ns/op
BenchmarkMatchPng-24 165 ns/op 221 ns/op 1176 ns/op
ดูการมีส่วนร่วม.md