谈谈io流&&文件复制的几种方法

194 阅读3分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第3天,点击查看活动详情
提到io必然要讲文件

文件

啥是文件?硬盘上的文件 txt docx 电影 图片等都是。
代码怎么创建文件?

//file:文件\目录\不存在的文件或目录
 File file = new File("d:/abc.txt");
 file.creatNewFile();

“引号里面可以是任意的,不过要完成我们的实验还是需要填写正确的地址哦”
方法:
getPath()获取相对路径(相对当前根目录)
getAbsolutePath()获取绝对路径
getName() 获取文件名称
length()获取文件大小
isFile()是不是文件
isDirectory()是不是目录
exists()是不是存在
相对路径/绝对路径:

- 如果FIle("绝对路径"):getPath() 和getAbsolutePath()的结果一致,打印的都是绝对路径
- 如果FIle("相对路径"):getPath() 打印相对路径;getAbsolutePath()打印绝对路径
    

字节流:将内容转为了字节形式进行传输, 1 字节 ->8二进制 ,二进制可以传输任何类型的数据,因此字节流也可以传输任何类型的数据。
字符流:字符流是16位的unicode字符流 (只用于处理字符,处理文本文件)

文件复制1之字节流

字节流有哪些? InputStream,OutputStream 怎么创建流》

             InputStream in = null ;
             OutputStream out = null ;
             in = new FileInputStream("d:/abc.txt") ;

             out = new FileOutputStream("d:/xyz.txt") ;

在new时候需要捕捉异常,可以用trycatch,也可以throw

InputStream in = null ;
       OutputStream out = null ;
       try {
           //abc.txt->内存
            in = new FileInputStream("需要复制的文件地址") ;

            out = new FileOutputStream("目的地址") ;
         
       }

       } catch (FileNotFoundException e) {
           e.printStackTrace();
       } 

流创建好了,怎么复制?

1.png 根据图片,我们知道
需要先写入,但是如果文件非常大,我们不可能在内存了吗开辟很大空间,然后就用到了缓存数组。因为是字节流,所以创建字节缓存数组
byte []buf = new byte[10] ;
这里我们假设是10
然后通过 out.write(buf) 输出到我们目的文件,
这里会出现一个问题,最后一个buf假设没有10字节,会出现什么情况?
答案是:因为部分覆盖,让目的文件多了一些数据

15.png 修改方法:在输出时候,我们读了多少进来,就输出多少。
int len=in.read(buf);
out.write(buf,0,len)。
最后,记得关闭流

import java.io.*;

public class FileCopy {
    //abc.txt->内存->xyz.txt
    public static void main(String[] args) {
        InputStream in = null ;
        OutputStream out = null ;
        try {
            //abc.txt->内存
             in = new FileInputStream("d:/abc.txt") ;

             out = new FileOutputStream("d:/xyz.txt") ;
            //开辟10字节的内存
            byte []buf = new byte[10] ;
            int len = -1 ;
            ;
        while(   (len= in.read(buf)) != -1){//in ->buf
            out.write(buf,0,len);//buf->out
        }

        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            try {
                if(out !=null)out.close();
                if(in !=null) in.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

文件复制3之使用字符流进行文件的复制

字符流是啥?
Reader Writer
怎么创建?
reader = new FileReader("");
writer = new FileWriter("“) ;
,这里和上面字节差不多,不过我们new字符数组
用StringBuffer 接收输入

import java.io.*;

public class FileCopyCharactor {
   public static void main(String[] args) {
       //文件->内存(Reader)
       Reader reader = null ;
       Writer writer = null ;
       try {
            reader = new FileReader("d:/abc.txt");
            writer = new FileWriter("d:/xyz.txt") ;

           char[] buf = new char[4];
           StringBuffer sb = new StringBuffer() ;

           int len = -1 ;
           while((len =reader.read(  buf)) != -1 ){
               // str += buf ;
               sb.append(buf,0,len) ;//将每次读取到的 4个字符 拼接起来
           }

           System.out.println(sb);

           String content = sb.toString() ;
           writer.write(content);
           System.out.println("成功...");

//            writer.flush(); 将管道中的数据 刷出到 文件中

       } catch (FileNotFoundException e) {
           e.printStackTrace();
       } catch (IOException e) {
           e.printStackTrace();
       }finally {
           try {
              if(writer!=null) writer.close();
               if(reader!=null) reader.close();
           } catch (IOException e) {
               e.printStackTrace();
           }

       }
   }
}

因为每次new数组太麻烦了,然后出现了自带缓冲区的字符流(BufferedReader /BufferedWriter)
带缓冲区的字符流创建 对象 = new 带缓冲区的字符流(字符流)
上面代码修改成:

import java.io.*;

public class FileCopyCharactorBuffered {
   public static void main(String[] args) {
       //文件->内存(Reader)
       Reader reader = null ;
       Writer writer = null ;

       BufferedReader br = null ;
               BufferedWriter bw = null ;

       try {
            reader = new FileReader("d:/abc.txt");
            writer = new FileWriter("d:/xyz.txt") ;
            
            br = new BufferedReader( reader) ;
            bw = new BufferedWriter( writer);
            
           StringBuffer sb = new StringBuffer() ;
           String line = null ;

           while( (line= br.readLine()) != null   ){
               sb.append(line) ;
           }

           System.out.println(sb);

           String content = sb.toString() ;
           bw.write(content);
           System.out.println("成功...");

//            writer.flush(); 将管道中的数据 刷出到 文件中

       } catch (FileNotFoundException e) {
           e.printStackTrace();
       } catch (IOException e) {
           e.printStackTrace();
       }finally {

           /*
           *    1先关出,再关入
           *    2从外往内关  br外 = new BufferedReader( reader内) ;
           * */
           try {
              if(bw != null) bw.close();
             if(br!=null )  br.close();
              if(writer!=null) writer.close();
               if(reader!=null) reader.close();
           } catch (IOException e) {
               e.printStackTrace();
           }
       }


   }
}

这里出现了不一样的
reader = new FileReader("d:/abc.txt");
writer = new FileWriter("d:/xyz.txt") ;
br = new BufferedReader( reader) ;
bw = new BufferedWriter( writer);
也可以用装饰模式写
br = new BufferedReader( new FileReader("d:/abc.txt")) ;
bw = new BufferedWriter( new FileWriter("d:/xyz.txt") );

1576461139194.png