Java 如何逐字节写入并连续显示

Java 如何逐字节写入并连续显示,java,Java,我对视频文件进行了加密,在解密时,我定义了ByteByte[]输入=新字节[1024]大小以将其写入输出文件。 在这里,我想在输出文件中写入前1024个字节,同时如果想播放该视频文件,我可以播放该输出文件,而无需等待像视频流一样写入整个文件 当写入第一个1024字节时,视频文件将开始播放,直到写入整个文件。您必须在单独的线程中进行写入。 由于写入文件要比显示视频慢得多,所以在您停止观看视频后,文件写入线程可能会运行很长时间。除非(据我所知)您打算只将前1024个字节写入文件 如果您打算将整个视频

我对视频文件进行了加密,在解密时,我定义了Byte
Byte[]输入=新字节[1024]大小以将其写入输出文件。
在这里,我想在输出文件中写入前1024个字节,同时如果想播放该视频文件,我可以播放该输出文件,而无需等待像视频流一样写入整个文件


当写入第一个1024字节时,视频文件将开始播放,直到写入整个文件。

您必须在单独的线程中进行写入。
由于写入文件要比显示视频慢得多,所以在您停止观看视频后,文件写入线程可能会运行很长时间。除非(据我所知)您打算只将前1024个字节写入文件

如果您打算将整个视频写入文件,一个1024字节的缓冲区将降低您的速度。您必须使用更大的缓冲区,或者需要大量1024字节的缓冲区。(我认为1024字节的缓冲区大小是解密算法的结果?

此外,您可能希望查看JVM有多少可用内存,以确保不会中途出现OutOfMemoryException。您可以使用
-Xms
-Xmx
选项设置JVM可用的内存量。

写入文件的一种简单方法,您还需要处理的是打开文件两次(或更多次)。在一个线程中,您写入文件并更新计数器,以说明您写入了多少,例如受
同步
块保护的
。在读取线程中,您可以获取该值并一直读取到该点,重复读取,直到编写器完成。发出写入完成信号的一种简单方法是将大小设置为Long.MAX_值,使读卡器读取到EOF。要停止读卡器忙于等待,可以让它们等待(),直到写入的数据大于读取的数据量


这种方法始终使用固定的内存量,例如16-128K,而不管读卡器与写卡器之间的距离有多远。

您必须根据获取数据的位置以及保存/查看数据的位置设置输入流和输出流。通过对输出进行一些缓冲,也可以提高性能。你应该了解大概情况

public class DecryptionWotsit {
    private final BlockingDeque<Byte> queue = new LinkedBlockingDeque<Byte>();
    private final InputStream in;
    private final OutputStream out;
    public DecryptionWotsit(InputStream in, OutputStream out) {
        this.in = in;
        this.out = out;
    }

    public void go() {
        final Runnable decryptionTask = new Runnable() {
            @Override
            public void run() {
                try {
                    byte[] encrypted = new byte[1024];
                    byte[] decrypted = new byte[1024];
                    while (true) {
                        int encryptedBytes = in.read(encrypted);

                        // TODO: decrypt into decrypted, set decryptedBytes
                        int decryptedBytes = 0;

                        for (int i = 0; i < decryptedBytes; i++)
                            queue.addFirst(decrypted[i]);
                    }
                }
                catch (Exception e) {
                    // exception handling left for the reader
                    throw new RuntimeException(e);
                }
            }
        };
        final Runnable playTask = new Runnable() {
            @Override
            public void run() {
                try {
                    while (true) {
                        out.write(queue.takeLast());
                    }
                }
                catch (Exception e) {
                    throw new RuntimeException(e);
                }
            }
        };
        Executors.newSingleThreadExecutor().execute(decryptionTask);
        Executors.newSingleThreadExecutor().execute(playTask);
    }
}
公共类解密wotsit{
private final BlockingDeque queue=new LinkedBlockingDeque();
私有最终输入流;
私有最终输出流输出;
公共解密WOTSIT(输入流输入,输出流输出){
this.in=in;
this.out=out;
}
公开作废go(){
final Runnable decryptionTask=new Runnable(){
@凌驾
公开募捐{
试一试{
字节[]加密=新字节[1024];
字节[]解密=新字节[1024];
while(true){
int encryptedBytes=in.read(加密);
//TODO:解密为decrypted,设置decryptedBytes
int decryptedBytes=0;
for(int i=0;i