IO之文件,Properties集合的存取,其他类

一、文件

File类:用来将文件或者文件夹封装成对象,方便对文件与文件夹的属性信息进行操作。File对象可以作为参数传递给流的构造函数。
  在Java中,将目录(directory, 文件夹)也当作文件处理
  File类方法
  1)文件/目录名操作
  String getName(), String getPath(), String getAbsolutePath(),String getParent(), boolean renameTo(File new Name)
  2)获取常规文件信息操作
  long lastModified(), long length(), boolean delete()
  3)File测试操作
  boolean exists(), boolean canWrite(), boolean canRead(), boolean isFile(), boolean isDirectory(), boolean isAbsolute()
  4) 目录操作
  boolean mkdir(), String[] list()

import java.io.File;
import java.text.DateFormat;
import java.util.Date;
import java.io.IOException;
public class FileDemo {
	public static void main(String[] args){
		constructorDemo();
		try {
			FileMethodDemo();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	public static void constructorDemo(){
		//可以将一个已存在的或不存在的文件或目录封装成file对象
		File f1 = new File("a.txt");
		File f2 = new File("d:\\a.txt");
		File f = new File("d:\\a.txt");
		File f3 = new File(f,"a.txt");
		File f4 = new File("d:"+File.separator+"a.txt");
	}
	public static void FileMethodDemo() throws IOException{
		File file1 = new File("file.txt");
		File file2 = new File("d:\\file.txt");
		//获取
		System.out.println("name:"+file2.getName());
		System.out.println("path1:"+file1.getPath());
		System.out.println("absPath:"+file1.getAbsolutePath());
		System.out.println("len:"+file2.length());	
		System.out.println("parent1:"+file1.getParent());
		System.out.println("parent2:"+file2.getParent());
		long time = file2.lastModified();
		Date date = new Date(time);
		DateFormat df = DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.LONG);
		String str_time = df.format(date);
		System.out.println("str_time:"+str_time);
		//创建和删除
		boolean b1 = file1.createNewFile();
		System.out.println("b1 = "+b1);
		boolean b2 = file1.delete();
		System.out.println("b2 = "+b2);
		File dir = new File("ab/cd/ef");
		boolean b3 = dir.mkdir(); //创建多级目录
		System.out.println("b3 = "+b3);
		boolean b4 = dir.delete(); //删除最里层目录
		System.out.println("b4 = "+b4);
		//判断
		if(!file1.exists())
			file1.createNewFile();
		if(file1.exists()){
			System.out.println(file1.isFile());
			System.out.println(file1.isDirectory());
		}
		dir.mkdirs();
		if(dir.exists()){
			System.out.println(dir.isFile());
			System.out.println(dir.isDirectory());
		}
		//重命名
		file1.renameTo(file2);
		System.out.println(file1.getName());
		//系统根目录和容量获取
		File[] files = File.listRoots();
		for (File file: files){
			System.out.println(file);
		}
		File file = new File("User/");
		System.out.println(file.getFreeSpace());
		System.out.println(file.getTotalSpace());
		System.out.println(file.getUsableSpace());
	}
}
/*
 * 获取d盘目录下后缀名为".java"的文件
 */
import java.io.File;
import java.io.FilenameFilter;
public class FileListDemo {
	public static void main(String[] args){
		listDemo();
	}
	public static void listDemo(){
		File dir = new File("d:\\");
		String[] names = dir.list(new SuffixFilter(".java"));
		for(String name: names){
			System.out.println(name);
		}
	}
}
class SuffixFilter implements FilenameFilter{
	private String suffix;
	public SuffixFilter(String suffix){
		super();
		this.suffix = suffix;
	}
	public boolean accept(File dir, String name){
		return name.endsWith(suffix);
	}
}
/*
 * 获取c盘目录下的隐藏文件。
 */
import java.io.File;
import java.io.FilenameFilter;
public class FileListDemo2 {
	public static void main(String[] args){
		listDemo();
	}
	public static void listDemo(){
		File dir = new File("c:\\");
		File[] files = dir.listFiles(new FilterByHidden());
		for(File file: files){
			System.out.println(file);
		}
	}	
}
class FilterByHidden implements FilenameFilter{
	public boolean accept(File dir, String name){
		return dir.isHidden();
	}
}

二、Properties集合的存和取

特点:
  Properties集合中的键和值都是字符串类型。
  集合中的数据可以保存到流中,或者从流中获取。
  通常该集合用于操作以键值对形式存在的配置文件。

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.FileWriter;
import java.util.Properties;
public class PropertiesDemo {
	public static void main(String[] args) throws Exception{
		propertiesDemo();
	}
	public static void propertiesDemo() throws Exception{
		Properties prop = new Properties();
		prop.setProperty("Susan","10");
		prop.setProperty("Penny","20");
		prop.setProperty("Jessica","30");
		prop.setProperty("Jennifer", "40");
		//关联输出流,将集合中的字符串键值存储到文件中
		FileOutputStream fos = new FileOutputStream("info.txt");
		//将集合中数据存储到文件中
		prop.store(fos, "name+age");
		fos.close();
		//使用读取流,取出保存在txt文件中的键值对数据
		FileInputStream fis = new FileInputStream("info.txt");
		prop.load(fis);
		prop.list(System.out);
		test();
		myLoad();
	}
	//对已有的配置文件中的信息进行修改
	public static void test() throws Exception{
		//读取这个文件
		File file = new File("info.txt");
		if(!file.exists()){
			file.createNewFile();
		}
		FileReader fr = new FileReader("info.txt");
		//创建集合存储配置信息
		Properties prop = new Properties();
		//将流中信息存储到集合中
		prop.load(fr);
		prop.setProperty("Luna", "23");
		FileWriter fw = new FileWriter(file);
		prop.store(fw, "");
		fr.close();
	}
	//模拟load方法
	public static void myLoad() throws Exception{
		Properties prop = new Properties();
		BufferedReader bufr = new BufferedReader(new FileReader("info.txt"));
		String line = null;
		while((line = bufr.readLine()) != null){
			if(line.startsWith("#"))
				continue;
			String[] arr = line.split("=");
			prop.setProperty(arr[0],arr[1]);
		}
		prop.list(System.out);
		bufr.close();
	}
}
/*
 * 获取一个应用程序运行的次数,如果超过5次,给出使用次数已到请注册的提示,并不要再运行程序。
 * 分析:程序启动时,应该先读取这个用于记录计数器信息的配置文件。 
 * 获取上一次计数器次数。并进行使用次数的判断。 
 */
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Properties;
public class Test1 {
	public static void main(String[] args) throws IOException{
		getAppCount();
	}
	public static void getAppCount() throws IOException{
		//将配置文件封装成File对象
		File confile = new File("count.properties");
		if(!confile.exists())
			confile.createNewFile();
		FileInputStream fis = new FileInputStream(confile);
		Properties prop = new Properties();
		prop.load(fis);
		//从集合中通过键获取次数
		String value = prop.getProperty("time");
		//定义计数器,记录获取到的次数
		int count = 0;
		if(value !=  null){
			count = Integer.parseInt(value);
			if(count >= 5){
				throw new RuntimeException("The times are used up. Pls register!");
			}
		}
		count++;
		//将改变后的次数重新存储到集合中
		prop.setProperty("time",count+"");
		FileOutputStream fos = new FileOutputStream(confile);
		prop.store(fos, "");
		fos.close();
		fis.close();
	}
}
/*
 * 获取指定目录下,指定扩展名的文件(包含子目录中的),并且将这些文件的绝对路径写入到
 * 一个文本文件中。
 */
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.FilenameFilter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
public class Test2 {
	public static void main(String[] args) throws IOException{
		File dir = new File("d:\\");
		FilenameFilter filter = new FilenameFilter(){
			public boolean accept(File dir, String name){
				return name.endsWith("java");
			}
		};
		List<File> list = new ArrayList<File>();
		getFiles(dir, filter, list);
		File destFile = new File(dir, "javalist.txt");
		write2File(list,destFile);
	}
	//对指定目录中的内容进行深度遍历,并按照指定过滤器进行过滤并存储到List中
	public static void getFiles(File dir, FilenameFilter filter, 
			List<File> list){
		File[] files = dir.listFiles();
		//递归
		for(File file: files){
			if (file.isDirectory()){
				getFiles(file,filter,list);
			}else{
				//对遍历到的文件进行过滤,将符合条件的File对象存储到List集合中
				if(filter.accept(dir, file.getName())){
					list.add(file);
				}
			}
		}
	}
	public static void write2File(List<File> list, File destFile) throws
			IOException{
		BufferedWriter bufw = null;
		try{
			bufw = new BufferedWriter(new FileWriter(destFile));
			for(File file: list){
				bufw.write(file.getAbsolutePath());
				bufw.newLine();
				bufw.flush();
			}
		}finally{
			if(bufw != null)
				try{
					bufw.close();
				}catch(IOException e){
					throw new RuntimeException("Failed close");
				}
		}
	}
}

三、IO包中的其他类

1.打印流

PrintWriter与PrintStream:可以直接操作输入流和文件。
  PrintStream为其他输出流添加了功能,使它们能够方便地打印各种数据值表示形式。与其他输出流不同,PrintStream永远不会抛出IOException。 PrintStream打印的所有字符都使用平台的默认字符编码转换为字节。 在需要写入字符而不是写入字节的情况下,应该使用PrintWriter类。

PrintStream:
  1) 提供了打印方法可以对多种数据类型值进行打印,并保持数据的表示形式
  2.)它不抛IOException
  构造函数,接收三种类型的值: a. 字符串路径 b. File对象 c. 字节输出流

