0

そこで、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  

最後の数バイトに変更があります。これは、filesize%splitval が解決されたことを意味します..しかし、'_split_1' を含むこの..の最初のファイルは、最後の部分の一部を再生中にエラーが発生しました。

'_split_2' を含む 2 番目のファイルは、最初のファイルが終了したところから始まります。したがって、分割プロセスは正しいです。では、最初のファイルの最後にある余分な空は正確には何ですか?

また、元のファイルのアートワークと情報が最初のファイルにのみ引き継がれることに気付きました。他のファイルはありません。それと何か関係がありますか?他のいくつかの mp3 ファイルでは同じことが起こりません。

コード:

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());
    }                        
4

1 に答える 1

2

mp3nバイトをファイルにコピーして次のファイルに移動するだけで、ファイルを分割できるとは思えません。Mp3 には特定の形式があり、この形式を処理するにはおそらくライブラリが必要です。

パーツファイルのサイズがすべて等しいことに関する編集:

ファイルのすべてのバイトをファイルに書き込んでいるわけではありませんsplit。すべてのsplitファイルのサイズを合計して元のファイルのサイズと比較すると、数バイトが不足していることがわかります。これは、ループが から1に実行されsplitval、常に正確なバイト数を各パーツ ファイルに書き込むためですsplitsize。したがって、欠落しているバイト数は ですfilesize % splitval

filesize % splitvalこの問題を解決するには、単にsplitsize. これにより、バイトが失われることはありません。から1までのファイルsplitval - 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
于 2013-07-26T16:38:57.273 に答える