我的mp3分割程序错误?

时间:2013-07-26 16:26:12

标签: java mp3

所以,我制作了一个用Java分割.mp3文件的程序。基本上,它在某些文件上工作正常但在某些文件中,第一个分割文件在播放某些部分后遇到错误。其他文件完全正常。

我认为它与文件如何不是我的数组大小的倍数有关,应该有一些mod值。有人可以在此代码中找出错误并更正吗?

(此处,splitval =要进行拆分的编号,filename1 =所选文件)

 int splitsize=filesize/splitval;
 String filecalled;
 try
 {
        byte []b=new byte[splitsize];
        FileInputStream fis = new FileInputStream(filename1);
        name1=filename2.replaceAll(".mp3", "");
        for(int j=1;j<=splitval;j++)
        {
            filecalled=name1+"_split_"+j+".mp3";
            FileOutputStream fos = new FileOutputStream(filecalled);
            int i=fis.read(b);
            fos.write(b, 0, i);
            //System.out.println("no catch");
         }
        JOptionPane.showMessageDialog(this, "split process successful");
     }
   catch(IOException e)
       {
           System.out.println(e.getMessage());

       }

提前致谢!

编辑: 我按照建议编辑了代码,运行它。这里:

C:\Users\dell5050\Desktop\Julien.mp3      5383930 bytes  
C:\Users\dell5050\Desktop\ Julien_split_1.mp3    1345984 bytes  
C:\Users\dell5050\Desktop\ Julien_split_2.mp3    1345984 bytes  
C:\Users\dell5050\Desktop\ Julien_split_3.mp3    1345984 bytes  
C:\Users\dell5050\Desktop\ Julien_split_4.mp3    1345978 bytes  

最后几个字节有变化,这意味着文件大小%splitval已经解决了..但是在播放部分最后一部分时,包含'_split_1'的第一个文件仍然有错误。

包含'_split_2'的第二个文件正好从第一个结束的位置开始。因此拆分过程是正确的。那么,第一个文件末尾的额外空是什么?

另外,我注意到原始文件的图稿和信息只会转移到第一个文件中。没有其他文件。它与此有关吗?在其他一些mp3文件中也不会发生同样的事情。

CODE:

FileInputStream fis;
    FileOutputStream fos;
    int splitsize = (int)(filesize / splitval) + (int)(filesize % splitval);
    byte[] b = new byte[splitsize];
    System.out.println(filename1 + "            " + filesize + " bytes");
    try 
    {
        fis = new FileInputStream(file);
        name1 = filename2.replaceAll(".mp3", "");
        for (int j = 1; j <= splitval; j++) 
        {
            String filecalled = name1 + "_split_" + j + ".mp3";
            fos = new FileOutputStream(filecalled);
            int i = fis.read(b);
            fos.write(b, 0, i);
            fos.close();
            System.out.println(filecalled + "    " + i + " bytes");

        }
    }
    catch(IOException ie)
    {
        System.out.println(ie.getMessage());
    }                        

1 个答案:

答案 0 :(得分:2)

我怀疑你是否可以通过将n个字节复制到文件来分割mp3文件并转到下一个文件。 Mp3有一个specific format,您可能需要一个library来处理这种格式。

关于零件文件大小相等的

编辑

您没有将文件的所有字节写入split文件。如果将所有split文件的大小相加并将其与原始文件的大小进行比较,您将发现缺少一些字节。这是因为您的循环从1运行到splitval并始终将确切的字节数写入每个零件文件,即splitsize。因此,缺少的字节数为filesize % splitval

要解决此问题,只需将filesize % splitval添加到splitsize即可。这样你就不会错过任何字节。从1splitval - 1的文件大小相同,最后一个文件会更小。

以下是代码的更正版本,并添加了一些内容以合并split文件,以便使用SHA1校验和执行断言。

免责声明 - 输出文件不应该是正确的mp3文件

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

import junit.framework.Assert;

import org.junit.Test;

public class SplitFile {

