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