復制的本質,如字節流字節數組復制,根據方法.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();