    @Test
    public void splitFile() throws IOException, NoSuchAlgorithmException {
        String filename1 = "mp3/Innocence_-_Nero.mp3";
        File file = new File(filename1);
        FileInputStream fis = null;
        FileOutputStream fos = null;
        long filesize = file.length();
        long filesizeActual = 0L;
        int splitval = 5;
        int splitsize = (int)(filesize / splitval) + (int)(filesize % splitval);
        byte[] b = new byte[splitsize];
        System.out.println(filename1 + "            " + filesize + " bytes");
        try {
            fis = new FileInputStream(file);
            String name1 = filename1.replaceAll(".mp3", "");
            String mergeFile = name1 + "_merge.mp3";
            for (int j = 1; j <= splitval; j++) {
                String filecalled = name1 + "_split_" + j + ".mp3";
                fos = new FileOutputStream(filecalled);
                int i = fis.read(b);
                fos.write(b, 0, i);
                fos.close();
                fos = null;
                System.out.println(filecalled + "    " + i + " bytes");
                filesizeActual += i;
            }
            Assert.assertEquals(filesize, filesizeActual);
            mergeFileParts(filename1, splitval);
            check(filename1, mergeFile);
        } finally {
            if(fis != null) {
                fis.close();
            }
            if(fos != null) {
                fos.close();
            }
        }
    }

    private void mergeFileParts(String filename1, int splitval) throws IOException {
        FileInputStream fis = null;
        FileOutputStream fos = null;
        try {
            String name1 = filename1.replaceAll(".mp3", "");
            String mergeFile = name1 + "_merge.mp3";
            fos = new FileOutputStream(mergeFile);
            for (int j = 1; j <= splitval; j++) {
                String filecalled = name1 + "_split_" + j + ".mp3";
                File partFile = new File(filecalled);
                fis = new FileInputStream(partFile);
                int partFilesize = (int) partFile.length();
                byte[] b = new byte[partFilesize];
                int i = fis.read(b, 0, partFilesize);
                fos.write(b, 0, i);
                fis.close();
                fis = null;
            }
        } finally {
            if(fis != null) {
                fis.close();
            }
            if(fos != null) {
                fos.close();
            }
        }
    }

    private void check(String expectedPath, String actualPath) throws IOException, NoSuchAlgorithmException {
        System.out.println("check...");

        FileInputStream fis = null;

        try {

            File expectedFile = new File(expectedPath);
            long expectedSize = expectedFile.length();

            File actualFile = new File(actualPath);
            long actualSize = actualFile.length();

            System.out.println("exp=" + expectedSize);
            System.out.println("act=" + actualSize);

            Assert.assertEquals(expectedSize, actualSize);

            fis = new FileInputStream(expectedFile);
            String expected = makeMessageDigest(fis);
            fis.close();
            fis = null;


            fis = new FileInputStream(actualFile);
            String actual = makeMessageDigest(fis);
            fis.close();
            fis = null;

            System.out.println("exp=" + expected);
            System.out.println("act=" + actual);

            Assert.assertEquals(expected, actual);

        } finally {
            if(fis != null) {
                fis.close();
            }
        }
    }

    public String makeMessageDigest(InputStream is) throws NoSuchAlgorithmException, IOException {
        byte[] data = new byte[1024];
        MessageDigest md = MessageDigest.getInstance("SHA1");
        int bytesRead = 0;

        while(-1 != (bytesRead = is.read(data, 0, 1024))) {
            md.update(data, 0, bytesRead);
        }

        return toHexString(md.digest());
    }

    private String toHexString(byte[] digest) {
        StringBuffer sha1HexString = new StringBuffer();
        for(int i = 0; i < digest.length; i++) {
            sha1HexString.append(String.format("%1$02x", Byte.valueOf(digest[i])));
        }

        return sha1HexString.toString();
    }
}

输出(对于我的测试文件)

mp3/Innocence_-_Nero.mp3            5048528 bytes
mp3/Innocence_-_Nero_split_1.mp3    1009708 bytes
mp3/Innocence_-_Nero_split_2.mp3    1009708 bytes
mp3/Innocence_-_Nero_split_3.mp3    1009708 bytes
mp3/Innocence_-_Nero_split_4.mp3    1009708 bytes
mp3/Innocence_-_Nero_split_5.mp3    1009696 bytes
check...
exp=5048528
act=5048528
exp=e81cf2dc65ab84e3df328e52d63a55301232b917
act=e81cf2dc65ab84e3df328e52d63a55301232b917