IO使用Buffer复制流媒体文件

Posted ysirsun

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了IO使用Buffer复制流媒体文件相关的知识,希望对你有一定的参考价值。

之前的文章整理一下重新发布

java io流有如下内容:

技术图片

      使用java-io流复制文件时,可以从以下步骤来进行判断使用何种流:

1.首先判断是源文件还是目的文件,若为源文件就使用inputstream和reader,否则就使用outputstream和writer;

2.如果是文本文件使用字节流,所以使用inputstream/outputstream体系,媒体文件就使用reader/writer体系;

3.接下来明确使用体系中的那个对象,reader中操作文件的对象是filereader,inputstream体系中操作文件的对象是fileinputstream;

4.是否提高效率:如需提高效率,使用缓存类buffered~,只要用到缓冲区,就要记得刷新,关闭缓冲区,就是在关闭缓冲区中的流对象。

     ① 完整的复制媒体文件的类如下:

 1 import java.io.BufferedInputStream;
 2 import java.io.FileInputStream;
 3 import java.io.FileNotFoundException;
 4 import java.io.FileOutputStream;
 5 import java.io.IOException;
 6 import java.io.InputStream;
 7 import java.io.OutputStream;
 8 
 9 public class CopyMdeia {
10 
11     public static void main(String[] args) {
12         // TODO Auto-generated method stub
13         try {
14             InputStream is = new FileInputStream("e://txdx.mp3");
15             BufferedInputStream bis = new BufferedInputStream(is);
16             OutputStream os = new FileOutputStream("d://txdx.mp3");
17             byte[] buffer = new byte[1024];
18             int count = 0;
19             try {
20                 while((count=bis.read(buffer))!=-1) {
21                     os.write(buffer, 0, count);    
22                 }                
23             }catch(IOException e) {
24                 // TODO Auto-generated catch block
25                 e.printStackTrace();
26             }
27             try {
28                 os.flush();
29                 os.close();
30                 bis.close();
31             } catch (IOException e) {
32                 // TODO Auto-generated catch block
33                 e.printStackTrace();
34             }
35         } catch (FileNotFoundException e) {
36             // TODO Auto-generated catch block
37             e.printStackTrace();
38         }
39     }
40 }

 

     ② 接下来编写自己的缓存类:

 1 import java.io.FileInputStream;
 2 import java.io.IOException;
 3 
 4 public class MyIputStremBufferedFileMediaCopy {
 5 
 6     private FileInputStream fis = null;
 7 
 8     private byte[] by = new byte[1024];
 9 
10     private int len = 0, p = 0;
11 
12     MyIputStremBufferedFileMediaCopy(FileInputStream fis) {
13         this.fis = fis;
14     }
15 
16     public int Read() throws IOException {
17 
18         if (len == 0) {
19             len = fis.read(by);
20             if (len < 0)
21                 return -1;
22             p = 0;
23             byte b = by[p];
24             p++;
25             len--;
26             return b & 255;
27         } else if (len > 0) {
28             byte b = by[p];
29             p++;
30             len--;
31             return b & 255;
32         }
33         return -1;
34     }
35 
36     public void myClose() throws IOException {
37         fis.close();
38     }
39 }

       这里解释下为什么要&255:

* 因为read读取到的是二进制数据,二进制数据是由0和1组成的,有可能出现11111111
* 作为一个字节来讲11111111的十进制是-1,由于返回值是int类型,就会自动提升,int类型是32位,在前面补1,
* 就成了11111111-11111111-11111111-11111111,他的值还是-1,在写入的while循环哪里,判断到-1就会停止循环,
* 就导致了数据丢失,所以在这里&一个255,也就是二进制的00000000-00000000-00000000-11111111,
* 11111111-11111111-11111111-11111111
* 00000000-00000000-00000000-11111111
* ————————————————————————————————————& 值都为1结果才为1。
* 00000000-00000000-00000000-11111111
* 结果不变,
* 这样既保证了返回值不是-1,又没有改变二进制数据。

查看BufferedInputStream源码就可以看到:

1 public synchronized int read() throws IOException {
2         if (pos >= count) {
3             fill();
4             if (pos >= count)
5                 return -1;
6         }
7         return getBufIfOpen()[pos++] & 0xff;
8     }

这里也&255,具体的原因就是上面提到的问题。

参考文章:https://blog.csdn.net/qq_41890624/article/details/81625383

以上是关于IO使用Buffer复制流媒体文件的主要内容,如果未能解决你的问题,请参考以下文章

文件下载复制原理

使用文件流来实现多媒体文件复制

IO流 - 复制文件(字节缓冲流+字节流)

Java NIO之缓冲区

Java NIO之缓冲区

片段中的媒体控制器