ในการพัฒนา Java มักพบกรณีที่ต้องตรวจสอบประเภทไฟล์ เช่น ในฟังก์ชันอัปโหลดไฟล์ จำเป็นต้องตรวจสอบว่าไฟล์ที่ผู้ใช้อัปโหลดเป็นประเภทที่กำหนดหรือไม่ บทความนี้จะแนะนำวิธีใช้ Java เพื่อระบุประเภทไฟล์อย่างละเอียด。
หนึ่ง、ใช้ส่วนขยายของชื่อไฟล์เพื่อระบุประเภทไฟล์
วิธีระบุประเภทไฟล์ที่พบบ่อยที่สุดคือพิจารณาจากนามสกุลไฟล์ ไฟล์ส่วนใหญ่ในระบบปฏิบัติการมีนามสกุลเฉพาะ เช่น นามสกุลของไฟล์ข้อความโดยทั่วไปคือ.txt,นามสกุลไฟล์รูปภาพโดยทั่วไปคือ.jpgหรือ.pngเป็นต้น。
การดึงนามสกุลไฟล์ด้วยโปรแกรม Java ทำได้ง่ายมาก เพียงใช้Stringของคลาสsubstringเมธอดก็เพียงพอแล้ว โค้ดมีดังนี้:
public static String getFileExtension(File file) {
String fileName = file.getName();
if (fileName.lastIndexOf(".") != -1 && fileName.lastIndexOf(".") != 0) {
return fileName.substring(fileName.lastIndexOf(".") + 1);
} else {
return "";
}
}เมธอดนี้รับหนึ่งFileออบเจ็กต์เป็นพารามิเตอร์ แล้วใช้lastIndexOfใช้เมธอดหาตำแหน่งจุดตัวสุดท้ายในชื่อไฟล์ ซึ่งก็คือตำแหน่งเริ่มต้นของนามสกุลไฟล์ แล้วจึงใช้substringเมธอดรับสตริงนามสกุลไฟล์และส่งกลับ หากไฟล์ไม่มีนามสกุล จะส่งกลับสตริงว่าง
สามารถใช้โค้ดต่อไปนี้ทดสอบเมธอดนี้ได้:
File file = new File("C:/path/to/file.txt");
String extension = getFileExtension(file);
System.out.println(extension);ผลการทำงานคือ:
txt
การใช้วิธีนี้ตรวจสอบประเภทไฟล์มีข้อดีดังต่อไปนี้:
ใช้งานง่าย และเขียนโค้ดได้กระชับ。
ใช้ได้ผลกับไฟล์ส่วนใหญ่ เพราะไฟล์ส่วนใหญ่มีนามสกุลไฟล์。
อย่างไรก็ตาม วิธีนี้ก็มีข้อเสียบางประการเช่นกัน:
นามสกุลไฟล์อาจถูกเปลี่ยน ทำให้ผลการตรวจสอบผิดพลาด
ไฟล์บางไฟล์ไม่มีนามสกุล เช่น ไฟล์ปฏิบัติการที่ไม่มีนามสกุลไฟล์。
เพื่อระบุประเภทไฟล์ให้แม่นยำยิ่งขึ้น เราสามารถใช้เลขแมจิกของไฟล์ประกอบการพิจารณาได้。

