/** * @param startByte * @param endByte * @return * @throws Exception * @return true if all the bytes between in the file between startByte and endByte are null, false * otherwise */ private boolean isFilePortionNull(int startByte, int endByte) throws IOException { logger.config("Checking file portion:" + Hex.asHex(startByte) + ":" + Hex.asHex(endByte)); FileInputStream fis = null; FileChannel fc = null; try { fis = new FileInputStream(file); fc = fis.getChannel(); fc.position(startByte); ByteBuffer bb = ByteBuffer.allocateDirect(endByte - startByte); fc.read(bb); while (bb.hasRemaining()) { if (bb.get() != 0) { return false; } } } finally { if (fc != null) { fc.close(); } if (fis != null) { fis.close(); } } return true; }
/** * Extracts the raw ID3v2 tag data into a file. * * <p>This provides access to the raw data before manipulation, the data is written from the start * of the file to the start of the Audio Data. This is primarily useful for manipulating corrupted * tags that are not (fully) loaded using the standard methods. * * @param outputFile to write the data to * @return * @throws TagNotFoundException * @throws IOException */ public File extractID3v2TagDataIntoFile(File outputFile) throws TagNotFoundException, IOException { int startByte = (int) ((MP3AudioHeader) audioHeader).getMp3StartByte(); if (startByte >= 0) { // Read byte into buffer FileInputStream fis = new FileInputStream(file); FileChannel fc = fis.getChannel(); ByteBuffer bb = ByteBuffer.allocate(startByte); fc.read(bb); // Write bytes to outputFile FileOutputStream out = new FileOutputStream(outputFile); out.write(bb.array()); out.close(); fc.close(); fis.close(); return outputFile; } throw new TagNotFoundException("There is no ID3v2Tag data in this file"); }
/** * Read V2tag if exists * * <p>TODO:shouldn't we be handing TagExceptions:when will they be thrown * * @param file * @param loadOptions * @throws IOException * @throws TagException */ private void readV2Tag(File file, int loadOptions, int startByte) throws IOException, TagException { // We know where the actual Audio starts so load all the file from start to that point into // a buffer then we can read the IDv2 information without needing any more File I/O if (startByte >= AbstractID3v2Tag.TAG_HEADER_LENGTH) { logger.finer("Attempting to read id3v2tags"); FileInputStream fis = null; FileChannel fc = null; ByteBuffer bb; try { fis = new FileInputStream(file); fc = fis.getChannel(); bb = fc.map(FileChannel.MapMode.READ_ONLY, 0, startByte); } // #JAUDIOTAGGER-419:If reading networked file map can fail so just copy bytes instead catch (IOException ioe) { bb = ByteBuffer.allocate(startByte); fc.read(bb, 0); } finally { if (fc != null) { fc.close(); } if (fis != null) { fis.close(); } } try { bb.rewind(); if ((loadOptions & LOAD_IDV2TAG) != 0) { logger.config("Attempting to read id3v2tags"); try { this.setID3v2Tag(new ID3v24Tag(bb, file.getName())); } catch (TagNotFoundException ex) { logger.config("No id3v24 tag found"); } try { if (id3v2tag == null) { this.setID3v2Tag(new ID3v23Tag(bb, file.getName())); } } catch (TagNotFoundException ex) { logger.config("No id3v23 tag found"); } try { if (id3v2tag == null) { this.setID3v2Tag(new ID3v22Tag(bb, file.getName())); } } catch (TagNotFoundException ex) { logger.config("No id3v22 tag found"); } } } finally { // Workaround for 4724038 on Windows bb.clear(); if (bb.isDirect() && !TagOptionSingleton.getInstance().isAndroid()) { // Reflection substitute for following code: // ((sun.nio.ch.DirectBuffer) bb).cleaner().clean(); // which causes exception on Android - Sun NIO classes are not available try { Class<?> clazz = Class.forName("sun.nio.ch.DirectBuffer"); Method cleanerMethod = clazz.getMethod("cleaner"); Object cleaner = cleanerMethod.invoke(bb); // cleaner = bb.cleaner() if (cleaner != null) { Method cleanMethod = cleaner.getClass().getMethod("clean"); cleanMethod.invoke(cleaner); // cleaner.clean() } } catch (ClassNotFoundException e) { logger.severe("Could not load sun.nio.ch.DirectBuffer."); } catch (NoSuchMethodException e) { logger.severe("Could not invoke DirectBuffer method - " + e.getMessage()); } catch (InvocationTargetException e) { logger.severe("Could not invoke DirectBuffer method - target exception"); } catch (IllegalAccessException e) { logger.severe("Could not invoke DirectBuffer method - illegal access"); } } } } else { logger.config("Not enough room for valid id3v2 tag:" + startByte); } }