use of java.nio.channels.FileChannel in project MusicDNA by harjot-oberai.
the class MP3File method readV2Tag.
/**
* Read V2tag if exists
*
* TODO:shouldn'timer 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 {
//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();
// avoid using fc.map method since it does not work on Android ICS and JB. Bug report: https://code.google.com/p/android/issues/detail?id=53637
// bb = fc.map(FileChannel.MapMode.READ_ONLY,0,startByte);
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 {
bb.clear();
}
} else {
logger.config("Not enough room for valid id3v2 tag:" + startByte);
}
}
use of java.nio.channels.FileChannel in project MusicDNA by harjot-oberai.
the class MP3File method isFilePortionNull.
/**
*
* @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;
}
use of java.nio.channels.FileChannel in project MusicDNA by harjot-oberai.
the class Mp4AtomTree method buildTree.
/**
* Build a tree of the atoms in the file
*
* @param raf
* @param closeExit false to keep randomfileacces open, only used when randomaccessfile already being used
* @return
* @throws java.io.IOException
* @throws org.jaudiotagger.audio.exceptions.CannotReadException
*/
public DefaultTreeModel buildTree(RandomAccessFile raf, boolean closeExit) throws IOException, CannotReadException {
FileChannel fc = null;
try {
fc = raf.getChannel();
//make sure at start of file
fc.position(0);
//Build up map of nodes
rootNode = new DefaultMutableTreeNode();
dataTree = new DefaultTreeModel(rootNode);
//Iterate though all the top level Nodes
ByteBuffer headerBuffer = ByteBuffer.allocate(Mp4BoxHeader.HEADER_LENGTH);
while (fc.position() < fc.size()) {
Mp4BoxHeader boxHeader = new Mp4BoxHeader();
headerBuffer.clear();
fc.read(headerBuffer);
headerBuffer.rewind();
try {
boxHeader.update(headerBuffer);
} catch (NullBoxIdException ne) {
//If we only get this error after all the expected data has been found we allow it
if (moovNode != null & mdatNode != null) {
NullPadding np = new NullPadding(fc.position() - Mp4BoxHeader.HEADER_LENGTH, fc.size());
DefaultMutableTreeNode trailingPaddingNode = new DefaultMutableTreeNode(np);
rootNode.add(trailingPaddingNode);
logger.warning(ErrorMessage.NULL_PADDING_FOUND_AT_END_OF_MP4.getMsg(np.getFilePos()));
break;
} else {
//File appears invalid
throw ne;
}
}
boxHeader.setFilePos(fc.position() - Mp4BoxHeader.HEADER_LENGTH);
DefaultMutableTreeNode newAtom = new DefaultMutableTreeNode(boxHeader);
//Go down moov
if (boxHeader.getId().equals(Mp4AtomIdentifier.MOOV.getFieldName())) {
//and finish
if (moovNode != null & mdatNode != null) {
logger.warning(ErrorMessage.ADDITIONAL_MOOV_ATOM_AT_END_OF_MP4.getMsg(fc.position() - Mp4BoxHeader.HEADER_LENGTH));
break;
}
moovNode = newAtom;
moovHeader = boxHeader;
long filePosStart = fc.position();
moovBuffer = ByteBuffer.allocate(boxHeader.getDataLength());
int bytesRead = fc.read(moovBuffer);
//If Moov atom is incomplete we are not going to be able to read this file properly
if (bytesRead < boxHeader.getDataLength()) {
String msg = ErrorMessage.ATOM_LENGTH_LARGER_THAN_DATA.getMsg(boxHeader.getId(), boxHeader.getDataLength(), bytesRead);
throw new CannotReadException(msg);
}
moovBuffer.rewind();
buildChildrenOfNode(moovBuffer, newAtom);
fc.position(filePosStart);
} else if (boxHeader.getId().equals(Mp4AtomIdentifier.FREE.getFieldName())) {
//Might be multiple in different locations
freeNodes.add(newAtom);
} else if (boxHeader.getId().equals(Mp4AtomIdentifier.MDAT.getFieldName())) {
//mdatNode always points to the last mDatNode, normally there is just one mdatnode but do have
//a valid example of multiple mdatnode
//if(mdatNode!=null)
//{
// throw new CannotReadException(ErrorMessage.MP4_FILE_CONTAINS_MULTIPLE_DATA_ATOMS.getMsg());
//}
mdatNode = newAtom;
mdatNodes.add(newAtom);
}
rootNode.add(newAtom);
fc.position(fc.position() + boxHeader.getDataLength());
}
return dataTree;
} finally {
//now rather than later when try and write to it.
if (mdatNode == null) {
throw new CannotReadException(ErrorMessage.MP4_CANNOT_FIND_AUDIO.getMsg());
}
if (closeExit) {
fc.close();
}
}
}
use of java.nio.channels.FileChannel in project MusicDNA by harjot-oberai.
the class AbstractID3v1Tag method delete.
/**
* Delete tag from file
* Looks for tag and if found lops it off the file.
*
* @param file to delete the tag from
* @throws IOException if there was a problem accessing the file
*/
public void delete(RandomAccessFile file) throws IOException {
//Read into Byte Buffer
logger.config("Deleting ID3v1 from file if exists");
FileChannel fc;
ByteBuffer byteBuffer;
fc = file.getChannel();
if (file.length() < TAG_LENGTH) {
throw new IOException("File not not appear large enough to contain a tag");
}
fc.position(file.length() - TAG_LENGTH);
byteBuffer = ByteBuffer.allocate(TAG_LENGTH);
fc.read(byteBuffer);
byteBuffer.rewind();
if (AbstractID3v1Tag.seekForV1OrV11Tag(byteBuffer)) {
try {
logger.config("Deleted ID3v1 tag");
file.setLength(file.length() - TAG_LENGTH);
} catch (IOException ex) {
logger.severe("Unable to delete existing ID3v1 Tag:" + ex.getMessage());
}
} else {
logger.config("Unable to find ID3v1 tag to deleteField");
}
}
use of java.nio.channels.FileChannel in project MusicDNA by harjot-oberai.
the class AbstractID3v2Tag method getV2TagSizeIfExists.
/**
* Checks to see if the file contains an ID3tag and if so return its size as reported in
* the tag header and return the size of the tag (including header), if no such tag exists return
* zero.
*
* @param file
* @return the end of the tag in the file or zero if no tag exists.
* @throws java.io.IOException
*/
public static long getV2TagSizeIfExists(File file) throws IOException {
FileInputStream fis = null;
FileChannel fc = null;
ByteBuffer bb = null;
try {
//Files
fis = new FileInputStream(file);
fc = fis.getChannel();
//Read possible Tag header Byte Buffer
bb = ByteBuffer.allocate(TAG_HEADER_LENGTH);
fc.read(bb);
bb.flip();
if (bb.limit() < (TAG_HEADER_LENGTH)) {
return 0;
}
} finally {
if (fc != null) {
fc.close();
}
if (fis != null) {
fis.close();
}
}
//ID3 identifier
byte[] tagIdentifier = new byte[FIELD_TAGID_LENGTH];
bb.get(tagIdentifier, 0, FIELD_TAGID_LENGTH);
if (!(Arrays.equals(tagIdentifier, TAG_ID))) {
return 0;
}
//Is it valid Major Version
byte majorVersion = bb.get();
if ((majorVersion != ID3v22Tag.MAJOR_VERSION) && (majorVersion != ID3v23Tag.MAJOR_VERSION) && (majorVersion != ID3v24Tag.MAJOR_VERSION)) {
return 0;
}
//Skip Minor Version
bb.get();
//Skip Flags
bb.get();
//Get size as recorded in frame header
int frameSize = ID3SyncSafeInteger.bufferToValue(bb);
//addField header size to frame size
frameSize += TAG_HEADER_LENGTH;
return frameSize;
}
Aggregations