Java基础 IO流——第三部分
新博客地址:Temi
- 用于将文件或者文件夹封装成对象。
- 方便对文件与文件夹进行操作。
- File对象可作为参数传递给流对象的构造方法。
- File 类的声明:public class File extends Object implements Serializable, Comparable<File> 文件和目录路径名的抽象表示形式。
- 构造方法:public File(String pathname) 通过将给定路径名字符串转换为抽象路径名来创建一个新
File
实例。如果给定字符串是空字符串,那么结果是空抽象路径名。 - 构造方法:public File(String parent, String child) 根据 parent 路径名字符串和 child 路径名字符串创建一个新
File
实例。==方便于目录不变文件变化的情况== - 构造方法:public File(URI uri) 通过将给定的 file: URI 转换为一个抽象路径名来创建一个新的 File 实例。
- 静态字段:public static final String separator 与系统有关的默认名称分隔符,为了方便,它被表示为一个字符串。此字符串只包含一个字符。
- 方法:public long length() 此抽象路径名表示的文件的长度,以字节为单位;如果文件不存在,则返回
0L
。 - 方法:public String getPath() 将此抽象路径名转换为一个路径名字符串。所得字符串使用
默认名称分隔符
分隔名称序列中的名称。 - 方法:public String getName() 返回由此抽象路径名表示的文件或目录的名称。
- 方法:public String getParent() 返回此抽象路径名父目录的路径名字符串;如果此路径名没有明确指定父目录,则返回
null
。 - public boolean createNewFile() throws IOException 如果指定的文件不存在并成功地创建,则返回
true
;如果指定的文件已经存在,则返回false ===注:从方法只能创建文件,不能创建目录===
- 方法:public boolean mkdir() 创建此抽象路径名指定的目录。
- 方法:public boolean mkdirs() 创建此抽象路径名指定的目录,包括所有必需但不存在的父目录。注意,此操作失败时也可能已经成功地创建了一部分必需的父目录。
- 方法:public boolean delete() 删除此抽象路径名表示的文件或目录。如果此路径名表示一个目录,则该目录必须为空才能删除。
- public void deleteOnExit() 在虚拟机终止时,请求删除此抽象路径名表示的文件或目录。==此方法可以避免当文件正在被打开时无法删除的问题===
- 方法:public boolean renameTo(File dest) 重新命名此抽象路径名表示的文件。
二,需求分析:实现使用File 对象实现文件的创建,以及删除
三,代码练习:
1 import java.io.*;
2
3
4 public class FileDemo {
5
6 public static void main(String[] args) {
7
8 //创建File对象
9 File f=new File("E:/myfile.txt");
10
11 try {
12
13 //创建文件
14 f.createNewFile();
15 } catch (IOException e) {
16 System.out.println("文件创建失败"+e.toString());
17 }
18
19 //在程序关闭时删除文件
20 f.deleteOnExit();
21 }
22
23 }
第三讲,第四讲:黑马程序员_毕向东_Java基础视频教程第20天-03-IO流(File对象功能-判断),第20天-04-IO流(File对象功能-获取)
一,File 类中有很多返回值为 boolean 的方法,这些方法可以对文件进行一系列的判断:
- public boolean canExecute() 测试应用程序是否可以执行此抽象路径名表示的文件。
- public boolean exists() 测试此抽象路径名表示的文件或目录是否存在。
- public boolean isFile() 测试此抽象路径名表示的文件是否是一个标准文件。
- public boolean isDirectory() 测试此抽象路径名表示的文件是否是一个目录。
- public boolean isHidden() 测试此抽象路径名指定的文件是否是一个隐藏文件。
二,File 类中的一些列getXXX()方法可以用于获取文件信息。
- public String getPath() 将此抽象路径名转换为一个路径名字符串。所得字符串使用
默认名称分隔符
分隔名称序列中的名称。===注:封装什么路径获取什么路径== - public String getAbsolutePath() 返回此抽象路径名的绝对路径名字符串。 ===注:总是返回绝对路径===
- public long lastModified() 返回此抽象路径名表示的文件最后一次被修改的时间。
- public long length() 返回由此抽象路径名表示的文件的长度。
- public String getPath() 将此抽象路径名转换为一个路径名字符串。所得字符串使用
三,代码练习,重命名文件实现剪切: =============注:此种方法若目标文件存在则剪切失败==================
1 import java.io.*; 2 3 public class FileDemo2 { 4 public static void main(String rgs[]){ 5 6 //源文件 7 File f=new File("E:/test.java"); 8 9 //目标文件 10 File f2=new File("F:/test.txt"); 11 12 //如果源文件不存在给出提示,结束程序 13 if(!f.exists()){ 14 System.out.println("源文件不存在"); 15 System.exit(0); 16 } 17 18 //如果源不是文件,给出提示,退出程序 19 if(!f.isFile()){ 20 System.out.println("目标不是文件"); 21 System.exit(0); 22 } 23 24 //将f重命名为f2实现文件的剪切 25 f.renameTo(f2); 26 27 //成功剪切,给出提示 28 System.out.println("成功剪切文件"); 29 } 30 }
第五讲:IO流(File对象功能-文件列表)
一,用到的File中的方法:
- public static File[] listRoots() 列出可用的文件系统根。
- public String[] list() 返回一个字符串数组,这些字符串指定此抽象路径名表示的目录中的文件和目录。
二,代码练习:
1 import java.io.File; 2 3 public class ListFileDemo { 4 public static void main(String args[]){ 5 6 //获得系统盘符 7 File[] f=File.listRoots(); 8 9 //循环输出盘符 10 for(File file:f){ 11 System.out.println(file); 12 } 13 14 15 //获得f[0]盘符下的文件和文件夹 16 String file[]=f[0].list(); 17 18 19 //循环输出 20 for(String s:file) 21 System.out.println(s); 22 } 23 }
第六讲:IO流(File对象功能-文件列表2)
一,需求分析:列出指定目录下所有的 ".java" 文件
二,用到的方法和类:
- public String[] list(FilenameFilter filter) 返回一个字符串数组,这些字符串指定此抽象路径名表示的目录中满足指定过滤器的文件和目录。
- 接口:FilenameFilter 此接口只有一个方法:boolean accept(File dir, String name) 测试指定文件是否应该包含在某一文件列表中。
三,代码练习:
1 import java.io.*; 2 public class ListJava { 3 public static void main(String args[]){ 4 5 //指定一个目录 6 File f=new File("E:\\java"); 7 8 // 用内部匿名类实现列出目录下指定的文件 9 String s[] = f.list(new FilenameFilter(){ 10 11 //覆写抽象方法,dir表示目录,name表示文件名 12 public boolean accept(File dir,String name){ 13 14 //如果文件名以".java" 结尾返回true否则返回false 15 return name.endsWith(".java"); 16 } 17 }); 18 19 //循环输出复合指定格式的文件名 20 for(String name : s){ 21 System.out.println(name); 22 } 23 } 24 }
===========注:list() 方法只能获取文件名称, listFile() 也可获得文件的其他信息,如路径===============
第七讲:IO流(列出目录下所有内容-递归)
一,需求分析:列出目录下所有内容,也就是列出指定目录下的所有内容。
二,思路分析:因为目录中还有目录,只要使用同一个列出目录功能的函数即可。在列出的过程中出现的还是目录的话,还可以再次调用本功能,也就势函数自身调用自身------递归。
三,使用递归计算一个十进制数字的二进制表示形式:原理图:
四,练习代码:
1 import java.io.*; 2 3 public class FileDemo3 { 4 public static void main(String args[]){ 5 6 7 //指定需要列出内容的文件 8 File filename=new File("E:\\java"); 9 10 //调用函数 11 myListFile(filename); 12 13 toBin(8); 14 } 15 16 17 //定义函数,列出文件下的所有内容。 18 public static void myListFile(File dir){ 19 20 //输出目录 21 System.out.println(dir); 22 23 //列出目录下的所有内容 24 File[] filearr=dir.listFiles(); 25 for(File f : filearr){ 26 27 //如果是文件夹,递归列出文件夹内容 28 if(f.isDirectory()){ 29 myListFile(f); 30 }else{ 31 32 //如果是文件输出 33 System.out.println(f); 34 } 35 } 36 } 37 38 39 //使用递归输出一个十进制数字的二进制形式 40 public static void toBin(int num){ 41 42 //使用递归,算出各个 除二的余数 43 if(num>0){ 44 toBin(num/2); 45 System.out.println(num%2); 46 } 47 } 48 }
========递归使用的注意:1,一定要有结束条件。2,注意递归的次数,避免内存的溢出==========
第八讲:IO流(列出目录下所有内容-带层次)
一,基本思想:列出目录内容的函数,递归一次目录深度加一。
二,代码练习:
1 import java.io.*; 2 3 4 public class FileDemo4 { 5 public static void main(String args[]){ 6 7 8 //指定需要列出内容的文件 9 File filename=new File("E:\\java"); 10 11 //调用函数 12 myListFile(filename); 13 14 } 15 16 17 //定义函数,列出文件下的所有内容。 18 public static void myListFile(File dir){ 19 20 21 //定义一个变量记录目录的深度 22 int level=1; 23 24 //输出目录,加上前缀 25 System.out.println(getLevel(level)+dir); 26 27 //列出目录下的所有内容 28 File[] filearr=dir.listFiles(); 29 for(File f : filearr){ 30 31 //如果是文件夹,递归列出文件夹内容 32 if(f.isDirectory()){ 33 myListFile(f); 34 }else{ 35 36 //如果是文件输出,加上前缀输出 37 System.out.println(getLevel(level)+f); 38 39 //函数每递归一次目录深度加一 40 level++; 41 } 42 } 43 } 44 45 46 //定义函数,根据目录的深度,返回制定的前缀 47 public static String getLevel(int level){ 48 49 //经常修改字符串内容,使用StringBuilder提高操作效率 50 StringBuilder sb=new StringBuilder(); 51 52 //根据深度增加指定长度的前缀 53 for(int x=0;x<level;x++) 54 sb.append("|--"); 55 56 //将前缀返回 57 return sb.toString(); 58 } 59 }
第九讲:IO流(删除带内容的目录)
一,删除目录的原理:
- 在Windows中删除目录都是从里面往外删除的。
- 既然是从里面向外面删除,那么就需要用到递归。
二,基本思路:
- 判断被删除对象是文件还是文件夹,若是文件则直接删除,若是文件夹则进行第二步。
- 列出文件夹中的所有文件,及子文件夹,对于每一个对象,进行第一步的判断。
- 当本文件夹下的所有内容都删除完了的时候,删除本文件夹。
三,代码练习:
1 import java.io.*; 2 3 public class RemoveDir { 4 public static void main(String args[]){ 5 myDelet(new File("E:\\java\\Snakes")); 6 } 7 8 9 public static void myDelet(File f){ 10 11 //接受目录下的所有文件及目录 12 File file[]=f.listFiles(); 13 14 15 //循环遍历目录中的内容 16 for(File delet : file){ 17 18 //如果是目录则递归判断 19 if(delet.isDirectory()) 20 myDelet(delet); 21 22 //如果是文件,删除 23 else if(delet.isFile()) 24 delet.delete(); 25 } 26 27 //目录中的内容删除后,删除本目录 28 f.delete(); 29 } 30 }
======注:特别注意一点,java中删除文件或者目录之后,不能在回收站中进行恢复======
第十讲:IO流(创建java文件列表)
一,需求分许:为了方便的找出文件的目录,将特定目录下的所有java文件的路径保存到一个文件中,方便查询。
二,思路:
- 先循环递归文件夹,寻找所有的java文件,找到则放入集合中。
- 将集合中的内容,写入文件中保存。
三,代码练习:
1 import java.io.*; 2 3 import java.util.*; 4 5 6 public class JavaFileList { 7 public static void main(String args[]){ 8 9 //创建file对象,指明需要列出java文件的目录 10 File dir = new File("E:/java"); 11 12 //创建文件列表,保存所有的java文件 13 List<File> list = new ArrayList<File>(); 14 15 //将指定目录下所有的java文件保存到列表中 16 fileToList(dir,list); 17 18 //将列表中所有文件的路径写入文件 19 writeToFile(list); 20 System.out.println(list.size()); 21 } 22 23 24 //创建方法将目录下java文件保存到列表中 25 public static void fileToList(File dir,List<File> list){ 26 27 //创建集合,保存目录下所有File 对象 28 File[] files = dir.listFiles(); 29 30 //遍历所有File对象 31 for(File file : files){ 32 33 //进行判断,如果是目录则进一步递归 34 if(file.isDirectory()){ 35 fileToList(file,list); 36 } 37 38 //如果是文件 39 if(file.isFile()){ 40 41 //判断是否是java文件 42 if(file.getName().endsWith(".java")); 43 44 //将java文件保存到集合中 45 list.add(file); 46 } 47 } 48 } 49 50 51 //创建方法将集合中的内容保存到文件中 52 public static void writeToFile(List<File> list){ 53 54 //保存到文件使用输出流,输出字符使用字符输出流,增加效率使用字符输出缓冲刘即 BufferedWriter 55 BufferedWriter bw=null; 56 try{ 57 58 //实例化缓冲流对象 59 bw = new BufferedWriter(new FileWriter("E:/javalist.txt")); 60 61 //遍历集合 62 for(File file : list){ 63 64 //写入文件的绝对路径 65 bw.write(file.getAbsolutePath()); 66 67 //换行 68 bw.newLine(); 69 70 //刷新 71 bw.flush(); 72 } 73 }catch(IOException e){ 74 System.out.println("操作失败"+e.toString()); 75 }finally{ 76 try{ 77 if(bw!=null) 78 bw.close(); 79 }catch(IOException e){ 80 System.out.println("为念关闭失败!"+e.toString()); 81 } 82 } 83 } 84 85 }
第十一讲,第十二讲:IO流(Properties简述),IO流(Properties存取)
一,Properties 简述: =======特点:不仅可以操作键值对而且可以操作硬盘上的键值对信息=======
- Properties 是 HashTable 的子类。也就是说它具备Map 集合的特点。且里面存储的键值对都是字符串。。
- 是集合中和IO技术相结合的容器。
- 可以用于键值对的配置文件。
二,Properties 了解:
- 类的声明:public class Propertiesextends Hashtable<Object,Object>
Properties
类表示了一个持久的属性集。Properties
可保存在流中或从流中加载。属性列表中每个键及其对应值都是一个字符串。 - 方法:public String getProperty(String key) 用指定的键在此属性列表中搜索属性。如果在此属性列表中未找到该键,则接着递归检查默认属性列表及其默认值。如果未找到属性,则此方法返回
null
。 - 方法:public String getProperty(String key, String defaultValue) 用指定的键在属性列表中搜索属性。如果在属性列表中未找到该键,则接着递归检查默认属性列表及其默认值。如果未找到属性,则此方法返回默认值变量。
- public Enumeration<?> propertyNames() 返回属性列表中所有键的枚举,如果在主属性列表中未找到同名的键,则包括默认属性列表中不同的键。
- public Set<String> stringPropertyNames() 返回此属性列表中的键集,其中该键及其对应值是字符串,如果在主属性列表中未找到同名的键,则还包括默认属性列表中不同的键。其键或值不是 String 类型的属性被忽略。
- public void list(PrintStream out) 将属性列表输出到指定的输出流。此方法对调试很有用。
- public void list(PrintWriter out) 将属性列表输出到指定的输出流。此方法对调试很有用。
- public void store(OutputStream out, String comments) throws IOException 以适合使用
load(InputStream)
方法加载到Properties
表中的格式,将此Properties
表中的属性列表(键和元素对)写入输出流。 - public void load(Reader reader) throws IOException 按简单的面向行的格式从输入字符流中读取属性列表(键和元素对)。
- public void load(InputStream inStream) throws IOException 从输入流中读取属性列表(键和元素对)。输入流按
load(Reader)
中所指定的、简单的面向行的格式,并假定使用 ISO 8859-1 字符编码。
三,小插曲:HashTable和HashMap有什么区别
- 继承的父类不同:Hashtable继承自Dictionary类,而HashMap继承自AbstractMap类。但二者都实现了Map接口。
- 线程安全性不同:Hashtable 中的方法是Synchronize的,而HashMap中的方法在缺省情况下是非Synchronize的。在多线程并发的环境下,可以直接使用Hashtable,不需要自己为它的方法实现同步,但使用HashMap时就必须要自己增加同步处理。
- 是否提供contains方法:HashMap把Hashtable的contains方法去掉了,改成containsValue和containsKey,因为contains方法容易让人引起误解。Hashtable则保留了contains,containsValue和containsKey三个方法,其中contains和containsValue功能相同。
- key和value是否允许null值:其中key和value都是对象,并且不能包含重复key,但可以包含重复的value。Hashtable中,key和value都不允许出现null值。HashMap中,null可以作为键,这样的键只有一个;可以有一个或多个键所对应的值为null。当get()方法返回null值时,可能是 HashMap中没有该键,也可能使该键所对应的值为null。因此,在HashMap中不能由get()方法来判断HashMap中是否存在某个键, 而应该用containsKey()方法来判断。
- 两个遍历方式的内部实现上不同:Hashtable、HashMap都使用了 Iterator。而由于历史原因,Hashtable还使用了Enumeration的方式 。
- hash值不同:哈希值的使用不同,HashTable直接使用对象的hashCode。而HashMap重新计算hash值。
- 内部实现使用的数组初始化和扩容方式不同:Hashtable和HashMap它们两个内部实现方式的数组的初始大小和扩容的方式。HashTable中hash数组默认大小是11,增加的方式是 old*2+1。HashMap中hash数组的默认大小是16,而且一定是2的指数
四,代码练习:
1 import java.util.*; 2 3 public class PropertyDemo { 4 public static void main(String args[]){ 5 6 //声明Properties对象 7 Properties prop=new Properties(); 8 9 //设置两个键值对属性 10 prop.setProperty("lisi", "23"); 11 prop.setProperty("wangwu", "24"); 12 13 14 //输出集合 15 System.out.println(prop); 16 17 System.out.println("======"); 18 19 //获取指定建对应的值 20 String value = prop.getProperty("lisi"); 21 22 //输出值 23 System.out.println(value); 24 25 System.out.println("====="); 26 27 28 //设置键对应的值 29 prop.setProperty("lisi", "60"); 30 31 //获得所有键值的set集合 32 Set<String> set = prop.stringPropertyNames(); 33 34 //输出所有内容 35 for(String s : set){ 36 System.out.println(s+"::"+prop.getProperty(s)); 37 } 38 } 39 }
第十三讲:IO流(Properties存取配置文件)
一,需求分析:将文件中的数据存储到Properties 对象中,改变内容后再将数据写入文件。
二,思路分析:
- 首先应当有输入流与输出流与属性文件info.txt关联。====流的确定:操作文件,内容是字符,高效处理。使用BufferedReader BufferedWriter.====
- 读取一行数据,将改行数据用“="进行分割。
- 等号左边作为键,右边作为值存储到Properties中。
- 修改Properties对象中的内容。
- 将ProPerties对象属性存储到文件中。
三,代码练习:
1 import java.io.*; 2 import java.util.*; 3 4 public class PropertiesDemo { 5 public static void main(String args[]){ 6 7 //声明属性文件对象 8 File file=new File("E:/info.txt"); 9 10 //Properties对象操作属性 11 Properties prop = new Properties(); 12 13 14 try { 15 16 17 //加载属性 18 myLoad2(file,prop); 19 } catch (FileNotFoundException e) { 20 System.out.println("属性文件不存在!"+e.toString()); 21 } catch (IOException e) { 22 System.out.println("文件操作发生异常"); 23 } 24 25 26 //输出加载后的属性 27 System.out.println(prop); 28 29 //改变属性 30 prop.setProperty("lisi", "12"); 31 32 try { 33 //将改变后的属性保存 34 myStore(file,prop,"zhushi"); 35 } catch (FileNotFoundException e) { 36 System.out.println("文件没有找到"+e.toString()); 37 } catch (IOException e) { 38 System.out.println("存储属性发生错误!"+e.toString()); 39 } 40 } 41 42 43 //自定义方法将文件数据保存到Properties对象中 44 public static void myLoad(File file,Properties prop) throws FileNotFoundException ,IOException{ 45 46 //定义缓冲流操作文件 47 BufferedReader br = new BufferedReader(new FileReader(file)); 48 49 //接受读入的一行数据 50 String line=null; 51 52 //循环读取内容,并进行判断设置 53 while((line=br.readLine())!=null){ 54 55 //判断是否是注释 56 if(line.startsWith("#")) 57 //是注释跳过,进行下一次读取 58 continue; 59 60 //不是注释,将内容分割 61 String[] info=line.split("="); 62 63 //将属性设置到Properties对象中 64 prop.setProperty(info[0], info[1]); 65 } 66 67 //关闭输入流 68 br.close(); 69 } 70 71 72 73 //使用Properties自带的方法将属性文件内容设置到对象中 74 public static void myLoad2(File file,Properties prop) throws FileNotFoundException,IOException{ 75 76 //缓冲流 77 BufferedReader br = new BufferedReader(new FileReader(file)); 78 79 //此方法可以自动将注释忽略掉 80 prop.load(br); 81 82 br.close(); 83 } 84 85 86 87 //声明方法将Properties存储到文件中 88 public static void myStore(File file,Properties prop,String comm)throws FileNotFoundException,IOException{ 89 90 //缓冲输出流关联文件 91 BufferedWriter bw=new BufferedWriter(new FileWriter(file)); 92 93 //调用Properties自带方法保存属性到文件中 94 prop.store(bw, comm); bw.close(); 95 } 96 }
第一十四讲:IO流(Properties练习)
一,练习目标:用于记录应用程序运行次数,如果使用次数已到,那么给出注册提示。
二,思路:很容易想到是计数器,可是计数器是存在于内存中的随着程序的结束而消失,那么应当将计数器保存在文件中,下次启动程序时自动加载该值,并加一后重新保存。
三,代码练习:
1 import java.util.*; 2 import java.io.*; 3 4 public class RunCount{ 5 6 public static void main(String[] args)throws IOException{ 7 8 //获得配置文件中的数据 9 int count=runCount(); 10 11 //判断程序运行次数 12 if(count>5) { 13 14 //给出注册提示 15 System.out.println("请注册!"); 16 return ; 17 } 18 else 19 //给出运行提示 20 System.out.println("程序第"+count+"次运行"); 21 } 22 23 24 25 //获取程序运行的次数 26 public static int runCount()throws IOException{ 27 28 //创建集合对象保存属性 29 Properties ps=new Properties(); 30 31 //定义属性文件对象 32 File file=new File("info.ini"); 33 34 //判断文件是否存在 35 if(!file.exists()) 36 file.createNewFile(); 37 38 //创建读取流读取文件内容 39 FileReader fr=new FileReader(file); 40 41 //加载流中的文件数据到集合中 42 ps.load(fr); 43 44 //定义变量表示计数器 45 int count=0; 46 47 //获得计数器的初值 48 String value=ps.getProperty("time"); 49 50 51 //判断value是否为空 52 if(value!=null) 53 { 54 //将String转换为int 55 count=Integer.parseInt(value); 56 } 57 58 //计数器加一 59 count++; 60 61 62 //将次数记录住集合 63 ps.setProperty("time",count+""); 64 65 //声明写入流对象 66 FileWriter fw=new FileWriter(file); 67 68 //保存数据 69 ps.store(fw,""); 70 71 //关闭流 72 fr.close(); 73 fw.close(); 74 75 76 //将计数器返回 77 return count; 78 } 79 }
第一十五讲:IO流(PrintWriter)
一,IO包中的其他类---打印流:
- 打印流:PrintWriter(字节打印流) 与 PrintStream(自负打印流) :可直接操作输入流和文件。该流提供了打印方法,可将各种类型的数据都原样打印。
- PrintStream 类的构造方法可以接受的参数类型。
- File对象。----File
- 字符串表示的路径。----String
- 字节输出流。----OutputStream
- PrintWriter 类的构造方法可以接收的参数类型。
- File对象。----File
- 字符串表示的路径。----String
- 字节输出流。----OutputStream
- 自负输出流。----Writer
二,代码练习:
1 import java.io.*; 2 3 public class PrintStreamDemo{ 4 5 6 public static void main(String[] args) throws IOException{ 7 8 9 //缓冲流接受键盘录入 10 BufferedReader bufr = 11 new BufferedReader(new InputStreamReader(System.in)); 12 13 //打印流关联文件,自动刷新 14 PrintWriter out = new PrintWriter(new FileWriter("E:/test.txt"),true); 15 16 String line = null; 17 18 19 //循环接受键盘录入 20 while((line=bufr.readLine())!=null) 21 { 22 23 //判断是否结束 24 if("over".equals(line)) 25 break; 26 27 //将数据打印到文件中 28 out.println(line); 29 } 30 31 32 //关闭流操作 33 out.close(); 34 bufr.close(); 35 36 } 37 }
第一十六讲:IO流(合并流)
一,合并流SequenceInputStream的了解:
- 类的定义:public class SequenceInputStreamextends InputStream
SequenceInputStream
表示其他输入流的逻辑串联。它从输入流的有序集合开始,并从第一个输入流开始读取,直到到达文件末尾,接着从第二个输入流读取,依次类推,直到到达包含的最后一个输入流的文件末尾为止。 - 构造方法:public SequenceInputStream(Enumeration<? extends InputStream> e) 通过记住参数来初始化新创建的
SequenceInputStream
,该参数必须是生成运行时类型为InputStream
对象的Enumeration
型参数。将按顺序读取由该枚举生成的输入流,以提供从此SequenceInputStream
读取的字节。在用尽枚举中的每个输入流之后,将通过调用该流的close
方法将其关闭。 - 构造方法:public SequenceInputStream(InputStream s1,InputStream s2) 通过记住这两个参数来初始化新创建的
SequenceInputStream
(将按顺序读取这两个参数,先读取s1
,然后读取s2
),以提供从此SequenceInputStream
读取的字节。
- 类的定义:public class SequenceInputStreamextends InputStream
二,合并流使用的步骤:
- 创建集合,并将流对象添加进集合。 ====Vector<InputStream> ve=new Vector<InputStream>();======
- 创建Enumeration对象,将集合元素加入。 ====== Enumeration<InputStream> en=ve.elements();==========
- 创建SequenceInputStream对象,合并流对象。=======SequenceInputStream sis=new SequenceInputStream(en);========
- 创建写入流对象,FileOutputStream关联写入文件。=======FileOutputStream fos=new FileOutputStream("4.txt");=======
- 利用SequenceInputStream对象和FileOutputStream对象读数据进行反复读写操作。
三,代码练习:
1 import java.util.*; 2 import java.io.*; 3 4 class SequenceInputStreamDemo{ 5 6 public static void main(String[] args)throws IOException{ 7 8 //第一步,创建集合 9 Vector<InputStream> ve=new Vector<InputStream 10 11 //向集合中添加数据 12 ve.add(new FileInputStream("1.txt")); 13 ve.add(new FileInputStream("2.txt")); 14 ve.add(new FileInputStream("3.txt")); 15 16 17 //创建枚举对象 18 Enumeration<InputStream> en=ve.elements(); 19 20 //创建合并流,并将枚举对象传入 21 SequenceInputStream sis=new SequenceInputStream(en); 22 23 //创建输出流,与文件相关联 24 FileOutputStream fos=new FileOutputStream("4.txt"); 25 26 27 28 //接收读入的数据 29 byte[] buf=new byte[1024]; 30 //标记读入的个数 31 int len=0; 32 33 //循环读取 34 while((len=sis.read(buf))!=-1){ 35 //写入文件 36 fos.write(buf,0,len); 37 } 38 39 //关闭流 40 fos.close(); 41 sis.close(); 42 } 43 }