package ch.retorte.intervalmusiccompositor.audiofile; import java.io.File; import java.io.FileInputStream; /** * @author nw */ public abstract class AudioFileProperties { protected abstract String[] getFileExtensions(); /** * Returns an array of hex strings representing the respective magic numbers of this media type. E.g. the mp3 file format has 'ID3' as magic number, which is * '49 44 33' as a hex string. The hex string may contain empty spaces for improved readability. Furthermore it may contain wildcards in the form of 'nn' * which denotes any hex item, e.g. '12 34 nn 56' matches '12 34 11 56' as well as '12 34 22 56'. */ protected abstract String[] getMagicNumberHexStrings(); public boolean isOfThisType(File file) { for (String magicNumber : getMagicNumberHexStrings()) { if (fileStartsWith(file, magicNumber)) { return true; } } String lowerCaseName = file.getName().toLowerCase(); for (String extension : getFileExtensions()) { if (lowerCaseName.endsWith(extension)) { return true; } } return false; } public boolean fileStartsWith(File file, String magicByteHexString) { byte[] magicNumberBuffer = new byte[hexStringToByteArray(magicByteHexString).length]; try { FileInputStream fileInputStream = new FileInputStream(file); fileInputStream.read(magicNumberBuffer); fileInputStream.close(); } catch (Exception e) { return false; } return compareByteArrayWithHexString(magicNumberBuffer, magicByteHexString); } private boolean compareByteArrayWithHexString(byte[] byteArray, String hexString) { String normalizedHexString = hexString.replaceAll(" ", ""); for (int i = 0; i < byteArray.length; i++) { byte b = byteArray[i]; String hexItem = normalizedHexString.substring(i * 2, i * 2 + 2); if (!hexItem.equals("nn") && b != hexStringToByteArray(hexItem)[0]) { return false; } } return true; } /** * Taken from http://stackoverflow.com/questions/11208479/how-do-i-initialize-a-byte-array-in-java/11208685#11208685 */ private byte[] hexStringToByteArray(String s) { s = s.replaceAll(" ", ""); int len = s.length(); byte[] data = new byte[len / 2]; for (int i = 0; i < len; i += 2) { data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4) + Character.digit(s.charAt(i + 1), 16)); } return data; } }