目录
3.5 FileReader与FileWriter实现文件的复制
3.8 BufferedWriter与BufferedReader实现文件的复制
4.5 FileInputStream与FileOutputStream实现文件复制
4.8 BufferedInputStream与BufferedOutputStream实现文件复制
1.IO流的概念与作用
1.1 IO流是什么
I(Input)输入,O(Out)输出
1.2 IO流的作用
数据在各个设备之间的传输,是通过流的方式完成的
1.3 IO流分类
-
根据流动方向的不同,流分为输入流和输出流(相对于内存,输入和输出)
-
根据流的格式不同,流分为字节流和字符流
-
程序中的输入和输出都是以流的形式保存的,流中保存的实际上全是字节文件。
-
所有文件的存储都是字节(byte)来存储,在磁盘上保留的并不是文件的字符,而是先把字符编码成字节,再存储这些字节到硬盘上,在读取时也是一个一个的读取以形成序列
-
-
根据流的功能不同,又分为节点流和处理流
-
节点流:可以从某节点读数据或向某节点写数据的流
-
处理流:对已存在的流的连接和封装,实现更为丰富的流数据处理,提高流读写效率
-
2.IO流的体系结构
2.1 字节流的抽象父类
-
InputStream字节输入流, OutputStream字节输出流
-
派生出来的子类名称都是以其父类名作为子类名的后缀。如:InputStream的子类FileInputStream
2.2 字符流的抽象父类
-
Reader 字符输入流, Writer字符输出流
-
派生出来的子类名称都是以其父类名作为子类名的后缀。如:Reader的子类FileReader
2.3 Java中IO流的体系结构
2.3.1 Java中IO流的体系结构
2.3.2 InputStream基础体系
2.3.3 OutputStrean基础体系
2.3.4 Reader基础体系
2.3.5 Writer基础体系
3.字符的输入输出流
3.1 Writer抽象类
-
Writer抽象类里的方法
-
由于Writer是抽象类不能创建对象,所以用它子类来完成写入字节的操作
3.2 FileWriter类
-
FileWriter类是Writer的子类,是文件写入流,以字符流的形式对文件进行写操作,其构造方法有5种重载,以下是常用的4种:
-
案例
package com.bx.rw; import java.io.FileWriter; import java.io.IOException; public class FileWriterTest { //定义常量 保存换行符 private static final String LINE_SEPARATOR = System.getProperty("line.separator"); public static void main(String[] args) { FileWriter fw = null; try { fw = new FileWriter("writerData.txt", true); //true会追加,false不会追加 //调用流对象的写入方法,将数据写入流,其实写到临时存储缓冲区中 fw.write(97);//在文件中显示的是a,ASCII码 fw.write(LINE_SEPARATOR); fw.write("1234567890" + LINE_SEPARATOR);//添加换行符号 //fw.flush();//先写入a1234567890 fw.write("ABCDEFG", 1, 3); fw.write(LINE_SEPARATOR);//写入换行符号 fw.write(new char[]{'a', 'x', 'b'}); //刷新缓冲区,数据立刻写入文件 // 刷新该流的缓冲,直接到目的地 //不写flush方法会有什么结果呢?关闭流资源,在关闭流资源前先调用flush方法,并将流中的数据清空到文件中。 fw.flush(); } catch (IOException e) { e.printStackTrace(); } finally { if (fw != null) { try { fw.close();//主动关闭writer } catch (IOException e) { e.printStackTrace(); } } } } }
-
换行符
-
不同操作系统换行符:
-
windows下的文本文件换行符:\r\n
-
linux/unix下的文本文件换行符:\n
-
Mac下的文本文件换行符:\r
-
-
要用System.getProperty(“line.separator”)代替 固定格式的换行符
-
具备平台无关性
-
一次编写,到处运行
-
更保险
-
-
3.3 Reader抽象类
-
Reader抽象类里的方法
-
由于Writer是抽象类不能创建对象,所以用它子类来完成写入字节的操作
3.4 FileReader类
-
FileReader类是Reader的子类,称为文件读取流,允许以字符流的形式对文件进行读操作,其构造方法有3种重载方式,以下是常用的2种:
-
案例:
package com.bx.rw; import java.io.FileNotFoundException; import java.io.FileReader; import java.io.IOException; public class FileReaderTest { public static void main(String[] args) { // readData1(); readData2(); } private static void readData2() { FileReader fr; try { fr = new FileReader("writerData.txt"); int ch; //循环去读取数据,每次读一个字符,fr.read()返回值是字符的编码值 while ((ch = fr.read()) != -1) { System.out.print((char) ch); } } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } private static void readData1() { FileReader fr = null; try { //创建FileReader对象 fr = new FileReader("writerData.txt"); //把流中的数据循环读到数组缓存中 char[] buffer = new char[1024];//超过1024可循环读 //一个换行两字符\r\n int num;//每次读取到的数量 //读到数据数量为-1表示数据已经读完 while ((num = fr.read(buffer)) != -1) { String s = new String(buffer, 0, num); // 错误写法 // String s = new String(buffer); // String s = new String(buffer, 0, 8); // String s = new String(buffer,0,buffer.length); System.out.println(s); } System.out.println("读取完毕"); //数组缓存中把数组转变成字符串,打印到控制台 } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } finally { if (fr != null) { try { fr.close(); } catch (IOException e) { e.printStackTrace(); } } } } }
3.5 FileReader与FileWriter实现文件的复制
-
案例
package com.bx.rw; import java.io.FileNotFoundException; import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; public class FileReaderAndFileWriterCopyTest { public static void main(String[] args) { copyFile(); } public static void copyFile() { //FileReader.reader读取原始文件数据(字符) //FileWriter.write把读取到数据写到新文件中 //边读边写就完成了文件复制功能 FileReader fr = null; FileWriter fw = null; try { fr = new FileReader("writerData.txt"); fw = new FileWriter("writerData.txt", true); int num; char[] buffer = new char[8]; //边读边写 while ((num = fr.read(buffer)) != -1) { //写入数据到流中 fw.write(buffer, 0, num); } fw.flush(); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } finally { if (fr != null) { try { fr.close(); } catch (IOException e) { e.printStackTrace(); } } if (fw != null) { try { fw.close(); } catch (IOException e) { e.printStackTrace(); } } } } }
3.6 BufferedWriter类
-
BufferedWriter类里有一个方法要注意
-
案例
package com.bx.rw; import java.io.BufferedWriter; import java.io.FileWriter; import java.io.IOException; public class BufferedWriterTest { public static void main(String[] args) { //创建BufferedWriter对象 FileWriter fw = null; BufferedWriter bw = null; try { fw = new FileWriter("c:/tmp/data.txt"); bw = new BufferedWriter(fw); for (int i = 0; i < 4; i++) { bw.write("abc" + i); bw.newLine(); } bw.flush(); } catch (IOException e) { e.printStackTrace(); } finally { //后打开先关闭,bw依赖于fw if (bw != null) { try { bw.close(); } catch (IOException e) { e.printStackTrace(); } } if (fw != null) { try { fw.close(); } catch (IOException e) { e.printStackTrace(); } } } } }
3.7 BufferedReader类
-
BufferedReader类里有一个方法要注意
-
案例
package com.bx.rw; import java.io.BufferedReader; import java.io.FileNotFoundException; import java.io.FileReader; import java.io.IOException; public class BufferedReaderTest { public static void main(String[] args) { FileReader fr = null; BufferedReader br = null; try { fr = new FileReader("c:/tmp/data.txt"); br = new BufferedReader(fr); String str; //readLine()读取一行,返回首字符串,如果返回为null,说明数据已经读完了 while ((str = br.readLine()) != null) { System.out.println(str); } } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } finally { if (br != null) { try { br.close(); } catch (IOException e) { e.printStackTrace(); } } if (fr != null) { try { fr.close(); } catch (IOException e) { e.printStackTrace(); } } } } }
3.8 BufferedWriter与BufferedReader实现文件的复制
-
案例
package com.bx.rw; import com.bx.IOUtils; import java.io.*; public class BufferedReaderAndBufferedWriterCopyTest { public static void main(String[] args) throws IOException { FileReader fr = new FileReader("c:/tmp/data.txt"); FileWriter fw = new FileWriter("c:/tmp/data1.txt"); BufferedReader br = new BufferedReader(fr); BufferedWriter bw = new BufferedWriter(fw); //边读边写BufferedReader用来读目标文件,BufferedWriter吧读到的内容写到新文件中 String str = br.readLine(); //读取一行 while (str != null) { //处理数据 bw.write(str); bw.newLine(); //读取一行 str = br.readLine(); } bw.flush(); IOUtils.close(bw); IOUtils.close(fw); IOUtils.close(br); IOUtils.close(fr); // try { // if (bw != null) { // bw.close(); // } // if (fw != null) { // fw.close(); // } // if (br != null) { // br.close(); // } // if (fr != null) { // fr.close(); // } // } catch (IOException e) { // e.printStackTrace(); // } } }
IOUtils
package com.bx;
import java.io.*;
public class IOUtils {
public static void close(Writer w) {
if (w != null) {
try {
w.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
public static void close(Reader r) {
if (r != null) {
try {
r.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
public static void close(OutputStream os) {
if (os != null) {
try {
os.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
public static void close(InputStream is) {
if (is != null) {
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
4.字节的输入输出流
4.1 OutputStream类
-
OutputStream它不仅可以写入字节,字符,还可以写入图片等媒体文件
-
由于OutputStream是抽象类不能创建对象,所以用它子类来完成写入字节的操作
4.2 FileOutputStream类
-
用OutputStream的子类java.io.FileOutputStream向文件中写入字节
-
FileOutputStream类的构造方法有5种重载方式,以下是常用的4种
-
案例
package com.bx.inputoutput; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; public class FileOutputStreamTest { public static void main(String[] args) { FileOutputStream fos = null; try { //创建FileOutputStream对象 fos = new FileOutputStream("date.txt"); //写指定字节到输出流 fos.write(97); //写字节数组到输出流中 fos.write("abc".getBytes()); fos.write("1234567".getBytes(), 1, 5);//一部分 fos.write("博肖".getBytes()); fos.flush(); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } finally { if (fos != null) { try { fos.close(); } catch (IOException e) { e.printStackTrace(); } } } } }
4.3 InputStream类
-
InputStream它不仅可以读取字节,字符,还可以读取图片等媒体文件
-
由于IntputStream是抽象类不能创建对象,所以用它子类来完成写入字节的操作
4.4 FileInputStream类
-
用InputStream的子类java.io.FileInputStream从文件中读取字节
-
FileOutputStream类的构造方法有3种重载方式,以下是常用的2种
构 造 方 法 说 明 FileInputStream(File file) throws FileNotFoundException 使用File对象创建文件输入流对象,如果文件打开失败,将抛出异常 FileInputStream(String name) throws FileNotFoundException 使用文件名或路径创建文件输入流对象,如果文件打开失败,将抛出异常 -
案例
package com.bx.inputoutput; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.nio.charset.Charset; public class FileInputStreamTest { public static void main(String[] args) { System.out.println("readByte():"); readByte(); System.out.println(); System.out.println("read():"); read(); } //读取一个 private static void read() { FileInputStream fis = null; try { fis = new FileInputStream("date.txt"); int num = fis.read(); while (num != -1) { System.out.println((char) num); num = fis.read(); } } catch (IOException e) { e.printStackTrace(); } } private static void readByte() { FileInputStream fis = null; try { //创建FileInputStream对象 fis = new FileInputStream("date.txt"); //定义字节数字 byte[] buffer = new byte[6]; //把流中的数据读取到定义的字节数组中 int len = fis.read(buffer); //循环读取,判断读取字节数量是否为-1,为-1停滞循环,否则一直循环 while (len != -1) { String s = new String(buffer, 0, len, Charset.defaultCharset()); //打印 System.out.println(s); //关闭FileInputStream len = fis.read(buffer); } } catch (IOException e) { e.printStackTrace(); } finally { if (fis != null) { try { fis.close(); } catch (IOException e) { e.printStackTrace(); } } } } }
4.5 FileInputStream与FileOutputStream实现文件复制
-
案例
package com.bx.inputoutput; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.util.Date; public class FileInputStreamAndFileOutputStreamCopyTest { public static void main(String[] args) { Date start = new Date(); FileInputStream fis = null; FileOutputStream fos = null; try { //创建FileInputStream和FileOutputStream对象 fis = new FileInputStream("date.txt"); fos = new FileOutputStream("date1.txt"); // fis = new FileInputStream("c:/tmp/aa.mp4"); // fos = new FileOutputStream("c:/tmp/aa1.mp4"); // fis = new FileInputStream("c:/tmp/bb.png"); // fos = new FileOutputStream("c:/tmp/bb1.png"); //定义字节数组 byte[] buffer = new byte[100];//空间可调大 //FileInputStream循环读取数据 int len; while ((len = fis.read(buffer)) != -1) { fos.write(buffer, 0, len); } fos.flush(); //FileOutputStream把字节数据写到新的文件里面 } catch (IOException e) { e.printStackTrace(); } finally { //关闭对象 try { if (fos != null) { fos.close(); } if (fis != null) { fos.close(); } } catch (IOException e) { e.printStackTrace(); } } Date end = new Date(); System.out.println(end.getTime() - start.getTime()); } }
package com.bx.inputoutput; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; public class FileInOutputStreamTest { public static void main(String[] args) { FileInputStream fis = null; FileOutputStream fos = null; try { fis = new FileInputStream("date.txt"); fos = new FileOutputStream("dateABC.txt"); byte[] bytes = new byte[100]; int len; while ((len = fis.read(bytes)) != -1) { fos.write(bytes, 0, len); } fos.flush(); } catch (IOException e) { e.printStackTrace(); } finally { try { if (fos != null) { fos.close(); } if (fis != null) { fis.close(); } } catch (IOException e) { e.printStackTrace(); } } } }
4.6 BufferedOutputStream类
-
BufferedOutputStream类里有一个方法要注意
-
案例
package com.bx.inputoutput; import com.bx.IOUtils; import java.io.BufferedOutputStream; import java.io.FileOutputStream; import java.io.IOException; public class BufferedOutputStreamTest { public static void main(String[] args) { FileOutputStream fos = null; BufferedOutputStream bos = null; try { fos = new FileOutputStream("data2.txt"); bos = new BufferedOutputStream(fos); bos.write(97); bos.write("abcdefg".getBytes(), 2, 5); bos.write("ABCD".getBytes()); } catch (IOException e) { e.printStackTrace(); } finally { IOUtils.close(bos); IOUtils.close(fos); } } }
4.7 BufferedInputStream类
-
BufferedInputStream类里有一个方法要注意
-
案例
package com.bx.inputoutput; import com.bx.IOUtils; import java.io.BufferedInputStream; import java.io.FileInputStream; import java.io.IOException; public class BufferedInputStreamTest { public static void main(String[] args) { FileInputStream fis = null; BufferedInputStream bis = null; try { fis = new FileInputStream("data2.txt"); bis = new BufferedInputStream(fis); byte[] buffer = new byte[3]; int len; while ((len = bis.read(buffer)) != -1) { String s = new String(buffer, 0, len); System.out.println(s); } } catch (IOException e) { e.printStackTrace(); } finally { IOUtils.close(bis); IOUtils.close(fis); } } }
4.8 BufferedInputStream与BufferedOutputStream实现文件复制
-
案例
package com.bx.inputoutput; import com.bx.IOUtils; import java.io.*; import java.util.Date; public class BufferedOutputStreamAndBufferedInputStreamCopyTest { public static void main(String[] args) { Date start = new Date(); FileInputStream fis = null; FileOutputStream fos = null; BufferedInputStream bis = null; BufferedOutputStream bos = null; try { fis = new FileInputStream("C:/tmp/bb.png"); fos = new FileOutputStream("C:/tmp/bb2.png"); bis = new BufferedInputStream(fis); bos = new BufferedOutputStream(fos); byte[] buffer = new byte[100]; int len; while ((len = bis.read(buffer)) != -1) { bos.write(buffer, 0, len); } bos.flush(); } catch (IOException e) { e.printStackTrace(); } finally { IOUtils.close(bos); IOUtils.close(bis); IOUtils.close(fos); IOUtils.close(fis); } Date end = new Date(); System.out.println(end.getTime() - start.getTime()); } }
5.System的标准输入输出流
5.1 输入和输出流
-
程序对应的基本输入为键盘输入,基本输出为显示器输出。Java中,System类的in和out两个成员代表了基本输入输出的抽象
-
System.in:
-
System.in是InputStream, 标准输入流, 默认可以从键盘输入读取字节数据
-
注意:System.in流是无需关闭的
-
案例
package com.bx.sys; import java.io.BufferedInputStream; import java.io.IOException; public class SystemInTest { public static void main(String[] args) { //创建BufferedInputStream对象,传入的参数时System.in的InputStream(接收键盘输入的数据) //System.in无需关闭 BufferedInputStream bis; System.out.print("输入数据:"); try { bis = new BufferedInputStream(System.in); //定义字节数组 byte[] buffer = new byte[200]; int len; while ((len = bis.read(buffer)) != -1) { String s = new String(buffer, 0, len); System.out.println("获取数据:" + s); } //循环读取数据并打印到控制台 } catch (IOException e) { e.printStackTrace(); } } }
-
-
System.out:
-
System.out是PrintStream, 标准输出流, 默认可以向Console中输出字符和字节数据
-
PrintStream继承了OutputStream
-
案例
package com.bx.sys; import com.bx.IOUtils; import java.io.BufferedOutputStream; import java.io.IOException; public class SystemOutTest { public static void main(String[] args) { //传入的参数是System.out是从PrintStream,输出控制台和字节 BufferedOutputStream bos = null; bos = new BufferedOutputStream(System.out); try { bos.write("abcd".getBytes()); bos.flush(); } catch (IOException e) { e.printStackTrace(); } finally { IOUtils.close(bos); } } }
-
-
5.2 Scanner类
-
Scanner类位于java.util包中,不在java.io包中,不属于IO流
-
Scanner是一个工具类,主要目标是简化文本的扫描,最常使用此类获取控制台输入,Scanner获取控制台输入的步骤:
-
使用控制台输入创建Scanner对象
Scanner scanner=new Scanner(System.in);
-
-
调用Scanner中的nextXXX方法,获得需要的数据类型
例如:next、 nextLine、nextInt、nextByte等
package com.bx.sys; import java.util.Scanner; public class ScannerTest { public static void main(String[] args) { //Scanner是工具类 //System.in是InputStream字节输入流,可以读取键盘输入的数据 Scanner sc = new Scanner(System.in); while (true) { System.out.println("输入数据:"); String next = sc.next(); //"exit".equals(next)和next.equals("next") //如果next为null,"exit".equals(next),返回false next.equals("next")空指针异常。 if ("exit".equals(next)) { System.out.println("再见"); break; } System.out.println("输入的数据:" + next); } } }
6.字节字符转换流
-
转换流:以将一个字节流转换为字符流,也可以将一个字符流转换为字节流
-
字节字符转换流位于java.io包
6.1 OutputStreamWriter类
-
OutputStreamWriter:可以将输出的字符流转换为字节流的输出形式
-
字符流转换成字节流图解
-
案例
package com.bx.writer_to_outputstream; import com.bx.IOUtils; import java.io.*; public class OutputStreamWriterTest { public static void main(String[] args) { //OutputStreamWriter(继承了Writer) //BufferedWriter对象 把字符串写入流中(写入字符流->转换流->字节流->文件中) FileOutputStream fos = null; OutputStreamWriter osw = null; BufferedWriter bw = null; try { fos = new FileOutputStream("myData.txt"); osw = new OutputStreamWriter(fos, "utf-8"); bw = new BufferedWriter(osw); bw.write("BJYXZSWWLSFY"); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } finally { IOUtils.close(bw); IOUtils.close(osw); IOUtils.close(fos); } } }
6.2 InputStreamReader类
-
InputStreamReader:将输入的字节流转换为字符流输入形式。
-
字节流转换成字符流图解
-
案例
package com.bx.writer_to_outputstream; import java.io.*; public class SystemReaderTest { public static void main(String[] args) { InputStream in=System.in; InputStreamReader isr=null; try { isr=new InputStreamReader(in,"utf-8"); BufferedReader br=new BufferedReader(isr); while (true){ String s=br.readLine(); System.out.println("数据:"+s); } } catch (UnsupportedEncodingException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } }
7.随机访问文件流
-
随机流(RandomAccessFile):此类的实例支持对随机访问文件的读取和写入
-
位于java.io包
-
特点
-
该对象即能读也能写,一个对象就搞定
-
该对象内部维护了一个大型 byte 数组,光标或索引在该数组任意位置读取或写入任意数据
-
可以通过getFilePointer方法获得光标的位置和通过seek方法设置光标位置
-
该对象将字节输入流和输出流进行了封装
-
该对象源或目的,只能文件,通过下面的构造方法就可以看出
-
-
构造方法
-
随机流的方法有很多
-
案例
package com.bx.test1; import java.io.IOException; import java.io.RandomAccessFile; public class RandomAccessFileTest { public static void main(String[] args) { RandomAccessFile randomAccessFile; try { //创建RandomAccessFile对象 //构造方法参数,第一个参数:文件名称,第二个参数:r表示读w表示写,rw表示读写 randomAccessFile = new RandomAccessFile("writedate", "rw"); //seek()把指针移动到指定位置 //utf-8中文编码,一个汉字三个字节 //略过前四个汉字 randomAccessFile.seek(3 * 4); //定义缓冲数组 byte[] buffer = new byte[30]; //read,从指定位置读取数据到byte[] buffer数组中 //读取12个字节(4个汉字)到buffer中 randomAccessFile.read(buffer, 0, 12); //把buffer数组中的数据转换成字符串 String str = new String(buffer, 0, 12); System.out.println(str); //seek再把指针移动到指定位置 //略过2个汉字 randomAccessFile.seek(2 * 3); //写入数据,覆盖对应的位置数据 //字符串“大”所在的文件RandomAccessFileTest.java比如是utf-8编码--->"大".getByte("utf-8")没有问题 //字符串“大”所在的文件RandomAccessFileTest.java比如是gbk编码--->"大".getByte("gbk")有问题 randomAccessFile.write("大".getBytes("gbk")); } catch (IOException e) { e.printStackTrace(); } } }
8.字节数组流
-
字节数组流:提供了针对于字符数组 byte [] 的标准的IO操作方式
-
位于java.io包
-
ByteArrayInputStream 和 ByteArrayOutputStream
-
ByteArrayInputStream将会给一个byte buf[] 提供标准的IO操作方式
-
ByteArrayOutputStream则是将数据写入到内部的字节数组中
-
-
ByteArrayInputStream 和 ByteArrayOutputStream
-
ByteArrayOutputStream 写入的是自己内部的字节数组,属于内存数据,不涉及任何资源,所以不需要close
-
案例
package com.bx.test1;
import java.io.*;
public class ByteArrayOutputAndInputStreamTest {
public static void main(String[] args) {
byte[] buffer = getByte();
readByte(buffer);
}
private static byte[] getByte() {
BufferedOutputStream bos = null;
try {
//字节数组输出流对象(内存中)
ByteArrayOutputStream baos = new ByteArrayOutputStream();
bos = new BufferedOutputStream(baos);
bos.write("hello world".getBytes());
bos.flush();
return baos.toByteArray();
} catch (IOException e) {
e.printStackTrace();
return null;
} finally {
if (bos != null) {
try {
bos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
private static void readByte(byte[] buffer) {
BufferedInputStream bis = null;
try {
//字节数组输入流
ByteArrayInputStream bais = new ByteArrayInputStream(buffer);
bis = new BufferedInputStream(bais);
byte[] buf = new byte[buffer.length];
bis.read(buf);
String s = new String(buf);
System.out.println(s);
} catch (IOException e) {
e.printStackTrace();
} finally {
if (bis != null) {
try {
bis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}