IO流之二

-------android培训java培训、期待与您交流! ---------- 
File类:
        专门用于描述系统中文件或者文件夹的对象。 
可以用于操作文件或者文件夹的属性信息。
        File对象可以作为参数传递给流的构造函数。
File类中常用方法:
1,获取文件信息。
获取名称,getName();
获取路径,getPath();  getAbsolutePath();  getParent();
获取大小。length();
获取时间。lastModified();
...
2,判断,如
是否只读?
是否隐藏?

3,文件的创建和删除以及该文件是否存在,文件对象自己最清楚。
    创建  file.createNewFile();如果文件不存在,就创建。如果文件存在,就不创建。输出流流会覆盖,如果不覆盖,                                                需要在构造函数中加入true参数。续写。
    删除  file.delete();文件的删除是从里到外进行逐层删除的。
   是否存在  file.exists();
注意:File中构造时,指定的路径可以是存在的也可以是不存在的。
常用方法演示:
import java.io.File;
import java.text.DateFormat;
import java.util.Date;

public class FileDemo {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		File file = new File("src\\day04\\tempfile\\file.txt");
		System.out.println(file.length());//获取文件的大小,单位是字节
//		System.out.println(file.lastModified());//获取文件最后修改的时间,结果是毫秒值
		
		//为了知道具体的时间,需要将time毫秒值转成Date对象,然后对Date对象进行格式化
		Date date = new Date(file.lastModified());
		DateFormat dateFormat = DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.LONG);
		String str_time = dateFormat.format(date);
		System.out.println(str_time);
		
		System.out.println(file.getAbsolutePath());//获取绝对路径  H:\JAVA\lianxi\JAVA Review\Review\src\day04\tempfile\file.txt
		System.out.println(file.getName());//获取文件名  file.txt
		System.out.println(file.getParent());//获取父目录  src\day04\tempfile
		System.out.println(file.getPath());//获取相对路径  src\day04\tempfile\file.txt
	}

}

过滤器:是一个接口
    1,文件过滤器。FileFilter
    2,文件名过滤器。FilenameFilter
过滤器的原理:list(FilenameFilter filter)
    1,首先获取到给定目录下的所有内容。
    2,对这些内容进行遍历,在遍历过程中加入条件:accept(dir,name);
    3,凡是符合条件的accept返回true,就将这些符合条件的内容进行存储。
    4,将存储的内容返回,这样就得到了过滤后的内容。
过滤器方法演示:
public class FilterDemo {
	public static void main(String[] args) {
		filterMethod();
	}
	public static void filterMethod() {
		File file = new File("src\\IO\\tempfile");
		/*
		//列出指定目录下的文件
		String[] names = file.list();
		for(String name : names)
			System.out.println(name);
		*/
		/*
		//列出指定目录下后缀名是.mp3的文件
		String[] names = file.list(new filterByHouZhuiMing()) ;
		for(String name : names)
			System.out.println(name);
		*/
			
		//列出后缀名是用户自己写的的文件,就是任意文件
		String[] names = file.list(new filterBySuffix(".txt")) ;
		for(String name : names)
			System.out.println(name);
	}
}
public class filterBySuffix implements FilenameFilter {
	private String suffix ;
	public filterBySuffix(String suffix) {
		super();
		this.suffix = suffix;
	}
	public boolean accept(File dir, String name) {
		return name.endsWith(suffix);
	}
}
public class filterByHouZhuiMing implements FilenameFilter {
	public boolean accept(File dir, String name) {
		return name.endsWith(".mp3");
	}
}

递归:函数自身调用自身(直接或者间接)。
    1,一定要有条件。否则就是StakOverflowError,栈内存溢出
    2,一定要注意递归次数。次数过多一样StakOverflowError
递归的应用场景:当某一功能要重复使用时。
递归代码演示:以删除一个带内容的文件夹为例:
public class FileTest {
	public static void main(String[] args) {
		File dir = new File("e:\\demodir");	
		removeDir(dir);
	}	
	public static void removeDir(File dir){		
		File[] files = dir.listFiles();
		for(File file : files){
			if(file.isDirectory()){
				removeDir(file);				
			}else{
				System.out.println(file+":"+file.delete());
			}			
		}
		System.out.println(dir+":"+dir.delete());
	}

}
注意:递归时一定要明确结束条件。
 
Properties集合:
    1, Map接口中Hashtable的子类。
    2, 该类上没有泛型定义,因为它的键值都是固定的字符串类型。
    3, 因为存储都是字符串数据,通常都作为属性信息存在。
    4, 该集合最大的特点就是可以和IO技术相结合。也就是,该集合中的数据可以来自于流。也可以将集合中的数据写入到流中。

  Propperties集合中一般存储的元素是键值对的形式,因为它是Map的子类。
