1

基本上我使用 Java 中的自定义压缩器类压缩视频。我在这里组装了完整的代码片段。我的实际问题是,从解压缩的字节数组生成的视频 [A.mp4] 没有运行。我实际上是通过互联网获得了这个压缩机类代码。作为 Java 平台的新手,我正在努力解决这个问题。你能请任何人帮助我吗?

public class CompressionTest
{
    public static void main(String[] args)
    {
        Compressor compressor = new Compressor();

        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        FileInputStream fis=null;
        File file=null;

        try
        {
            URL uri=CompressionTest.class.getResource("/Files/Video.mp4");
            file=new File(uri.getPath());
            fis = new FileInputStream(file);
        } 
        catch ( FileNotFoundException fnfe )
        {
            System.out.println( "Unable to open input file");
        }

        try 
        {

            byte[] videoBytes = getBytesFromFile(file);

            System.out.println("CompressionVideoToCompress is: '" +videoBytes + "'");

            byte[] bytesCompressed = compressor.compress(videoBytes);

            System.out.println("bytesCompressed is: '" +bytesCompressed+ "'");

            byte[] bytesDecompressed=compressor.decompress(bytesCompressed);

            System.out.println("bytesDecompressed is: '" +bytesDecompressed+ "'");

            FileOutputStream out = new FileOutputStream("A.mp4");
            out.write(bytesDecompressed,0,bytesDecompressed.length-1);
            out.close();

        } 
        catch (IOException e) 
        {
            // TODO Auto-generated catch block
            System.out.println("bytesCompressed is: '");
        }


    }

    public static byte[] getBytesFromFile(File file) throws IOException 
    {
        InputStream is = new FileInputStream(file);

        // Get the size of the file
        long length = file.length();

        // You cannot create an array using a long type.
        // It needs to be an int type.
        // Before converting to an int type, check
        // to ensure that file is not larger than Integer.MAX_VALUE.
        if (length > Integer.MAX_VALUE) {
            // File is too large
        }

        // Create the byte array to hold the data
        byte[] bytes = new byte[1064];

        // Read in the bytes
        int offset = 0;
        int numRead = 0;
        while (offset < bytes.length
               && (numRead=is.read(bytes, offset, bytes.length-offset)) >= 0)
        {
            offset += numRead;
        }

        // Ensure all the bytes have been read in
        if (offset < bytes.length) {
            throw new IOException("Could not completely read file "+file.getName());
        }

        // Close the input stream and return bytes
        is.close();
        return bytes;
    }
}

class Compressor
{
    public Compressor()
    {}

    public byte[] compress(byte[] bytesToCompress)
    {        
        Deflater deflater = new Deflater();
        deflater.setInput(bytesToCompress);
        deflater.finish();

        byte[] bytesCompressed = new byte[Short.MAX_VALUE];

        int numberOfBytesAfterCompression = deflater.deflate(bytesCompressed);

        byte[] returnValues = new byte[numberOfBytesAfterCompression];

        System.arraycopy
        (
            bytesCompressed,
            0,
            returnValues,
            0,
            numberOfBytesAfterCompression
        );

        return returnValues;
    }

    public byte[] decompress(byte[] bytesToDecompress)
    {
        Inflater inflater = new Inflater();

        int numberOfBytesToDecompress = bytesToDecompress.length;

        inflater.setInput
        (
            bytesToDecompress,
            0,
            numberOfBytesToDecompress
        );

        int compressionFactorMaxLikely = 3;

        int bufferSizeInBytes =
            numberOfBytesToDecompress
            * compressionFactorMaxLikely;

        byte[] bytesDecompressed = new byte[bufferSizeInBytes];

        byte[] returnValues = null;

        try
        {
            int numberOfBytesAfterDecompression = inflater.inflate(bytesDecompressed);

            returnValues = new byte[numberOfBytesAfterDecompression];

            System.arraycopy
            (
                bytesDecompressed,
                0,
                returnValues,
                0,
                numberOfBytesAfterDecompression
            );            
        }
        catch (DataFormatException dfe)
        {
            dfe.printStackTrace();
        }

        inflater.end();

        return returnValues;
    }
}
4

2 回答 2

1

两个提示:

1) 替换getBytesFromFile为众所周知的 API 调用,使用 Apache commons (IOUtils) 或 java 7 现在也提供了这样的方法。
2)测试compressdecompress编写一个Junit测试:创建一个随机的大字节数组,将其写出,读回并与创建的数组进行比较。

于 2013-02-18T12:07:34.053 回答
1

我已经通过压缩和解压缩一个简单的 TXT 文件来测试您的代码。代码已损坏,因为压缩文件在未压缩时与原始文件不同。

理所当然地认为代码至少getBytesFromFile函数中被破坏了。它的逻辑既棘手又麻烦,因为它只允许长度为 1064 的文件,并且检查(IOException读取较长文件时抛出)根本不起作用。该文件仅部分读取,不会引发异常。

您想要实现的目标(文件压缩/解压缩)可以通过这种方式完成。我已经测试过了,它可以工作,你只需要这个库

import java.io.*;
import java.util.zip.*;
import org.apache.commons.io.IOUtils; // <-- get this from http://commons.apache.org/io/index.html

public class CompressionTest2 {

    public static void main(String[] args) throws IOException {
        File input = new File("input.txt");
        File output = new File("output.bin");
        Compression.compress(input, output);
        File input2 = new File("input2.txt");
        Compression.decompress(output, input2);
        // At this point, input.txt and input2.txt should be equal
    }

}

class Compression {

    public static void compress(File input, File output) throws IOException {
        FileInputStream fis = new FileInputStream(input);
        FileOutputStream fos = new FileOutputStream(output);
        GZIPOutputStream gzipStream = new GZIPOutputStream(fos);
        IOUtils.copy(fis, gzipStream);
        gzipStream.close();
        fis.close();
        fos.close();
    }

    public static void decompress(File input, File output) throws IOException {
        FileInputStream fis = new FileInputStream(input);
        FileOutputStream fos = new FileOutputStream(output);
        GZIPInputStream gzipStream = new GZIPInputStream(fis);
        IOUtils.copy(gzipStream, fos);
        gzipStream.close();
        fis.close();
        fos.close();
    }

}

此代码并非来自“可靠和/或官方来源”,但至少它有效。:)

此外,为了获得更多答案,请调整标题以说明您的真正问题:您的压缩文件没有以正确的方式解压。这里没有“视频”的东西。此外,压缩.mp4文件也不是什么成就(压缩率可能在 99.99% 左右)。

于 2013-02-18T12:14:02.557 回答