1、Comment 木木木木1: 这个特点,我们在介绍方法的用法时,尤其注意。引言1. 数据源data source. 提供原始数据 的原始媒介。常见的: 数据库、文件、其他程序、内存、网络连接、IO 设备2. 流的概念Stream:名词,水流,趋势。动词:流出,流动。数据源就像水箱,流就像水管中流着的水流,程序就是我们最终的用户。 流是一个抽象、动态的概念,是一连串连续动态的数据集合。 3. 第一个简单的 IO流程序(将文件中的数据读入)当程序需要读取数据源的数据时,就会通过 IO流对象开启一个通向数据源的流,通过这个 IO流对象相关方法可以 顺序读取流中的数据。同理,通过流向目的地写入数据通过
2、流来处理。基本代码如下:这个代码是通过流对象从一个文件中读取数据:try FileInputStream fis = new FileInputStream(“d:/a.txt“); /内容是:abcint s1 = fis.read(); /97int s2 = fis.read(); /98int s3 = fis.read(); /99int s4 = fis.read(); /-1int s5 = fis.read(); /-1System.out.println(s1);fis.close(); catch (FileNotFoundException e) e.printStack
3、Trace(); catch (IOException e) e.printStackTrace();上面的代码可以升级为如下更加标准的代码:FileInputStream fis =null;try fis = new FileInputStream(“d:/a.txt“); /内容是:abcComment 木木木木2: 也可以对其他处理流StringBuilder sb = new StringBuilder();int temp = 0;while(temp=fis.read()!=-1)sb.append(char)temp);System.out.println(sb); catch
4、 (FileNotFoundException e) e.printStackTrace(); catch (IOException e) e.printStackTrace();finallytryif(fis!=null)fis.close(); /流对象,使用完后必须关闭!catch(IOException e)e.printStackTrace();4. Java中流的概念细分流的方向:输入流:数据源到程序(InputStream 、Reader 读进来)输出流:程序到目的地(OutPutStream、Writer 写出去)处理数据单元:字节流:按照字节读取数据(InputStream
5、 、OutputStream)字符流:按照字符读取数据(Reader、Writer)功能不同:节点流:可以直接从数据源或目的地读写数据。处理流:不直接连接到数据源或目的地,是处理流的流。通过对其他流的处理提高程序的性能。节点流和处理流的关系:节点流处于 io操作的第一线,所有操作必须通过他们进行;处理流可以对节点流进行包装,提高性能或提高程序的灵活性。处理流:5. Java 中 IO 流类的体系(这里只列出常用的类,详情可以参考 JDK API 文档。红色粗体标注为最常用,必须掌握的!)四个基本抽象类:InputStream:ObjectFileRandomAccessFileInputStr
6、eamOutputStreamReaderWriterByteArrayInputStreamSequenceInputStreamStringBufferInputStreamPipedInputStreamFileInputStreamFilterInputStreamObjectInputStreamBufferedInputStreamPushBackInputStreamLineNumberInputStreamByteArrayOutputStreamPipedOutputStreamFileOutputStreamFilterOutputStreamObjectOutputStr
7、eamBufferedOutputStreamPrintStreamBufferedReaderFilterReaderInutStreamReaderPipedReaderStringReaderFileReaderBufferedWriterFilterWriterOututStreamWriterPipedWriterStringWriterFileWriterDateOutputDateInputComment 木木木木3: 也就是说,处理文本的话使用字符流。此抽象类是表示字节输入流的所有类的超类。InputSteam 是一个抽象类,它不可以实例化。数据的读取需要由它的子类来实现。根据
8、节点的不同,它派生了不同的节点流子类 。继承自 InputSteam的流都是用于向程序中输入数据,且数据的单位为字节( 8 bit) ;下图中深色为节点流,浅色为处理流。常用方法:read, close. 详情可以参考 API文档。OutputStream:此抽象类是表示输出字节流的所有类的超类。输出流接受输出字节并将这些字节发送到某个接收器。常见子类的使用方法:1. FileInputStream和 FileOutputStream构造方法和常用方法:自己参考 API文档。FileInputStream用于读取诸如图像数据之类的原始字节流。要读取字符流,请考虑使用 FileReader。av
9、ailable(): 并不是指定文件还有多少数据没有读,不然,如果是 100g的大文件,返回得数就溢出了。不过,对于普通文件的话可以看做是剩余的未读数据。返回下一次对此输入流调用的方法可以不受阻塞地从此输入流读取(或跳过)的估计剩余字节数。FileOutputStream 用于写入诸如图像数据之类的原始字节的流。要写入字符流,请考虑使用 FileWriter。练习:文件读取到内存中:void testInputStream()FileInputStream fis = null;StringBuilder sb = new StringBuilder();int temp = 0;int nu
10、m = 0;long date1 = System.currentTimeMillis();try fis = new FileInputStream(“d:/a.txt“); /内容是:abc/* while(temp = fis.read()!=-1)sb.append(char)temp);num+;*/使用数组作为缓存,读取的效率大大提高byte buffer = new byte1024; while(temp=fis.read(buffer)!=-1)sb.append(new String(buffer,0,temp);System.out.println(sb); catch
11、(FileNotFoundException e) e.printStackTrace(); catch (IOException e) e.printStackTrace();finallytry fis.close(); catch (IOException e) e.printStackTrace();new File(“d:“+File.separator+“a.txt“);long date2 = System.currentTimeMillis();System.out.println(“耗时:“ +(date2-date1);将字符串/字节数组的内容写入到文件中:FileOutp
12、utStream fos = null;String string = “abcdefg“;try fos = new FileOutputStream(“d:/a.txt“,true);fos.write(string.getBytes(); catch (FileNotFoundException e) e.printStackTrace(); catch (IOException e) / TODO Auto-generated catch blocke.printStackTrace();finallytry fos.close(); catch (IOException e) e.p
13、rintStackTrace();实现文件的复制功能:copyFile(“d:/a.txt“, “d:/b.txt“); /b.txt可以不存在。void copyFile(String src,String dec)FileInputStream fis = null;FileOutputStream fos = null;byte buffer = new byte1024; /为了提高效率,设置缓存数组int temp = 0;try fis = new FileInputStream(src);fos = new FileOutputStream(dec);while(temp=fis
14、.read(buffer)!=-1)fos.write(buffer, 0, temp); catch (FileNotFoundException e) e.printStackTrace(); catch (IOException e) e.printStackTrace();finallytry fos.close(); catch (IOException e) e.printStackTrace();try fis.close(); catch (IOException e) e.printStackTrace();/copy目录下面所有的内容到另一个目录!(作业!)public c
15、lass TestCopy public static void main(String args) /1. 实现一个文件到另一个文件的copy/2. 实现一个目录(目录下面只有文件) 到另一个目录的 copy/3.实现一个目录(目录下面包含文件和子目录)到另一个目录的copy/4.利用递归,实现将一个目录下面所有的内容copy到另一个目录File file = new File(“D:share0100_JavaSEppt“);File file2 = new File(“e:/tt“);copyDir(file,file2);/负责copy一个目录下面所有的文件和子目录到另一个目录stat
16、ic void copyDir(File file,File file2)new File(file2,file.getName().mkdir();/copyFile(new File(file,“22.txt“),new File(file2,“22.txt“);File files = file.listFiles();for(File f:files)if(f.isDirectory()copyDir(f,new File(file2,file.getName();if(f.isFile()copyFile(f,new File(new File(file2,file.getName(
17、),f.getName(); /*将d:/a/下所有的内容copy到e:/tt/*/static void copyFile(File src,File dec)FileInputStream fis = null;FileOutputStream fos = null;byte buffer = new byte1024; /为了提高效率,设置缓存数组int temp = 0;try fis = new FileInputStream(src);fos = new FileOutputStream(dec);while(temp=fis.read(buffer)!=-1)fos.write(
18、buffer, 0, temp); catch (FileNotFoundException e) e.printStackTrace(); catch (IOException e) e.printStackTrace();finallytry fos.close(); catch (IOException e) e.printStackTrace();try fis.close(); catch (IOException e) e.printStackTrace();public static void copy(File src,File desx)new File(desx, src.
19、getName().mkdir();File files = src.listFiles();if(files.length=0)copy1(src, new File(desx,src.getName();elsefor(File temp:files)if(temp.isDirectory()=false)copy1(temp, new File(new File(desx, src.getName(),temp.getName();elsecopy(temp,new File(new File(desx, src.getName(),temp.getName();public stati
20、c void copy1(File src,File desx)FileInputStream inputStream = null;FileOutputStream outputStream = null;try inputStream = new FileInputStream(src);outputStream = new FileOutputStream(desx);byte temp = new byte1024;int index = 0;while(index=inputStream.read(temp)!=-1)outputStream.write(temp, 0, index
21、); catch (FileNotFoundException e) / TODO Auto-generated catch blocke.printStackTrace(); catch (IOException e) / TODO Auto-generated catch blocke.printStackTrace();2. ByteArrayInutStream 和 ByteArrayOutputStream(经常用在需要流和数组之间转化的情况!)ByteArrayInputStream 包含一个内部缓冲区,该缓冲区包含从流中读取的字节。内部计数器跟踪 read 方法要提供的下一个字节
22、。说白了,FileInputStream 是把文件当做数据源。ByteArrayInputStream 则是把内存中的某个数组当做数据源。ByteArrayOutputStream:此类实现了一个输出流,其中的数据被写入一个 byte 数组。缓冲区会随着数据的不断写入而自动增长。可使用 toByteArray() 和 toString() 获取数据。 ByteArrayOutputStream 将一个输出流指向一个 Byte数组,但这个 Byte数组是 ByteArrayOutputStream内部内置的,不需要我们来定义。注:不需要关闭流的,但是调用 close 也没有问题,close 不做
23、任何事情。因为ByteArrayOutputStream 本身操作的是数组,并没有打开文件描述符之类的,所以不需要关闭。简单测试ByteArrayInputStream :ByteArrayInputStream bais = null;StringBuilder sb = new StringBuilder();int temp = 0;int num = 0;long date1 = System.currentTimeMillis();try byte b = “abcdefghijklmnopqrstuvwxyz“.getBytes();/ bais = new ByteArrayIn
24、putStream(b); bais = new ByteArrayInputStream(b,2,10); while(temp = bais.read()!=-1)sb.append(char)temp);num+;System.out.println(sb);System.out.println(“读取的字节数:“+num); finallytry bais.close(); catch (IOException e) e.printStackTrace();new File(“d:“+File.separator+“a.txt“);long date2 = System.current
25、TimeMillis();System.out.println(“耗时:“ +(date2-date1);将输入流的内容读入到一个数组中返回:byte getBytesFromIS(FileInputStream fis)ByteArrayOutputStream baos = null;int temp = 0;try baos = new ByteArrayOutputStream();while(temp=fis.read()!=-1)baos.write(temp);return baos.toByteArray(); /从而返回一个包含输入流所有内容的数组 catch (IOExce
26、ption e) e.printStackTrace();return null;3. BufferedInputStream 和 BufferedOutputStream是处理流。 通过内部缓存数组来提高操作流的效率。使用 BufferedInputStream 和 BufferedOutputStream 实现文件的复制:void copyFile(String src,String dec)FileInputStream fis = null;BufferedInputStream bis = null;FileOutputStream fos = null;BufferedOutput
27、Stream bos = null;int temp = 0;Comment s4: bufferedOutputStream的 write一定要强制刷新吗?Comment s5: 必须强制刷新try fis = new FileInputStream(src);fos = new FileOutputStream(dec);bis = new BufferedInputStream(fis);bos = new BufferedOutputStream(fos);while(temp=bis.read()!=-1)bos.write(temp);bos.flush(); catch (Fil
28、eNotFoundException e) e.printStackTrace(); catch (IOException e) e.printStackTrace();finally/增加处理流后,注意流的关闭顺序!“后开的先关闭!”try bos.close(); catch (IOException e) e.printStackTrace();try bis.close(); catch (IOException e) e.printStackTrace();try fos.close(); catch (IOException e) e.printStackTrace();try f
29、is.close(); catch (IOException e) e.printStackTrace();BufferedWiter和 BufferedReadpublic static void copyBychar()FileReader fileReader = null;BufferedReader bufferedReader = null;Comment s6: 注意:先关闭高效类,再关闭基本类,由于高效率依存于基本类,不需要强制刷新FileWriter fileWriter = null;BufferedWriter bufferedWriter = null;try file
30、Reader = new FileReader(new File(“d:/add/text.java“);bufferedReader = new BufferedReader(fileReader);fileWriter = new FileWriter(new File(“d:/sss.java“);bufferedWriter = new BufferedWriter(fileWriter);String temp = “;while(temp=bufferedReader.readLine()!=null)bufferedWriter.write(temp); catch (FileN
31、otFoundException e) / TODO Auto-generated catch blocke.printStackTrace(); catch (IOException e) / TODO Auto-generated catch blocke.printStackTrace();finallytry bufferedReader.close();fileReader.close();bufferedWriter.close();fileWriter.close(); catch (IOException e) / TODO Auto-generated catch block
32、e.printStackTrace();4. DataInputStream和 DataOutputStream数据流 通常在流中写入或读取一个结果时使用 ,如网络数据传递。DataInputStream和 DataOutputStream提供了可以存取与机器无关的所有 Java基础类型数据(如:int,double 等)的方法 。 public class TestDataStream public static void main(String args) DataOutputStream dos = null;DataInputStream dis = null;try dos = ne
33、w DataOutputStream(new BufferedOutputStream(new FileOutputStream(“D:share0100_JavaSEpptsrc8iodata.txt“);dis = new DataInputStream(new BufferedInputStream(new FileInputStream(“D:share0100_JavaSEpptsrc8iodata.txt“);dos.writeDouble(Math.random();dos.writeBoolean(true);dos.writeInt(10);dos.writeChar(a);
34、dos.writeUTF(“中國字“);dos.flush();/从文件中直接读取数据System.out.println(“double: “ + dis.readDouble();System.out.println(“boolean: “ + dis.readBoolean();System.out.println(“int: “ + dis.readInt();System.out.println(“char: “ + dis.readChar();System.out.println(“String: “ + dis.readUTF(); catch (IOException e)
35、e.printStackTrace(); finally try dos.close(); catch (IOException e) / TODO Auto-generated catch blocke.printStackTrace();try dis.close(); catch (IOException e) / TODO Auto-generated catch blocke.printStackTrace();5. ObjectInputStream 和 ObjectOutputStream见专题文档:java 对象的序列化和反序列化。6. PrintStreamSystem.ou
36、t 就是一个 PrintStream。 简单看看就行了。Reader:用于读取字符流的抽象类,数据单位为字符。Writer:写入字符流的抽象类。FileReader 和 FileWriter:实现文本文件的 copy: 写法和使用stream基本一样。只不过,读取时是读取的字符 。FileReader fr = null;FileWriter fw = null;int c = 0;try fr = new FileReader(“d:/a.txt“);fw = new FileWriter(“d:/d.txt“);while(c=fr.read()!=-1)fw.write(c); catc
37、h (FileNotFoundException e) e.printStackTrace(); catch (IOException e) e.printStackTrace();finallytry fw.close(); catch (IOException e) e.printStackTrace();try fr.close(); catch (IOException e) e.printStackTrace();BufferReader 和 BufferWriter(实际开发中用的很多,需要大家亲自敲一遍!):使用他们来实现文本文件的复制:FileReader fr = null;
38、FileWriter fw = null;BufferedReader br = null;BufferedWriter bw = null;String tempString = “;try fr = new FileReader(“d:/a.txt“);fw = new FileWriter(“d:/d.txt“);br = new BufferedReader(fr);bw = new BufferedWriter(fw);while(tempString=br.readLine()!=null)bw.write(tempString); catch (FileNotFoundExcep
39、tion e) e.printStackTrace(); catch (IOException e) e.printStackTrace();finallytry bw.close(); catch (IOException e1) e1.printStackTrace();try br.close(); catch (IOException e1) e1.printStackTrace();try fw.close(); catch (IOException e) e.printStackTrace();try fr.close(); catch (IOException e) e.prin
40、tStackTrace();InputStreamReader 和 OutputStreamWriter用来实现将字节流转化成字符流/接受用户的输入BufferedReader bReader = null;try System.out.println(“名字:“ );bReader = new BufferedReader(new InputStreamReader(System.in);System.out.println(“用户输入:“ +bReader.readLine(); catch (IOException e) / TODO Auto-generated catch block
41、e.printStackTrace();附录(IO 中其他常用类):File 类:文件和目录路径名的抽象表示形式。一个 File 对象可以代表一个文件或目录,但是不是完全对应的。建立 File 对象不会对文件系统产生影响。RandomAccessFile:(不作为重点,了解即可!工作中用的非常少!)还是不讲了!用的不多!用来任意读取文件中某个位置的信息!有兴趣,大家可以自学一下!学习一下 Apache Commons 中的 IO 扩展类(了解一下):http:/commons.apache.org/io/, 简单学习一下,不需要看具体的 api。如果能在google 上搜索到中文帮助,可以详细
42、研究一下。JAVA 流技术总结(作业,要检查每个人写的!) 字节流 数据源/目的地经常用于 典型用法字符流 数据源/目的地特点 经常用于 典型用法3 班中南大学王鑫作业:字节流 类型 数据源/目的地 经常用于 典型用法InputStream 字节输入流超类 数据源: 文件/内存(数组、对象)/网络/数据库向程序中输入数据 Read,closeOutputStream 字节输出流超类 目的地:文件/内存(数组、对象)/网络/数据库向目的地输出数据 Flush,writeByteArryInputStream 节点流 数据源:字节数组 从字节数组向程序中输入数据1. close 方法可调可不调Re
43、ad,closeFileInputStream 节点流 数据源:文件 从文件向程序中输入数据 Read,closeObjectInputStream 处理流 数据源:对象 从对象向程序中输入数据 Read,closeByteArrayOutputStream 节点流 目的地:字节数组 输出流接受输出字节并将这些字节发送到字符数组 Flush,writeFileOutputStream 节点流 目的地:文件 输出流接受输出字节并将这些字节发送到文件 Flush,writeObjectOutputStream 处理流 目的地:对象 输出流接受输出字节并将这些字节发送到对象 Flush,writeD
44、ataInputStream 处理流 处理基本类型的数据 Read,closeBufferedInputStream 处理流 数据源:底层输入流 向程序中输入数据通过内部缓存数组来提高操作流的效率。Read,closeDataOutputStream 节点流 目的地:数据 处理基本类型的数据 Flush,writeBufferedOutputStream 处理流 目的地:底层输入流 输出流接受输出字节并将这些字节发送到底层输出流通过内部缓存数组来提高操作流的效率。Flush,writePrintStream 目的地:新打印流 写入 byte 数组之后自动调用 flush 方法 Flush,cl
45、ose.,print字符流 数据源/目的地 特点 经常用于 典型用法ReaderFileReader 数据源:文件 读取的是字符 用来读取字符文件的便捷类FileReader(File file)BufferReader 数据源:文本 读取的是字符,可以指定缓冲区的大小,或者可使用默认的大小从字符输入流中读取文本,缓冲各个字符,从而实现字符、数组和行的高效读取。Close,read, BufferedReader(Reader in)用于读取字符流的抽象类,数据单位为字符。InputStreamReader 数据源:字节流 用于将字节流转化成字符流用于将字节流转化成字符流InputStream
46、Reader(InputStream in)Close,readWriterFileWriter 目的地:文件 写入的是字符 写入字符文件的便捷类FileWriter(File file)BufferWriter 目的地:文本 写入的是字符, 可以指定缓冲区的大小,或者接受默认的大小将文本写入字符输出流,缓冲各个字符,从而提供单个字符、数组和字符串的高效写入BufferedWriter(Writer out),close,read写入字符流的抽象类。OutputStreamReader 目的地:字节流 用于将字节流转化成字符流OutputStreamWriter(OutputStream out)Close,flush,write