import java.io.PrintStream;
public class PrintStreamDemo {
	public static void main(String[] args) throws Exception{
		PrintStream out = new PrintStream("print.txt");
		//write(int b)方法只写最低8位
		out.write(97); //a
		//print方法先将79转换成字符串保存,再原样打印到目的地
		out.print(97); //97
		out.close();
	}
}

PrintWriter:字符打印流
  构造函数参数: a. 字符串路径 b. File对象 c. 字节输出流 d. 字符输出流

import java.io.BufferedReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
public class PrintWriterDemo {
	public static void main(String[] args) throws IOException{
		BufferedReader bufr = new BufferedReader(new InputStreamReader(System.in));
		//PrintWriter构造函数的第二个参数设置为true,表示自动刷新
		PrintWriter out = new PrintWriter(new FileWriter("out.txt"),true);
		String line = null;
		while((line = bufr.readLine()) != null){
			if("over".equals(line))
				break;
			out.println(line.toUpperCase());
			out.flush();
		}
		out.close();
		bufr.close();
	}
}

2.序列流

SequenceInputStream:对多个流进行合并。

/*
* 示例:将1.txt、2.txt、3、txt文件中的数据合并到一个文件中。
*/
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.SequenceInputStream;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Enumeration;
import java.util.Iterator;
public class SequenceInputStreamDemo {
	public static void main(String[] args) throws Exception{
		ArrayList<FileInputStream> al = new ArrayList<FileInputStream>();
		for(int x = 1; x <= 3; x++){
			al.add(new FileInputStream(x+".txt"));
		}
		final Iterator<FileInputStream> it = al.iterator();
		Enumeration<FileInputStream> en = Collections.enumeration(al);
		SequenceInputStream sis = new SequenceInputStream(en);
		FileOutputStream fos = new FileOutputStream("4.txt");
		byte[] buf = new byte[1024];
		int len = 0;
		while((len = sis.read(buf)) != -1){
			fos.write(buf,0,len);
		}
		fos.close();
		sis.close();
	}
}

