复制的本质,如字节流字节数组复制,根据方法.read()的一次一次2个字节的读取,第一次读出的是ab 长度 2,第二次读出cd长度2,第三次读出e 长度1,但是还没结束,第四次读出0,长度-1,结束循环。
常用的方法:
字节输出流OutputStream
后面的输出流是它的方法,基本都是可以用这些方法。
第一个子类:FileOutputStream 字节输出流
构造方法:
字节输入流:InputStream
int r=rs.read()=-1结束循环。
第一个子类:FileInputStream
他也继承read()和read(byte[] b)
案例如下:
1、字节流复制
//字节数组复制
public static void main(String[] args) throws IOException { //明确目的地的 FileOutputStream fos= new FileOutputStream("D:\\demo0611\\b\\1.jpg",true);如果不想覆盖,需要续写true //明确数据源 FileInputStream fis= new FileInputStream("D:\\demo0611\\a\\1.jpg"); //开始复制 //定义字节数组 byte [] b=new byte[1024]; //定义接收长度的初始值 int len=0; //遍历 while((len=fis.read(b))!=-1){ //将遍历的全部传入目的地 fos.write( b,0,len); //如果单纯的使用字节输入流,将文件读取到程序里面 //,必须要转字符串,因为程序执行的是ASCII码,要不然不执行。读取的主要是字节流的文件 * } //释放资源 fos.close(); fis.close();
这里面需要注意一个事情,就是上面所说的续写。“\r\n”是换行,不常用。
如果出现异常直接像红字一样throws在正常的操作中是不符合规范的,那就涉及到异常处理问题,用try catch
public static void main(String[] args) { // 明确目的地 字节输出流 FileOutputStream pst = null;// 定义全局变量 try { pst = new FileOutputStream("D:\\demo0611\\o.txt", true); // 定义字符串 String str = "\r\n" + "你好"; // 写入字节数组 字符→字节数组 pst.write(str.getBytes()); } catch (IOException e) { e.printStackTrace(); } finally { if (pst != null) { // 释放资源 try { pst.close(); } catch (IOException e) { e.printStackTrace(); } } }
这里处理异常的重点在于,将会出现问题的目的地,要传输的东西放入try获取错误代码,将释放资源放在finally里面,并且要判断是否为空。
ps:因为字节流没法正确的赋值字符流,所以我们需要一个单独的赋值字符的流。
字符输入流有一个自己的类叫Reader
FileReader是它的一个子类,继承上面的方法。
构造方法:
字符输出流Writer
写入方法:
构造方法:
flush():将流中的缓冲区缓冲的数据刷新到目的地中,刷新后,流还可以继续使用。
close():关闭资源,但在关闭前会将缓冲区中的数据先刷新到目的地,否则丢失数据,然后在关闭流。流不可以使用。如果写入数据多,一定要一边写一边刷新,最后一次可以不刷新,由close完成刷新并关闭。
2、字符流复制
//字节数组复制 //明确目的地的 FileOutputStream fos= new FileOutputStream("D:\\demo0611\\b\\1.jpg"); //明确数据源 FileInputStream fis= new FileInputStream("D:\\demo0611\\a\\1.jpg"); //开始复制 //定义字节数组 byte [] b=new byte[1024]; //定义接收长度的初始值 int len=0; //遍历 while((len=fis.read(b))!=-1){ //将遍历的全部传入目的地 fos.write( b,0,len); //如果单纯的使用字节输入流,将文件读取到程序里面
fos.flush(); //,必须要转字符串,因为程序执行的是ASCII码,要不然不执行。读取的主要是字节流的文件 * } //释放资源 fos.close(); fis.close();
字节缓冲输出流BufferedOutputStream
字节缓冲输入流 BufferedInputStream
缓冲流的作用就是给复制文件加一个加速buff,将文件从正常的输入流改为缓冲输入流。
3、缓冲数组字节流复制
//缓冲流的一个字节数组复制 710 速度最快 public static void copy4() throws IOException{ //明确数据源 FileInputStream fis=new FileInputStream("D:\\demo0611\\jdk1.8.zip"); //明确目的地 FileOutputStream fos=new FileOutputStream("D:\\demo0611\\b\\jbk1.8.zip"); //buff缓冲 套上一个功能,让功能去执行操作,加速一下 BufferedOutputStream bos=new BufferedOutputStream(fos); BufferedInputStream bis=new BufferedInputStream(fis); long a1=System.currentTimeMillis(); //创建byte数组 byte [] bytes=new byte[1024]; int len=0; //开始复制 读取的1024长度的字节,每次读取的内容长度不等于-1 while((len=bis.read(bytes))!=-1){ bos.write(bytes,0,len); } long a2=System.currentTimeMillis(); System.out.println(a2-a1); //释放资源 bis.close(); bos.close(); }
其实复制无非就是获取数据源,明确目的地,单个字符或字节开始一个个复制,或者字符char []字节数组byte[]的复制,数组需要在每一次读取中传入[char][byte]中。字节缓冲是一样的,但是缓冲数组字符流复制不同在于有一个特殊的读取方式。也就是当字符流增加缓冲buff后会一行一行的读取,定义的是string line=null;一行一行的读取,等于null时结束循环,每读完一行换行,并且刷新。
//缓冲流单个字符复制 5175 public static void copy2() throws IOException{ //明确数据源 FileReader fr=new FileReader("D:\\demo0611\\dmbj.txt"); //明确目的地 FileWriter fw=new FileWriter("D:\\demo0611\\a\\dmbj.txt"); //添加缓冲流 BufferedReader br=new BufferedReader(fr); //添加数据源缓冲流 BufferedWriter bw=new BufferedWriter(fw); long a1=System.currentTimeMillis(); //开始复制 String line=null; while((line=br.readLine())!=null){ bw.write(line); bw.newLine(); bw.flush(); } long a2=System.currentTimeMillis(); System.out.println(a2-a1); bw.close(); br.close(); }
4、缓冲数组字符流复制
//缓冲流字符数组复制 888 public static void copy4() throws IOException{ //明确数据源 FileReader fr=new FileReader("D:\\demo0611\\dmbj.txt"); //明确目的地 FileWriter fw=new FileWriter("D:\\demo0611\\d\\dmbj.txt"); //增加缓冲流 BufferedReader br=new BufferedReader(fr); BufferedWriter bw=new BufferedWriter(fw); //创建char数组 char[] ch=new char[1024]; long a1=System.currentTimeMillis(); int line=0; while((line=br.read(ch))!=-1){ bw.write(ch,0,line); //bw.newLine(); bw.flush(); } long a2=System.currentTimeMillis(); System.out.println(a2-a1); //释放资源 br.close(); bw.close(); }
字节流和字符流只能读取输出文本,必须和软件的编码表一样,如gbk
文字--->(数字) :编码。 “abc”.getBytes() byte[] 将文本转成字节数组
(数字)--->文字 : 解码。 byte[] b={97,98,99} new String(b,0,len) 将数组转为字符串(如果单纯输入流读取需要这样转换)
OutputStreamWriter转换输出流
InputStreamReader 转换输入流
5、转换流字节流复制
//字节数组转换流 //明确目的地 FileOutputStream fos=new FileOutputStream("D:\\demo0611\\b\\abc.txt",true); //添加转换流 OutputStreamWriter or=new OutputStreamWriter(fos,"gbk"); //开始写 or.write("nihaoya"); //释放资源 or.close();
FileInputStream fis=new FileInputStream("D:\\demo0611\\b\\abc.txt"); //添加转换输入流 InputStreamReader isr=new InputStreamReader(fis,"gbk"); //开始读取 char [] chars=new char[1024]; int len=0; while((len=isr.read(chars))!=-1){ System.out.println(new String (chars,0,len));//因为不是复制所以直接接受就行 } //释放资源 isr.close();