Properties基本方法演示:
public class PropertiesDemo {
	public static void main(String[] args) throws IOException {
//		methodDemo_1();
//		methodDemo_2();
		methodDemo_3();
//		loadPrinciple();
	}
	/**
	 * load方法演示
	 */
	public static void methodDemo_3() throws IOException {
		Properties prop = new Properties();
		FileInputStream fis = new FileInputStream("src\\IO\\tempfile\\info_1.properties");
		//将流中的数据加载到集合中去
		prop.load(fis);
		
		//想要对数据进行修改,通过map集合中新值覆盖旧值的方法
		prop.setProperty("wangwu", "20");
		//想要将修改的数据保存到文件中,需要输出流,创建文件覆盖旧文件
		//要用到store方法
		FileOutputStream fos = new FileOutputStream("src\\IO\\tempfile\\info_1.properties");
		prop.store(fos, "wangwu=27-->wangwu=20");//注意引号只能写入字符串,不可以写中文
		
		fos.close();
		fis.close();
		prop.list(System.out);
	}
	/**
	 * load方法原理演示
	 */
	public static void loadPrinciple() throws IOException{
		Properties prop = new Properties();
		BufferedReader bufr = new BufferedReader(new FileReader("src\\IO\\tempfile\\info_1.properties"));
		String line = null ;
		while((line=bufr.readLine())!=null){
			String[] strs = line.split("=");
			prop.setProperty(strs[0], strs[1]);
		}
		bufr.close();
		prop.list(System.out);
	}
	
	/**
	 * 演示和IO流相结合的方法
	 */
	public static void methodDemo_2() {
		Properties prop = new Properties();
		prop.setProperty("zhagnsan", "23");
		prop.setProperty("qianyi", "25");
		prop.setProperty("lisi", "21");
//		prop.setProperty("zhaoliu", "24");
		prop.list(System.out);//一把用于调试。
	}
	/**
	 * 基本方法演示
	 */
	public static void methodDemo_1() {
		//创建集合
		Properties prop = new Properties();
		//添加元素
		prop.setProperty("zhagnsan", "23");
		prop.setProperty("qianyi", "25");
		prop.setProperty("lisi", "21");
		prop.setProperty("zhaoliu", "24");	
		//取出元素
		Set<String> nameSet = prop.stringPropertyNames();
		for(String name : nameSet){
			String value = prop.getProperty(name);
			System.out.println(name+":::"+value);
		}		
	}
}
Properties中还有一个方法对调试很有用,它就是list方法。

 

 打印流:PrintStream,PrintWriter
     1,使他们能够方便地打印各种数据值表现形式。
     2,提供了一系列的打印功能,可以打印任何数据。
     3,他的特有方法不抛出异常。
构造方法:
     该流是一个处理目的的流对象。

PrintWriter:可以自动刷新和换行,不过启动自动刷新就必须使用println方法
打印流目的:
     1,file对象。可以指定字符集。File
     2,字符串路径。可以指定字符集。String
     3,字节输出流。OutputStream
     4,字符输出流。Writer

PrintStream中有write和print两个方法,它们的区别通过下面代码来演示:

public static void printDemo(){
	PrintStream out = new PrintStream("tempfile\\print_print.txt");
	//使用PrintStream继承的方法。write。
	out.write(97); //write将接收到整数的最后一个字节写入到流。所以打印的是a		
	//使用PrintStream的特有方法。print.
	out.print(97);//print方法,可以将参数的数据表现形式打印到目的中。原理是将97转成字符串,在write到目的。 
	//print方法打印各种数据都会将其变成字符串。所以可以保证数据的原有表现形式。
}


序列流:SequenceInputStream

    序列流可以把多个流对象串联成一个流对象。

    它的好处:就是将多个数据源变成一个数据源,这样操作起来很方便。

    构造方法:   

    SequenceInputStream(Enumeration<? extends InputStream> e):

            通过记住参数来初始化新创建的SequenceInputStream,该参数必须是生成运行时类型为 InputStream 对象的 Enumeration 型参数。

    SequenceInputStream(InputStream s1, InputStream s2):

        通过记住这两个参数来初始化新创建的 SequenceInputStream(将按顺序读取这两个参数,先读取 s1,然后读取 s2),以提供从此 SequenceInputStream 读取的字节。

   
因为是多个流对象进行合并,就要先将多个流对象存储到集合中去,由于序列流是从JDK1.0开始的,而那时的单列集合只有Vector,也就需要用到枚举对象。

