1.SequenceInputStream序列流:能将其他输入流的串联
用处:读完第一个再去读第二个输入流
用法:构造方法:SequenceInputStream(InputStream s1,InputStream s2):串联2个InputStream还可以,多个就很麻烦;
SequenceInputStream(Enumeration<? extends InputStream> e):Enumation对象需要通过Vector中获取,Vector是一个集合不过因为考虑线程安全效率比较低,他返回的的集合对象就是最初的Enumeration:
例子:将一个歌分成4份;再将4份合拼为1份
/** * 将一个文件切割为4份再将4份合拼为1份 * @author Administrator * */ public class sequenceInputStream { public static void main(String[] args) throws IOException { // TODO Auto-generated method stub //cutFile("C:/1.mp3","C:/mp3"); mergeFile("C:/mp3","C:/hepin.mp3"); } /** * 将文件以2M为一个单位分成多份 * @param pathFrom 被分文件位置 * @param pathTo 分成文件存放文件夹位置 * @throws IOException IO异常 */ public static void cutFile(String pathFrom,String pathTo) throws IOException{ File f=new File(pathFrom); FileInputStream fs=new FileInputStream(f); int length=0; byte[] buffer=new byte[1024*1024*2]; for(int i = 0 ; (length = fs.read(buffer))!=-1 ; i++){ FileOutputStream fos=new FileOutputStream(new File(pathTo,"part"+i+".mp3")); fos.write(buffer, 0, length); fos.close(); } fs.close(); } /** * 将一个文件夹中的多个文件合拼为一个文件 * @param pathFrom 存放多个文件的文件夹位置 * @param pathTo 合拼文件存放位置 * @throws IOException */ public static void mergeFile(String pathFrom,String pathTo) throws IOException{ File f=new File(pathFrom);//找到目标文件夹将其中的所有子文件都放到Vector中变成Enumation集合中去 File[] files=f.listFiles(); Vector<FileInputStream> vector=new Vector<FileInputStream>(); for(File file:files){ FileInputStream fs1=new FileInputStream(file); vector.add(fs1); } Enumeration<FileInputStream> e=vector.elements(); SequenceInputStream sis=new SequenceInputStream(e); FileOutputStream fos=new FileOutputStream(pathTo); int length=0; byte[] buffer=new byte[1024]; while((length=sis.read(buffer))!=-1){ fos.write(buffer,0,length); } fos.close(); sis.close(); } }
2.ObjectInputStream,ObjectionStream对象输入输出流
当我们想要将一个对象存到硬盘中时我们就需要这个东西将对象序列化和反序列化
(一)用法跟其他的流都是一样的
(二)注意:1.对象要想写到文件上,对象所属类必须实现Serialization接口;Serialization接口没有任何的方法,只是一个标识接口;
2.对象反序列化时并不会调用构造方法
3.serializationUID用于记录类的版本信息的,它由一个类的类名,成员,包名,工程名算出来的数字
4.使用ObjectInputStream反序列化时,会先读取文件中的serializationUID,然后与本地的比较,不一样就反序列化失败
5.如果序列化反序列化可能会修改类成员,那么最好一开始就给类指定serializationUID,之后jvm就不会再计算这个值了
6.如果对象的一个成员不想序列化到硬盘上,可以使用关键字transient修饰。
7.一个类维护了另一个类,那么另一个类也需要实现Serialization
(三)例子:
class Address implements Serializable{ String country; String city; public Address(String country,String city){ this.country = country; this.city = city; } } class User implements Serializable{ private static final long serialVersionUID = 1L; String userName ; String password; transient int age; // transient 透明 Address address ; public User(String userName , String passwrod) { this.userName = userName; this.password = passwrod; } public User(String userName , String passwrod,int age,Address address) { this.userName = userName; this.password = passwrod; this.age = age; this.address = address; } @Override public String toString() { return "用户名:"+this.userName+ " 密码:"+ this.password+" 年龄:"+this.age+" 地址:"+this.address.city; } } public class Demo3 { public static void main(String[] args) throws IOException, Exception { writeObj(); // readObj(); } //把文件中的对象信息读取出来-------->对象的反序列化 public static void readObj() throws IOException, ClassNotFoundException{ //找到目标文件 File file = new File("F:\obj.txt"); //建立数据的输入通道 FileInputStream fileInputStream = new FileInputStream(file); //建立对象的输入流对象 ObjectInputStream objectInputStream = new ObjectInputStream(fileInputStream); //读取对象信息 User user = (User) objectInputStream.readObject(); //创建对象肯定要依赖对象所属 的class文件。 System.out.println("对象的信息:"+ user); } //定义方法把对象的信息写到硬盘上------>对象的序列化。 public static void writeObj() throws IOException{ //把user对象的信息持久化存储。 Address address = new Address("中国","广州"); User user = new User("admin","123",15,address); //找到目标文件 File file = new File("F:\obj.txt"); //建立数据输出流对象 FileOutputStream fileOutputStream = new FileOutputStream(file); //建立对象的输出流对象 ObjectOutputStream objectOutputStream = new ObjectOutputStream(fileOutputStream); //把对象写出 objectOutputStream.writeObject(user); //关闭资源 objectOutputStream.close(); } }
3.Properties配置文件类
(一)用于生产和读取配置文件的
(二)注意:1.配置文件中使用中文在用store方法生成配置文件时只能用字符流,如果用字节流生成配置文件默认用的是iso885ma才可以
2.如果配置文件内容发生变化,需要重新生成配置文件
(三)例子:
基本用法在里面:
public class Demo4 { public static void main(String[] args) throws IOException { creatProperties(); // readProperties(); } //读取配置文件爱你的信息 public static void readProperties() throws IOException{ //创建Properties对象 Properties properties = new Properties(); //加载配置文件信息到Properties中 properties.load(new FileReader("F:\persons.properties")); //遍历 Set<Entry<Object, Object>> entrys = properties.entrySet(); for(Entry<Object, Object> entry :entrys){ System.out.println("键:"+ entry.getKey() +" 值:"+ entry.getValue()); } //修改狗娃的密码 //把修改后的Properties再生成一个配置文件 properties.setProperty("狗娃", "007"); properties.store(new FileWriter("F:\persons.properties"), "hehe"); } //保存配置文件文件的信息。 public static void creatProperties() throws IOException{ //创建Properties Properties properties = new Properties(); properties.setProperty("狗娃", "123"); properties.setProperty("狗剩","234"); properties.setProperty("铁蛋","345"); // 遍历Properties /*Set<Entry<Object, Object>> entrys = properties.entrySet(); for(Entry<Object, Object> entry :entrys){ System.out.println("键:"+ entry.getKey() +" 值:"+ entry.getValue()); }*/ //使用Properties生产配置文件。 //properties.store(new FileOutputStream("F:\persons.properties"), "haha"); //第一个参数是一个输出流对象,第二参数是使用一个字符串描述这个配置文件的信息。 properties.store(new FileWriter("F:\persons.properties"), "hehe"); } }
使用properties实现本软件只能 运行三次,超过了三次之后就提示购买正版,退jvm.
public class Demo5 { public static void main(String[] args) throws IOException { File file = new File("F:\count.properties"); if(!file.exists()){ //如果配置文件不存在,则创建该配置文件 file.createNewFile(); } //创建Properties对象。 Properties properties = new Properties(); //把配置文件的信息加载到properties中 properties.load(new FileInputStream(file)); FileOutputStream fileOutputStream = new FileOutputStream(file); int count = 0; //定义该变量是用于保存软件的运行次数的。 //读取配置文件的运行次数 String value = properties.getProperty("count"); if(value!=null){ count = Integer.parseInt(value); } //判断使用的次数是否已经达到了三次, if(count==3){ System.out.println("你已经超出了试用次数,请购买正版软件!!"); System.exit(0); } count++; System.out.println("你已经使用了本软件第"+count+"次"); properties.setProperty("count",count+""); //使用Properties生成一个配置文件 properties.store(fileOutputStream,"runtime"); } }
4.printStream打印流
(一)可以打印任意类型的数据而且打印之前会先变成字符串再打印
(二)设置标准默认输出流输入流
System.in;System.out都是可以设置流对象的一般指向printStream流对象
(三)例子:
class Animal{ String name; String color; public Animal(String name,String color){ this.name = name; this.color = color; } @Override public String toString() { return "名字:"+this.name+ " 颜色:"+ this.color; } } public class Demo6 { public static void main(String[] args) throws IOException { /*FileOutputStream fileOutputStream = new FileOutputStream("F:\a.txt"); fileOutputStream.write("97".getBytes()); fileOutputStream.close();*/ //打印流可以打印任何类型的数据,而且打印数据之前都会先把数据转换成字符串再进行打印。 File file = new File("F:\a.txt"); //创建一个打印流 PrintStream printStream = new PrintStream(file); /* printStream.println(97); printStream.println(3.14); printStream.println('a'); printStream.println(true); Animal a = new Animal("老鼠", "黑色"); printStream.println(a); //默认标准的输出流就是向控制台输出的, System.setOut(printStream); //重新设置了标准的输出流对象 System.out.println("哈哈,猜猜我在哪里!!"); */ //收集异常的日志信息。 File logFile = new File("F:\2015年1月8日.log"); PrintStream logPrintStream = new PrintStream( new FileOutputStream(logFile,true) ); try{ int c = 4/0; System.out.println("c="+c); int[] arr = null; System.out.println(arr.length); }catch(Exception e){ e.printStackTrace(logPrintStream); } } }
5.编码解码
byte[] buf = str.getBytes(); //使用gbk进行编码
str = new String(buf,"iso8859-1");//解码
6. 转换流:
(一)分类:
输入字节流的转换流:InputStreamReader 是字节流通向字符流的桥
输出字节流的转换流:OutputStreamWriter 可以把输出字节流转换成输出字符流 。
(二)注意:
转换时可以设置编码表读写文件
(三)用法:
//创建字节流的转换流并且指定码表进行读取
InputStreamReader inputStreamReader = new InputStreamReader(fileInputStream,"utf-8");
7.递归
例子:
a.列出一个文件夹的子孙文件与目录。
b.列出指定目录中所有的子孙文件与子孙目录名,要求名称前面要有相应数量的空格:
第一级前面有0个,第二级前面有1个,第三级前面有2个...,以此类推。
c.列出指定目录中所有的子孙文件与子孙目录名,要求要是树状结构,效果如下所示:
|--src
| |--cn
| | |--itcast
| | | |--a_helloworld
| | | | |--HelloWorld.java
| | | |--b_for
| | | | |--ForTest.java
| | | |--c_api
| | | | |--Student.java
|--bin
| |--cn
| | |--itcast
| | | |--i_exception
| | | | |--ExceptionTest.class
| | | |--h_linecount
| | | | |--LineCounter3.class
| | | | |--LineCounter2.class
| | | | |--LineCounter.class
|--lib
| |--commons-io.jar
d: 删除一个非空的文件夹。
*/
public class Demo10 { public static void main(String[] args) { /* File dir = new File("F:\1208project\day22"); listFiles3(dir,"|--");*/ File dir = new File("F:\aa"); deleteDir(dir); } //删除了一个非空的目录 public static void deleteDir(File dir){ // bb File[] files = dir.listFiles(); //列出了所有的子文件 for(File file : files){ if(file.isFile()){ file.delete(); }else if(file.isDirectory()){ deleteDir(file); } } dir.delete(); } public static void listFiles3(File dir,String space){ //space 存储的是空格 File[] files = dir.listFiles(); //列出所有 的子文件 for(File file : files){ if(file.isFile()){ System.out.println(space+file.getName()); }else if(file.isDirectory()){ System.out.println(space+file.getName()); listFiles3(file,"| "+space); } } } //列出一个文件夹的子孙文件与目录。 public static void listFiles2(File dir,String space){ //space 存储的是空格 File[] files = dir.listFiles(); //列出所有 的子文件 for(File file : files){ if(file.isFile()){ System.out.println(space+file.getName()); }else if(file.isDirectory()){ System.out.println(space+file.getName()); listFiles2(file," "+space); } } } //列出一个文件夹的子孙文件与目录。 public static void listFiles1(File dir){ File[] files = dir.listFiles(); //列出所有 的子文件 for(File file : files){ if(file.isFile()){ System.out.println("文件名:"+file.getName()); }else if(file.isDirectory()){ System.out.println("文件夹:"+file.getName()); listFiles1(file); } } } }