3.文件切割器

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Properties;
public class SplitFileDemo {
	private static final int SIZE = 1024*1024;
	public static void main(String[] args) throws IOException{
		File file = new File("0.mp3");
		splitFile(file);
	}
	public static void splitFile(File file) throws IOException{
		//用读取流关联源文件
		FileInputStream fis = new FileInputStream(file);
		//定义一个1M的缓冲区
		byte[] buf = new byte[SIZE];
		//创建目的
		FileOutputStream fos = null;
		int len = 0;
		int count = 1;
		//切割文件时,必须记录住被切割文件的名称,以及切割出来碎片文件的个数,以方便合并。
		//这个信息是为了进行描述,使用键值对的方式,用到了properties对象
		Properties prop = new Properties();
		File dir = new File("c:\\partFiles");
		if(!dir.exists())
			dir.mkdirs();
		while((len = fis.read(buf)) != -1){
			fos = new FileOutputStream(new File(dir,(count++)+".part"));
			fos.write(buf,0,len);
			fos.close();
		}
		//将被切割文件的信息保存到prop集合中
		prop.setProperty("partcount",count+"");
		prop.setProperty("filename",file.getName());
		fos = new FileOutputStream(new File(dir,count+".properties"));
		//将prop集合中的数据存储到文件中
		prop.store(fos, "save file info");
		fis.close();
		fos.close();
	}
}