代码演示:

public static void demoMethod() throws IOException {
	//创建多个流对象
	FileInputStream fis1 = new FileInputStream("src\\IO\\tempfile\\Sequence\\seq_1");
	FileInputStream fis2 = new FileInputStream("src\\IO\\tempfile\\Sequence\\seq_2");
	FileInputStream fis3 = new FileInputStream("src\\IO\\tempfile\\Sequence\\seq_3");
	//创建集合用于存储多个流对象
	//需要枚举对象,而具备枚举对象的集合石Vector
	Vector<FileInputStream> vector = new Vector<FileInputStream>();
	vector.add(fis1);
	vector.add(fis2);
	vector.add(fis3);
	//获取集合中的元素
	Enumeration<FileInputStream> enumeration = vector.elements();
	
	SequenceInputStream sis = new SequenceInputStream(enumeration);
	//创建目的
//		FileOutputStream fos = new FileOutputStream("src\\IO\\tempfile\\Sequence\\seq_4.txt");
	BufferedOutputStream bufos = 
			new BufferedOutputStream(new FileOutputStream("src\\IO\\tempfile\\Sequence\\seq_4"));
	byte[] buf = new byte[1024];
	int len = 0 ;
	while((len=sis.read(buf))!=-1){
		bufos.write(buf,0,len);
	}
	bufos.close();
	sis.close();
}


对象序列化:ObjectInputStream,ObjectOutputStream

    1,操作对象的流,其实就是把对象流化,序列化。就是把对象按照流的方式写入文件中,

    2,基本的读写对象操作
注意:
    对象能够被序列化必须实现序列化接口。实现Serializable接口
    最好默认给出序列化接口的序列化id值。

RandomAccessFile:

   1,不是字节流或者字符流体系中的成员。
   2,该类是用于操作File的类。
   3,该对象既可以读取又可以写入。
   4,该对象中封装了一个大型的byte类型的数组。
   5,其实它内部就是封装了字节输入流和字节输出流。
   6,通过seek方法设置数组的指针就可以实现对文件数据的随机读写。
   可以实现数据的修改。注意:被操作的数据一定要有规律。
   注意:如果文件存在,就不创建文件。如果不存在就创建文件。也就是说,不存在覆盖。

示例:

import java.io.IOException;
import java.io.RandomAccessFile;

public class RandomAccessFileDemo {

	/**
	 * @param args
	 * @throws IOException 
	 */
	public static void main(String[] args) throws IOException {	
//		writeFile();
		readFile();
	}

	public static void readFile() throws IOException {
		RandomAccessFile raf = new RandomAccessFile("src\\IO\\tempfile\\random.txt", "r");
//		System.out.println(raf.getFilePointer());//指针指向0,从0开始读取
		raf.seek(8);//将指针设置为从8开始
		byte[] buf = new byte[4];
		raf.read(buf);
		String name = new String(buf);
		int age = raf.readInt();
		System.out.println(name+"::"+age);
		System.out.println(raf.getFilePointer());
		
		raf.close();
	}

	public static void writeFile() throws IOException {
		RandomAccessFile raf = new RandomAccessFile("src\\IO\\tempfile\\random.txt", "rw");
		raf.write("张三".getBytes());
//		raf.write(97);//写入的是字节数
		raf.writeInt(97);//按四个字节将 int 写入该文件,先写高字节
		raf.write("李四".getBytes());
		raf.writeInt(99);
		
		raf.close();
	}

}


RandomAccessFile
    随机访问文件,自身具备读写的方法。
    通过skipBytes(int x),seek(int x)来达到随机访问的效果。

IO包中其他流对象:

    管道流:输入输出可以直接进行连接,通过结合线程使用。
         PipedInputStream和PipedOutputStream
    
操作基本数据类型
         DataInputStream与DataOutputStream
    操作字节数组
         ByteArrayInputStream与ByteArrayOutputStream
    操作字符数组
         CharArrayReader与CharArrayWrite
    操作字符串
         StringReader 与 StringWriter

 

编码:

1,字符串的编码问题
    编码:字符串 -- 字节数组
    解码:字节数组 -- 字符串

2,在IO流中,指定编码的需要使用转换流。

    字符流 = 字节流+编码表

下面三句代码结果是一样的:因为系统默认的编码表就是GBK

OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("a.txt"),"GBK");
OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("a.txt"));
FileWriter fw =  new FileWriter("a.txt");

正常情况下用哪种编码写数据,就用哪种编码读取数据。


 




                                                     -------android培训java培训、期待与您交流! ----------


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值