--------------------ASP.Net+Android+IOS開發、.Net培訓、期待與您交流! --------------------
1.字節流
字符流:Writer,Reader 主要是用來操作的是文本文件
字節流:InputStream,OutputStream主要是用來操作的是媒體文件,例如:圖片,音樂,電影…等。但是也可以操作文件。
如果用字符流操作媒體文件的話,複製文件的話:也能複製,只是複製後的圖片不能看,因爲查看的編碼是不一樣的,
不管是讀還是寫,都不需要刷新緩衝,除非用到了緩衝對象。
2. FileOutStream
操作文件,向文本文件中寫入數據,其沒有寫入字符串耳朵方法,有字節數組的寫入,所以我們要把字符串轉換成數組。然後寫入。
importjava.io.FileNotFoundException;
importjava.io.FileOutputStream;
importjava.io.IOException;
importjava.io.OutputStream;
public classOutStreamDemo {
public static void main(String[]args) {
OutputStream out=null;
try {
out=new FileOutputStream("F:\\demo.txt");
out.write("helloworld".getBytes());//寫入數據,把字符串轉換爲字節數組
} catch (IOException e) {
e.printStackTrace();
}finally{
if(out!=null){
try {
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
3. FileInputStream
讀取文件,有三種方法,
第一種:一個一個字符的讀取,
第二種:字節數組的讀取。
第三種:使用available()方法,讀取到文件的總大小,然後定義相同大小的字節數組,讀取一次即可,但是加入文件過大,大於了虛擬的內存的大小,那麼就會加載不進去,所以最好的辦法是定義恰當合適的數組,然後循環讀取。
1. 單個字節讀取
使用的read()方法,進行循環讀取。
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
public class InputStreamDemo {
public static void main(String[] args) {
InputStream in = null;
try {
in = new FileInputStream("F:\\demo.txt");
/* 這個爲一個一個的讀取,使用read()方法,然後讀取到的字符的ASCII碼,到結尾就返回-1*/
int r = -1;
while ((r = in.read()) != -1) {//開始讀取
System.out.print((char) r);
}
} catch (IOException e) {
e.printStackTrace();
}finally{
if(in!=null){
try {
in.close();//關閉流
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
2. 字節數組讀取
定義恰當的數組,然後循環讀取 使用的read(byte [] b)
然後轉換成字符串,返回。
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
public class InputStreamDemo {
public static void main(String[] args) {
InputStream in= null;
try {
in= new FileInputStream("F:\\demo.txt");
/* 使用字節數組讀取,然後轉成字符串。到結尾就返回-1*/
byte [] b=new byte[1024];
int len=-1;
while ((len = in.read(b)) != -1) {//開始讀取
System.out.print(new String(b,0,len));
}
} catch (IOException e) {
e.printStackTrace();
}finally{
if(in!=null){
try {
in.close();//關閉流
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
3. 固定數組大小
使用的available()方法,讀取到文件的大小,然後定義相應的大小的字節數組,如果文件小的話,可以這樣使用,但是文件很大,超過了虛擬機的申請的內存,那麼就會導致加載不進入,所以最好的方法是是喲第二種方法,定義合適的字節數組的大小。
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
public class InputStreamDemo {
public static void main(String[] args) {
InputStream in = null;
try {
in = new FileInputStream("F:\\demo.txt");
/* 使用字節數組讀取,數組的大小用:available()方法定,然後轉成字符串。到結尾就返回-1 */
byte[] b = new byte[in.available()];
int len = in.read(b);
System.out.print(new String(b, 0,len));
} catch (IOException e) {
e.printStackTrace();
} finally {
if (in != null) {
try {
in.close();// 關閉流
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
4. 複製圖片
使用的InputStream和OutputStream
步驟:
1.使用讀取流InputStream,與要讀取的圖片關聯。
2.定義寫入流,定義好複製到的位置和圖片的名稱。
3.然後一邊讀取一邊寫入,循環讀取和循環寫入。使用的是數組讀取和寫入。
4.最後關閉流。
擴展:複製後的文件名稱可以改變也可以不變,格式也可以改變,jpg或者bmp.或者其他的格式都可以
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
public class OutAndInputStreamDemo {
public static void main(String[] args) {
InputStream in = null;// 讀取流字節流
OutputStream out = null;// 寫入流字節流
try {
in = new FileInputStream("F:\\A\\1.jpg");// 與複製的圖片關聯起來
out = new FileOutputStream("F:\\B\\1.bmp");// 與複製到的目的關聯起來,這裏的圖片的名稱可以與原來的相同,也可以不一樣
byte[] b = new byte[1024];// 定義字節數組,並指定長度
int l = -1;
while ((l = in.read(b)) != -1) {// 讀取
out.write(b, 0, l);// 寫入,讀多少寫入多少,所以用 write(b,0,len)
}
System.out.println("複製成功");
} catch (IOException e) {
e.printStackTrace();
} finally {
if (in != null) {
try {
in.close();// 關閉讀取流
} catch (IOException e) {
System.out.println("讀取流關閉失敗");
}
if (out != null) {
try {
out.close();// 關閉寫入流
} catch (IOException e) {
System.out.println("寫入流關閉失敗");
}
}
}
}
}
}
結果:
複製成功
5. 字節流的緩衝
字符流:Writer,Reader
BufferedWriter和BufferedReader
字節流:InputStream,OutputStream體文
BufferedInputStream和BufferedOutputStream
字節流的緩衝和字符流的花衝使用方法是類似的,用的對象是BufferedInputStream和BufferedOutputStream,他們增強了字節流的讀取和寫入效率。
1. 利用緩衝對象複製MP3文件
package www.fuxi.IO;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
public class BufferedStreamDemo {
public static void main(String[] args) {
BufferedInputStream bis = null;// 讀取緩衝流
BufferedOutputStream bos = null;// 寫入緩衝流
try {
bis = new BufferedInputStream(new FileInputStream("F:\\A\\1.mp3"));// 要複製的MP3文件
bos = new BufferedOutputStream(new FileOutputStream("F:\\B\\1.mp3"));// 複製到的目的地
byte[] b = new byte[1024];
int len = 0;
while ((len = bis.read(b)) != -1) {// 讀取
bos.write(b, 0, len);// 寫入
}
System.out.println("複製成功");
} catch (Exception e) {
e.printStackTrace();
} finally {
if (bis != null) {
try {
bis.close();// 關閉讀取緩衝對象流
} catch (IOException e) {
e.printStackTrace();
}
if (bos != null) {
try {
bos.close();// 關閉寫入緩衝對象流
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
}
結果:
複製成功
2. 模擬讀取緩衝區
import java.io.IOException;
import java.io.InputStream;
public class MyBufferedInputStream {
privateInputStream in = null;
private intcount = 0;// 計數器
private intpos = 0;// 指針
private byte[]bu = new byte[1024];// 封裝的字節數組
publicMyBufferedInputStream(InputStream in) {
this.in =in;
}
public intMyRead() throws IOException {
if (count== 0) {// 說明此時緩衝區中沒有數據,可能是緩衝區中還沒有開始讀取,或者是緩衝區中數據讀取完畢
count= in.read(bu);// 向緩衝區中讀取數據
if(count < 0) {
return-1;// 這裏返回的是int類型的-1
}
pos=0;//每次把指針都初始化
byteb = bu[pos];
count--;//計數器減一
pos++;//指針加一
returnb & 0xff;// 這裏b是byte類型,自動提升爲整形,但是前面補充的是全是1,爲了防止當讀取道德byte數據爲11111111時,&上0xff,那麼使前面的是0,那麼這樣額可以是原數據不變,又能避免字節數據是-1的情況
} elseif(count>0){
byteb = bu[pos];
count--;//計數器減一
pos++;//指針加一
returnb & 0xff;// 這裏b是byte類型,自動提升爲整形,但是前面補充的是全是1,爲了防止當讀取道德byte數據爲11111111時,&上0xff,那麼使前面的是0,那麼這樣額可以是原數據不變,又能避免字節數據是-1的情況
}
return-1;
}
public voidmyClose() throws IOException {
in.close();
}
}
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
/*
*測試類,也是複製MP3*/
public class BufferedStreamDemo {
public static void main(String[] args) {
MyBufferedInputStream bis = null;// 讀取緩衝流
BufferedOutputStream bos = null;// 寫入緩衝流
try {
bis = new MyBufferedInputStream(new FileInputStream("F:\\A\\1.mp3"));// 要複製的MP3文件
bos = new BufferedOutputStream(new FileOutputStream("F:\\B\\1.mp3"));// 複製到的目的地
// byte[] b = new byte[1024];
int r = 0;
while ((r = bis.MyRead()) != -1) {// 讀取
bos.write(r);// 寫入
}
System.out.println("複製成功");
} catch (Exception e) {
e.printStackTrace();
} finally {
if (bis != null) {
try {
bis.myClose();// 關閉讀取緩衝對象流
} catch (IOException e) {
e.printStackTrace();
}
if (bos != null) {
try {
bos.close();// 關閉寫入緩衝對象流
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
}
結果:複製成功
注意點:在MyRead()方法中return 返回的必須寫b&0xff,因爲這樣byte類型的提升爲整形後,可以保證原數據保持不變,把原來的數據前面相當於添加的0.
例如:
byte : 11111111 這是-1
自動提升爲整形後的數據是
1111111111111111 11111111 11111111 此時這是-1
那麼當byte類型的數據是八個1的時候,那麼直接返回b,那麼提升爲整形後是四個八個1,那麼還是-1,所以程序直接結束,讀取完畢,解決方法是,要是在前面補充的是全是0的話,那麼原數據不變沒這樣也避免的讀取-1的情況。
1111111111111111 11111111 11111111
& 00000000 00000000 00000000 11111111 這是255,
-----------------------------------------------------------------
0000000000000000 00000000 11111111
所以這樣結果就是我們想要的數據,既避免了讀取byte是11111111的缺點,同時還保證了原數據不變。
Read方法是byte類型的提升,從1個字節提升爲整形爲四個字節。Write方法是把4個字節變成了1個字節,值去最後的一個字節。所以複製後的文件的大小和原來的大小一下,而不是其4倍的大小。
6. 鍵盤讀取
import java.io.IOException;
import java.io.InputStream;
public class ClassDemo {
public static void main(String[] args) throws IOException {
/*
* InputStream in“標準”輸入流:讀取的設備是鍵盤 PrintStream out“標準”輸出流。輸出到控制檯
*/
/*
* 我們可以循環輸入,當輸入爲over時候,結束輸入
*/
InputStream in = System.in;
StringBuilder bu= new StringBuilder();
while (true) {
int ch = in.read();
if (ch == '\r')
continue;
if (ch == '\n') {
String s = bu.toString();
if ("over".equals(s))// 如果輸入的是over,那麼結束輸入
break;
System.out.println("輸入的內容是:" + s);
bu.delete(0,bu.length());
} else
bu.append((char) ch);
}
}
}
結果:
aa
輸入的內容是:aa
bb
輸入的內容是:bb
cc
輸入的內容是:cc
over
--------------------ASP.Net+Android+IOS開發、.Net培訓、期待與您交流!
--------------------