4.文件合并器

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FilenameFilter;
import java.io.IOException;
import java.io.SequenceInputStream;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.Properties;
public class MergeFiles {
	public static void main(String[] args) throws IOException{
		File dir = new File("c:\\partFiles");
		mergeFile(dir);
	}
	public static void mergeFile(File dir) throws IOException{
		//获取指定目录下的配置文件对象
		File[] files = dir.listFiles(new SuffixFilter(".properties"));
		if(files.length != 1)
			throw new RuntimeException(dir+",该目录下没有properties扩展名的文件或者不唯一");
		//记录配置文件对象
		File confile = files[0];
		//获取该文件的信息
		Properties prop = new Properties();
		FileInputStream fis = new FileInputStream(confile);
		prop.load(fis);
		String filename = prop.getProperty("filename");
		int count = Integer.parseInt(prop.getProperty("partcount"));
		//获取该目录下的所有碎片文件
		File[] partFiles = dir.listFiles(new SuffixFilter(".part"));
		if(partFiles.length != (count-1)){
			throw new RuntimeException("碎片文件不符合要求,个数不对!应该是"+count+"个");
		}
		//将碎片文件和流对象关联并存储到集合中
		ArrayList<FileInputStream> al = new ArrayList<FileInputStream>();
		for(int x = 1; x <= partFiles.length; x++){
			al.add(new FileInputStream(partFiles[x-1]));
		}
		final Iterator<FileInputStream> it = al.iterator();
		//将多个流合并成一个序列流
		Enumeration<FileInputStream> en = Collections.enumeration(al);
		SequenceInputStream sis = new SequenceInputStream(en);
		FileOutputStream fos = new FileOutputStream(new File(dir, filename));
		byte[] buf = new byte[1024*1024];
		int len = 0;
		while((len = sis.read(buf)) != -1){
			fos.write(buf,0,len);
		}
		fos.close();
		sis.close();
	}
}
class SuffixFilter implements FilenameFilter{
	private String suffix;
	public SuffixFilter(String suffix){
		super();
		this.suffix = suffix;
	}
	public boolean accept(File dir, String name){
		return name.endsWith(suffix);
	}
}

5.操作对象

ObjectInputStream与ObjectOutputStream
  类通过实现java.io.Serializable接口以启用序列化功能,Serializable用于给被序列化的类加入ID号,用于判断类和对象是否是同一个版本。

import java.io.FileInputStream;
import java.io.ObjectInputStream;
import java.io.Serializable;
public class ObjectStreamDemo {
	public static void main(String[] args) throws Exception{
		readObj();
	}
	public static void readObj() throws Exception{
		ObjectInputStream ois = new ObjectInputStream(new FileInputStream("obj.object"));
		Person p = (Person) ois.readObject();
		System.out.println(p.getName()+":"+p.getAge());
		ois.close();
	}
}
class Person implements Serializable{
	//为Person类添加序列号属性。将Person类中属性修饰符修改为public,也不会出现任何异常。
	private static final long serialVersionUID = 9527;
	public String name;
	public int age;
	public Person(String name, int age){
		this.name = name;
		this.age = age;
	}
	public String getName(){
		return name;
	}
	public void setName(String name){
		this.name = name;
	}
	public int getAge(){
		return age;
	}
	public void setAge(int age){
		this.age = age;
	}
}

注意:writeObject方法不能写入类及其所有超类型的瞬态(transient)和静态(static)字段的值。

6.RandomAccessFile