สอง、ใช้เลขมหัศจรรย์ของไฟล์ระบุชนิดไฟล์
เลขมหัศจรรย์ของไฟล์คือไบต์เฉพาะบางตัวในช่วงไม่กี่ไบต์แรกของไฟล์ ซึ่งใช้ระบุประเภทไฟล์ การตรวจจับเลขมหัศจรรย์ของไฟล์ช่วยให้เราระบุประเภทไฟล์ได้อย่างแม่นยำ โดยไม่ถูกรบกวนจากนามสกุลไฟล์
ใน Java สามารถอ่านข้อมูลไบนารีของไฟล์เพื่อรับค่า magic number ของไฟล์ได้
2.1 อ่านข้อมูลไบนารีของไฟล์
เราสามารถใช้FileInputStreamคลาสเพื่ออ่านข้อมูลไบนารีของไฟล์ เมธอดต่อไปนี้จะคืนค่าอาร์เรย์ไบต์ที่มีข้อมูลไบนารีของไฟล์:
public static byte[] readFileToByteArray(File file) throws IOException {
FileInputStream fis = null;
try {
fis = new FileInputStream(file);
byte[] data = new byte[(int)file.length()];
fis.read(data);
return data;
} finally {
if (fis != null) {
fis.close();
}
}
}วิธีการข้างต้นใช้FileInputStreamเพื่อเปิดไฟล์ อ่านข้อมูล และจัดเก็บข้อมูลลงในอาร์เรย์ไบต์ โปรดทราบว่าเมื่ออ่านไฟล์เสร็จแล้ว ต้องเรียกcloseเมธอดปิดสตรีมไฟล์ เพื่อคืนทรัพยากรให้ระบบ
2.2 ใช้เมจิกนัมเบอร์ของไฟล์ระบุชนิดไฟล์
เมื่อมีข้อมูลไบนารีของไฟล์แล้ว เราก็สามารถระบุชนิดไฟล์ได้ ไฟล์แต่ละชนิดมีเลขมหัศจรรย์เฉพาะ ซึ่งใช้ระบุชนิดของไฟล์ได้ ต่อไปนี้คือเลขมหัศจรรย์ของไฟล์บางชนิดที่พบบ่อยและวิธีตรวจสอบที่สอดคล้องกัน:
ค่าเมจิกนัมเบอร์ของไฟล์ข้อความ(.txt)คือ
EF BB BF(ไฟล์ที่เข้ารหัส UTF-8 มีลำดับไบต์นี้อยู่ที่ต้นไฟล์),สามารถตรวจสอบได้ด้วยวิธีต่อไปนี้:public static boolean isTextFile(byte[] data) { if (data.length >= 3 && data[0] == -17 && data[1] == -69 && data[2] == -65) { return true; } return false; }เมจิกนัมเบอร์ของภาพ JPEG(.jpg)คือ
FF D8 FF,สามารถใช้วิธีต่อไปนี้เพื่อตรวจสอบได้:public static boolean isJPEGFile(byte[] data) { if (data.length >= 3 && data[0] == -1 && data[1] == -40 && data[2] == -1) { return true; } return false; }เลขมหัศจรรย์ของภาพ PNG(.png)คือ
89 50 4E 47 0D 0A 1A 0A,สามารถใช้วิธีต่อไปนี้เพื่อตรวจสอบได้:public static boolean isPNGFile(byte[] data) { if (data.length >= 8 && data[0] == -119 && data[1] == 80 && data[2] == 78 && data[3] == 71 && data[4] == 13 && data[5] == 10 && data[6] == 26 && data[7] == 10) { return true; } return false; }
สามารถเพิ่มประเภทไฟล์และวิธีตรวจสอบ magic number ที่สอดคล้องกันได้ตามความต้องการ。
2.3 ตัวอย่างฉบับสมบูรณ์
ต่อไปนี้คือตัวอย่างฉบับสมบูรณ์ที่แสดงวิธีใช้แมจิกนัมเบอร์ของไฟล์เพื่อตรวจสอบประเภทไฟล์:
import java.io.File;import java.io.FileInputStream;import java.io.IOException;public class FileTypeChecker {
public static void main(String[] args) {
File file = new File("C:/path/to/file.jpg");
try {
byte[] data = readFileToByteArray(file);
if (isJPEGFile(data)) {
System.out.println("This is a JPEG file.");
} else if (isPNGFile(data)) {
System.out.println("This is a PNG file.");
} else if (isTextFile(data)) {
System.out.println("This is a text file.");
} else {
System.out.println("Unknown file type.");
}
} catch (IOException e) {
e.printStackTrace();
}
}
public static byte[] readFileToByteArray(File file) throws IOException {
FileInputStream fis = null;
try {
fis = new FileInputStream(file);
byte[] data = new byte[(int)file.length()];
fis.read(data);
return data;
} finally {
if (fis != null) {
fis.close();
}
}
}
public static boolean isTextFile(byte[] data) {
if (data.length >= 3 && data[0] == -17 && data[1] == -69 && data[2] == -65) {
return true;
}
return false;
}
public static boolean isJPEGFile(byte[] data) {
if (data.length >= 3 && data[0] == -1 && data[1] == -40 && data[2] == -1) {
return true;
}
return false;
}
public static boolean isPNGFile(byte[] data) {
if (data.length >= 8 && data[0] == -119 && data[1] == 80 && data[2] == 78 && data[3] == 71 &&
data[4] == 13 && data[5] == 10 && data[6] == 26 && data[7] == 10) {
return true;
}
return false;
}
}โค้ดตัวอย่างข้างต้นจะระบุประเภทไฟล์จากเลขมหัศจรรย์ของไฟล์ และแสดงผลลัพธ์ที่สอดคล้องกัน
สาม、ใช้ไลบรารีของบุคคลที่สามระบุประเภทไฟล์
นอกจากวิธีข้างต้นแล้ว ยังใช้ไลบรารีของบุคคลที่สามเพื่อตรวจสอบชนิดไฟล์ได้ด้วย ใน Java มีไลบรารีโอเพนซอร์สของบุคคลที่สามบางตัวที่ช่วยให้เราระบุชนิดไฟล์ได้สะดวกขึ้น
3.1 Tika
Tika เป็นโครงการหนึ่งของ Apache Software Foundation ซึ่งให้บริการไลบรารี Java แบบโอเพนซอร์สสำหรับแยกวิเคราะห์ไฟล์หลากหลายรูปแบบ รวมถึงข้อความ ภาพ เสียง วิดีโอ เป็นต้น การใช้ Tika สามารถดึงเมทาดาทาของไฟล์ รวมถึงประเภทไฟล์ได้
ก่อนอื่น ต้องเพิ่มไลบรารี Tika เป็นส่วนที่โครงการพึ่งพา หากใช้ Maven สร้างโครงการ สามารถเพิ่มได้ใน pom.xml เพิ่มดีเพนเดนซีต่อไปนี้ลงในไฟล์:
<dependency> <groupId>org.apache.tika</groupId> <artifactId>tika-core</artifactId> <version>1.27</version> </dependency>
จากนั้น สามารถใช้โค้ดต่อไปนี้เพื่อหาประเภทของไฟล์:
import org.apache.tika.Tika;
public class FileTypeChecker {
public static void main(String[] args) {
Tika tika = new Tika();
try {
File file = new File("C:/path/to/file.jpg");
String fileType = tika.detect(file);
System.out.println("File type: " + fileType);
} catch (IOException e) {
e.printStackTrace();
}
}
}เมื่อรันโค้ดข้างต้น ระบบจะแสดงประเภทของไฟล์
Tika ใช้วิธีต่าง ๆ ในการระบุชนิดไฟล์ รวมถึงนามสกุลไฟล์ ค่าแมจิกนัมเบอร์ เป็นต้น นอกจากนี้ยังรองรับตัวตรวจจับที่กำหนดเอง จึงเพิ่มกฎการระบุชนิดไฟล์ตามต้องการได้。
3.2 FileTypeDetector
Java มี API มาตรฐานสำหรับตรวจสอบประเภทไฟล์ นั่นคือ FileTypeDetectorอินเทอร์เฟซและProbeContentTypeคลาส。เมื่อใช้อินเทอร์เฟซนี้ จะสามารถกำหนดตัวตรวจจับชนิดไฟล์ขึ้นเองได้。
ต่อไปนี้คือตัวอย่างตัวตรวจจับชนิดไฟล์ที่กำหนดเอง:
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.spi.FileTypeDetector;
public class CustomFileTypeDetector extends FileTypeDetector {
@Override
public String probeContentType(Path path) throws IOException {
String extension = getFileExtension(path.toFile());
if ("txt".equals(extension)) {
return "text/plain";
} else if ("jpg".equals(extension) || "jpeg".equals(extension)) {
return "image/jpeg";
} else if ("png".equals(extension)) {
return "image/png";
} else {
return null;
}
}
private String getFileExtension(File file) {
String fileName = file.getName();
if (fileName.lastIndexOf(".") != -1 && fileName.lastIndexOf(".") != 0) {
return fileName.substring(fileName.lastIndexOf(".") + 1);
} else {
return "";
}
}
}ในตัวอย่างนี้ เราพิจารณาประเภทไฟล์จากนามสกุลไฟล์ แล้วส่งกลับประเภท MIME ที่สอดคล้องกัน。
หากต้องการใช้ตัวตรวจจับประเภทไฟล์ที่กำหนดเอง โปรดเพิ่มโค้ดต่อไปนี้ที่จุดเริ่มต้นของโปรแกรม:
File file = new File("C:/path/to/file.jpg");
Path path = file.toPath();
String fileType = Files.probeContentType(path);
System.out.println("File type: " + fileType);เมื่อรันโค้ดข้างต้น ระบบจะแสดงประเภทของไฟล์
โปรดทราบว่า สำหรับไฟล์บางประเภทที่มีลักษณะพิเศษ เช่น ไฟล์ปฏิบัติการที่ไม่มีนามสกุล วิธีที่อาศัยนามสกุลไฟล์เช่นนี้อาจไม่แม่นยำเพียงพอ จึงแนะนำให้ใช้วิธีที่อาศัยค่าแมจิกนัมเบอร์ของไฟล์ซึ่งได้อธิบายไปก่อนหน้านี้มากกว่า
สี่、สรุป
บทความนี้แนะนำวิธีหลายแบบในการระบุประเภทไฟล์ใน Java สามารถระบุประเภทไฟล์จากนามสกุลไฟล์ หรือจากเลขมหัศจรรย์ของไฟล์ก็ได้ การใช้ไลบรารีของบุคคลที่สาม เช่น Tika ช่วยให้ระบุประเภทไฟล์ได้สะดวกยิ่งขึ้น สำหรับไฟล์ประเภทพิเศษ สามารถสร้างตัวตรวจจับประเภทไฟล์ขึ้นเองเพื่อระบุได้อย่างแม่นยำ
การเลือกวิธีที่เหมาะสมเพื่อระบุชนิดไฟล์ขึ้นอยู่กับสถานการณ์ใช้งานและความต้องการเฉพาะ ในการพัฒนาจริง ให้เลือกวิธีตรวจสอบที่เหมาะสมที่สุดตามลักษณะของไฟล์และความต้องการ พร้อมคำนึงถึงความสามารถในการขยายและความเข้ากันได้。