java笔记七:IO流之字节流与字节缓冲流
在I/O类库中,java.io.InputStream和java.io.OutputStream分别表示字节输入流和字节输出流,它们都是抽象类,不能实例化,数据流中的最小单位是字节,所以叫做字节流。
一、InputStream中的读取数据的方法如下:
1 、int read()
功能:读取一个字节的数据,并且返回读到得数据,如果返回-1,则表示读到输入流的末尾。
2、int read(byte[] b)
功能:从输入流中读取一定量的字节,并将其存储在字节数组b中,返回实际读取的字节数,如果返回-1,则表示读到输入流的末尾。
3、int read(byte[] b, int off, int len)
功能:将数据读入一个字节数组,同时返回读取的实际字节数,如果返回-1,则表示读到输入流的末尾。off指定在数组b中存放数据的起始偏移位置,len指定读取的最大字节数。
4、available()
功能:返回此输入流下一个方法调用可以不受阻塞地从此输入流读取或跳过的估计字节数。
5、close()
功能:关闭输入流,释放这个流的相关资源。
二、OutputStream中写入数据的方法如下:
1 、int write(int b)
功能:将b的最低的一个字节写入此输入流,其他三个字节丢弃。
2、int write(byte[] b)
功能:将指定的字节数组b写入此输入流。
3、int write(byte[] b, int off, int len)
功能:将指定byte数组中从偏移量off开始的len个字节写入输入流。
4、flush()
功能:刷新此输入流并强制写出所有缓冲的输出字节数。
5、close()
功能:关闭输出流,释放这个流的相关资源。
①字节数组输入流:
1 package com.iotest; 2 3 import java.io.ByteArrayInputStream; 4 import java.io.IOException; 5 public class ByteArryInputStreamDemo { 6 public static void main(String[] args) throws IOException { 7 String str = "abcdefghijk"; 8 byte[] strBuf = str.getBytes(); //字符串转换成字节数组 9 ByteArrayInputStream bais = new ByteArrayInputStream(strBuf); 10 int data = bais.read(); //从字节数组输入流读取字节 11 while(data!=-1){ 12 char upper = Character.toUpperCase((char)data); 13 System.out.print(upper+" "); 14 data = bais.read(); 15 } 16 bais.close(); 17 } 18 }
程序运行结果:A B C D E F G H I J K
②字节数组输出流:
1 package com.iotest; 2 3 import java.io.ByteArrayOutputStream; 4 import java.io.IOException; 5 6 public class ByteArrayOutputStreamDemo { 7 public static void main(String[] args) throws IOException { 8 ByteArrayOutputStream baos = new ByteArrayOutputStream(); 9 String s = "welcome to use ByteArrayOutputStreamDemo"; 10 byte[] buf = s.getBytes(); 11 baos.write(buf); //将指定的byte数组写到字节数组输出流中 12 System.out.println(baos.toString()); //将字节数组输出流内容转换成字符串输出 13 //将字节数组输出流中的内容复制到字节数组中 14 byte[] b = baos.toByteArray(); 15 for (int i = 0; i < b.length; i++) { 16 System.out.print((char)b[i]); 17 } 18 baos.close(); 19 } 20 }
程序运行结果:
welcome to use ByteArrayOutputStreamDemo
welcome to use ByteArrayOutputStreamDemo
③文件输入输出流的使用
1 package com.iotest; 2 3 import java.io.File; 4 import java.io.FileInputStream; 5 import java.io.FileNotFoundException; 6 import java.io.FileOutputStream; 7 import java.io.IOException; 8 //复制图片 9 public class FileInputStreamDemo { 10 public static void main(String[] args) throws IOException { 11 File file = new File("F:\\shar\\test\\logo17.gif"); 12 FileInputStream fis = new FileInputStream(file); //创建一个输入流 13 //创建一个输出流,后面一个参数true表示追加,原有内容不会被清除,默认为false 14 FileOutputStream fos = new FileOutputStream("F:\\shar\\test\\logo18.gif",false); 15 int ch = 0; 16 //方式一 17 /*while((ch=fis.read()) != -1){ 18 fos.write(ch); 19 }*/ 20 //方式二 21 /*byte[] b = new byte[1024]; 22 while((ch=fis.read(b)) != -1){ 23 fos.write(b,0,ch); 24 }*/ 25 //方式三 26 byte[] b = new byte[fis.available()]; 27 fis.read(b); //首先把fis的内容读到字节数组b里面 28 fos.write(b);//再把字节数组b的内容通过输出流写到指定文件 29 //关闭流 30 fos.close(); 31 fis.close(); 32 } 33 34 }
④管道流的使用:
一个PipedInputStream对象必须和一个PipedOutputStream对象进行连接从而产生一个通信管道。通常一个线程从管道输出流写入数据,另一个线程从管道输入流中读取数据。当线程A执行管道输入流的read()方法时,如果暂时没有数据,这个线程就会被阻塞,只有当线程B想管道输出流写了数据后,线程A才会恢复运行。
package com.iotest; import java.io.IOException; import java.io.PipedInputStream; import java.io.PipedOutputStream; /* * 管道流 */ class Sender extends Thread{ private PipedOutputStream out = new PipedOutputStream(); public PipedOutputStream getOut() { return out; } @Override public void run() { String s = "hello world"; try { out.write(s.getBytes()); out.close(); } catch (Exception e) { // TODO: handle exception } } } public class Receiver extends Thread{ private PipedInputStream in; public Receiver(Sender sender) throws IOException { in = new PipedInputStream(sender.getOut()); } @Override public void run() { try { int data; while((data=in.read())!=-1){ System.out.print((char)data); } in.close(); } catch (Exception e) { // TODO: handle exception } } public static void main(String[] args) throws IOException { Sender sender = new Sender(); Receiver r = new Receiver(sender); sender.start(); r.start(); } }
⑤缓冲流的使用:
1 package com.iotest; 2 3 import java.io.BufferedInputStream; 4 import java.io.BufferedOutputStream; 5 import java.io.FileInputStream; 6 import java.io.FileNotFoundException; 7 import java.io.FileOutputStream; 8 import java.io.IOException; 9 10 public class TestPrime { 11 private BufferedInputStream bis = null; 12 private BufferedOutputStream bos = null; 13 String fileName = "F:\\shar\\test\\test2.txt"; 14 static int s,p; 15 //判断是否是质数 16 public boolean isPrime(int n){ 17 for(int i=2;i<=n/2;i++){ 18 if(n%i == 0){ 19 return false; 20 } 21 } 22 return true; 23 } 24 void printPrime(int m) throws IOException{ 25 //将字节流转缓冲流 26 bos = new BufferedOutputStream(new FileOutputStream(fileName)); 27 int j = 0; 28 for (int i = 2; i < m; i++) { 29 if(isPrime(i)){ 30 j++; 31 if(j%s == 0){ 32 String s = String.valueOf(i)+" "; 33 bos.write(s.getBytes()); 34 bos.write("\r\n".getBytes()); 35 }else{ 36 String s = String.valueOf(i)+" "; 37 bos.write(s.getBytes()); 38 } 39 } 40 } 41 bos.flush(); 42 bos.close(); 43 } 44 void getPrime() throws IOException{ 45 //将字节流转缓冲流 46 bis = new BufferedInputStream(new FileInputStream(fileName)); 47 int c = bis.read(); 48 while(c != -1){ 49 char ch = (char)c; 50 System.out.print(ch); 51 c = bis.read(); 52 } 53 } 54 /** 55 * @param args 56 * @throws IOException 57 */ 58 public static void main(String[] args) throws IOException { 59 TestPrime t = new TestPrime(); 60 p = 100; 61 s = 10; 62 t.printPrime(p); 63 t.getPrime(); 64 } 65 66 }
如果不用缓冲流的话,程序是读一个数据,写一个数据。这样在数据量大的程序中非常影响效率。 缓冲流作用是把数据先写入缓冲区,等缓冲区满了,再把数据写到文件里。这样效率就大大提高了。