RandomAccessFile不是io体系中的子类。通过skipBytes(int x),seek(int x)等方法来达到随机访问。
  特点:
  1)该对象即能读,又能写。
  2)该对象内部维护了一个byte数组,并通过指针可以操作数组中的元素。
  3)可以通过getFilePointer方法获取指针的位置,和通过seek方法设置指针的位置。
  4) 其实该对象就是将字节输入流和输出流进行了封装。
  5)该对象的源或者目的只能是文件。通过构造函数就可以看出。
  
  构造方法
  RandomAccessFile(String name,String mode);
  RandomAccessFile(File f,String mode); 
  定位方法 
  public void seek(long pos); 
  读写方法 
  readBealoon(), readChar(), readInt(), readLong(), readFloat(), readDouble(), readLine(), readUTF() 等

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

public class RandomAccessFileDemo {
	public static void main(String[] args) throws IOException{
		writeFile();
		readFile();
	}
	//使用RandomAccessFile对象写入一些人要信息,比如姓名和年龄
	public static void writeFile() throws IOException{
		RandomAccessFile raf = new RandomAccessFile("ranacc.txt","rw");
		raf.write("Alex".getBytes());
		raf.write(97);
		raf.writeInt(97);
		raf.write("Vance".getBytes());
		raf.writeInt(99);
		raf.close();
	}
	public static void readFile() throws IOException{
		RandomAccessFile raf = new RandomAccessFile("ranacc.txt","r");
		//通过seek设置指针的位置
		raf.seek(9); 
		byte[] buf = new byte[5];
		raf.read(buf);
		
		String name = new String(buf);
		System.out.println("name = "+name);
		int age = raf.readInt();
		System.out.println("age = "+age);
		
		System.out.println("pos: "+raf.getFilePointer());
		raf.close();
	}
}

7.管道流

PipedInputStream和PipedOutputStream:输入输出可以直接进行连接,通过结合线程使用。

import java.io.PipedInputStream;
import java.io.PipedOutputStream;

public class PipedStreamDemo {
	public static void main(String[] args) throws Exception{
		PipedInputStream input = new PipedInputStream();
		PipedOutputStream output = new PipedOutputStream();
		input.connect(output);
		new Thread(new Input(input)).start();
		new Thread(new Output(output)).start();
	}
}
class Input implements Runnable{
	private PipedInputStream in;
	Input(PipedInputStream in){
		this.in = in;
	}
	public void run(){
		try{
			byte[] buf = new byte[1024];
			int len = in.read(buf);
			String s = new String(buf,0,len);
			System.out.println("s="+s);
			in.close();
		}catch(Exception e){
			e.printStackTrace();
		}
	}
}
class Output implements Runnable{
	private PipedOutputStream out;
	Output(PipedOutputStream out){
		this.out = out;
	}
	public void run(){
		try{
			out.write("Hi, pipe is on!".getBytes());
			out.close();
		}catch(Exception e){
			e.printStackTrace();
		}
	}
}

8.操作基本数据类型(DataInputStream与DataOutputStream)

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

public class DataStreamDemo {
	public static void main(String[] args) throws IOException{
		writeData();
		readData();
	}
	public static void writeData() throws IOException{
		DataOutputStream dos = new DataOutputStream(new FileOutputStream("data.txt"));
		dos.writeUTF("Hello");
		dos.close();
	}
	public static void readData() throws IOException{
		DataInputStream dis = new DataInputStream(new FileInputStream("data.txt"));
		String str = dis.readUTF();
		System.out.println(str);
		dis.close();
	}
}

9.操作字节数组(ByteArrayInputStream与ByteArrayOutputStream)

关闭字节数组输出输出流无效,因为它们没有调用底层资源,所有的操作都是在内存中完成的。

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;

public class ByteArrayStreamDemo {
	public static void main(String[] args) throws IOException{
		ByteArrayInputStream bis = new ByteArrayInputStream("abcdef".getBytes());
		ByteArrayOutputStream bos = new ByteArrayOutputStream();
		int ch = 0;
		while ((ch = bis.read()) != -1){
			bos.write(ch);
		}
		System.out.println(bos.toString());
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值