A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

本帖最后由 郭孟涛 于 2013-4-3 15:49 编辑
  1. import java.io.*;

  2. class CopyDemo
  3. {
  4.         public static void main(String[] args) throws IOException
  5.         {
  6.                

  7.                 String file = "D:\\黑马程序员_毕向东_Java基础视频教程第01天-10-注释.avi"; // 需要复制的文件avi文件,复制出来的打不开?

  8.                 //String file = "D:\\DBDownload\\汇总\\zong.txt"; //如果复制txt文件大小都一致

  9.                
  10.                 FileReader fr = new FileReader(file);
  11.                
  12.                 FileWriter fw = new FileWriter("d:\\01-10.avi");

  13.                
  14.                 int num = 0;
  15.                
  16.                 while ((num=fr.read()) != -1)
  17.                 {
  18.                         fw.write(num);
  19.                 }

  20.                
  21.                 fw.close();
  22.                 fr.read();
  23.                
  24.                 System.out.println("复制成功");



  25.         }
  26. }
复制代码
我觉得是否因为,只单单复制的文件的中的内容,而没有复制文件属性中的一些信息。而使得视频没法正常播放?


评分

参与人数 1技术分 +1 收起 理由
田磊阳 + 1

查看全部评分

7 个回复

倒序浏览
import java.io.*;

public class CopyMedia {

        /**
         * @param args
         */
        public static void main(String[] args) {
                // TODO Auto-generated method stub

                BufferedInputStream bis = null;
                BufferedOutputStream bos = null;
               
                try {
                        bis = new BufferedInputStream(new FileInputStream("D:\\黑马程序员_毕向东_Java基础视频教程第01天-10-注释.avi"));
                        bos = new BufferedOutputStream(new FileOutputStream("D:\\01-10.avi"));
                       
                        int len = 0;
                        while((len = bis.read()) != -1){
                                bos.write(len);
                        }
                } catch (FileNotFoundException e) {
                        // TODO Auto-generated catch block
                        throw new RuntimeException("未找到源文件");
                } catch (IOException e) {
                        // TODO Auto-generated catch block
                        throw new RuntimeException("拷贝文件失败");
                }finally{
                        if(bos != null){
                                try {
                                        bos.close();
                                } catch (IOException e) {
                                        // TODO Auto-generated catch block
                                        throw new RuntimeException("文件写入流资源关闭失败");
                                }
                        }
                       
                        if(bis != null){
                                try {
                                        bis.close();
                                } catch (IOException e) {
                                        // TODO Auto-generated catch block
                                        throw new RuntimeException("文件读取流资源关闭失败");
                                }
                        }
                }
        }

}

评分

参与人数 1技术分 +1 收起 理由
田磊阳 + 1

查看全部评分

回复 使用道具 举报
除了纯文本文件用字符流以外,其余应该用字节流,你这里是视频文件得用字节流
回复 使用道具 举报
用字节流吧 BufferedInputStream  和BufferedOutputStream   byte[] arr =  new byet[1024] int line ;  while((line = bf.read(arr))!= -1) bo .writ();  这样就行了
字符流是考视频是 先把视频先转为字符,在写出的时候又从新编码,这样肯定是错的,因为码表的问题,
回复 使用道具 举报
你用的是字符的操作流。你要操作非显示类型的文件,(视频,声音,系统文件)都必须使用字节流对其操作才能保证文件的完整性,因为非显示类型的文件,系统都是以字节的形式存储的。
如果你要操作一些显示文件,(.txt等一些字符文件)你要用字符流对其操作,
回复 使用道具 举报
首先,除了文本文件,其他的像音视频文件还有图片文件要用字节流,
下面是自定义的一个具有缓冲功能的字节输出流
结合这个来分析一下字节流读取字节文件的实现机制吧

public class MyBufferedInputStream {

private InputStream is = null;
private int count = 0 , pos = 0;
private byte[] bytes = new byte[1024];

public MyBufferedInputStream(InputStream is) {
this.is = is;
}

public int read() throws IOException{
int bt = 0;
if(count==0){
count = is.read(bytes);
if(count<0)
return -1;
pos = 0;
}
bt = bytes[pos];
pos++;
count--;                 //read完成提升操作 write完成截断的强制转型      
return bt&255;      //与音视频文件二进制编码有关,如果出现连续8个1(即为-1)的字节,则读取该字节自动被提升为int后仍然为 -1   ①
}                           //则在下面①处就会到导致读写停止,进而造成文件损坏,所以要手动提升让其前面补0而不是1!

public void close() throws IOException{
is.close();
}

public static void main(String[] args) {
MyBufferedInputStream mbis = null;
BufferedOutputStream bos = null;
try {
mbis = new MyBufferedInputStream(new FileInputStream(new File("E:\\你的背包.mp3")));
bos = new BufferedOutputStream(new FileOutputStream(new File("E:\\你的背包"+System.currentTimeMillis()+".mp3")));
int elem = 0;
while ((elem = mbis.read()) != -1) { //①
bos.write(elem);
}
} catch (IOException e) {
throw new RuntimeException("文件读取异常");
}finally{

try {
if (mbis != null)
mbis.close();
} catch (IOException e) {
throw new RuntimeException("输入流关闭异常");
}

try {
if (bos != null)
bos.close();
} catch (IOException e) {
throw new RuntimeException("输出流关闭异常");
}
}
}
}


在这里你解释一下①处的文字的意思,
首先音视频文件和图片文件的底层编码是二进制形式的,我们一般用字节流循环读取数据时都是用while循环判断读取的字节数据是不是为-1,
就像你这句  while ((num=fr.read()) != -1)
但是有一种情况很特殊,如果读取的字节正好8个为全为1,即为11111111,这个字节的值就是-1,而且虽然读取的字节在返回时会自动提升为int型也依然是-1,
所以为了在字节提升时改变这种状况,我们可以让返回结果做下面的运算然后再将得到的结果传到while里进行判断,就是通过下面这种形式
    11111111 11111111 11111111 11111111  (这个就是字节型的-1自动提升为int形式的的值,依然为-1)
& 00000000 00000000 00000000 11111111
------------------------------------------------------------------
    00000000 00000000 00000000 11111111

这就是上面①处 bt&255的原理,字节流的的曾应该是使用了这种处理机制而字符流没有,字符编码里好像也没有连续8个1的编码情形,这个还有待考证呵呵.....

评分

参与人数 1技术分 +1 收起 理由
田磊阳 + 1

查看全部评分

回复 使用道具 举报
用字节流吧,BuffereInputStream和BuffereOutputStream
回复 使用道具 举报
如果问题未解决,请继续追问,如果没有问题了,请将帖子分类 改为“已解决”,谢谢
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马