——Java培训、Android培训、iOS培训、.Net培训、期待与您交流!——
一、File类
- 概述
是将文件和文件夹封装成的对象,方便对文件或者文件夹的属性信息进行操作。File类的实例是不可变的;一旦创建,File 对象表示的抽象路径名将永不改变,并且可以作为参数传递。 - 常用操作方法
File file = new File("a.txt");//将a.txt封装成File对象。可以将已有的和未出现的文件或者文件夹封装成对象。
File file=newFile("c:\\a","b.txt");将文件所在目录路径和文件一起传入,指定文件路径。
file.createNewFile(); // 用于创建一个空文件,成功返回true,若已存在,则不会创建并返回false,
file.mkdir(); // 创建目录,一层(成功返回true,失败返回false)
file.mkdirs(); // 创建多级目录
file.delete(); // 删除成功返回true,否则返回false
file.deleteOnExit(); // 退出时删除,一般用于系统退出时删除临时文件
file.canExecute(); // 是否可被执行
file.exists(); // 是否存在
file.isDirectory(); // 是否为目录文件,不存在或者不是目录返回false
file.isFile(); // 是否为文件,不存在或不是文件返回false
file.isHidden(); // 是否为隐藏文件
file.isAbsolute(); // 是否为据对路径
file.getName(); // 获取文件名
file.getParh(); // 获取文件路径
file.getParent(); // 父目录
file.getAbsolutePath();//获取文件的绝对路径
file.lastModified(); // 最后修改时间
file.length();//返回文件长度
- 递归
因为文件目录中会包含子目录,所以想要遍历出所有文件,就需要使用递归。例子如下:
import java.io.File;
public class Demo {
public static void main(String[] args) {
String str = "C:\\";//列出C盘所有文件
File f = new File(str);
fun(f);
}
//要不断列出,因为给出的File类对象可能是一个目录
public static void fun(File f){
//判断给定的路径是否是目录,如果是目录在列出
if(f.isDirectory()){
File[] file = f.listFiles();
//再依次循环进行判断
try{
for(int i = 0;i < file.length;i++){
//继续把内容传入到fun方法之中进行验证
fun(file[i]);
}
}catch(Exception e){}
}
else{
System.out.println(f);
}
}
}
二、Properties类
概述
是Map–Hashtable的子类。一个可以将键值进行持久化存储的对象,键值对都是字符串,无泛型定义。是集合中和IO技术想结合的集合容器。常用方法
Properties prop = new Properties();//创建对象
prop.setProperty(String key,String value);// //设置键和值,调用Hashtable的方法put
prop.getProperty(String key);//指定key搜索value 返回string
prop.load(InputStream ism);//从输入字符流中读取属性列表(键和元素对).
prop.load(Reader reader); //从输入字符流中读取属性列表(键和元素对)。
prop.list(PrintStream out);//将属性列表输出到指定的输出流
prop.store(OutputStreamout,String comments);//对应load(InputStream )将属性列表(键值对)写入输出流。comments属性列表的描述。
prop.store(Writerwriter, String comments);//对应load(Reader)将属性列表(键值对)写入输出流。comments属性列表的描述。
3示例:
class Demo{
public static void main()throws IOException
{
//使用字符读取缓冲流关联文件
BufferedReader bufr = new BufferedReader(new FileReader("Test.txt"));
String line = null;
Properties prop = new Properties();//创建对象
while((line=bufr.readLine())!=null)
{
String[] arr = line.split("=");//将一行数据以“=”号进行分割
//将=左边作为键存入,将=右边作为值存入
prop.setProperty(arr[0],arr[1]);
}
bufr.close();//关流
System.out.println(prop);
}
}
三、打印流
概述
打印流提供了更多的功能,比如打印方法。可以直接打印任意类型的数据,使用的本机默认的字符编码. 。它有一个自动刷新机制,创建该对象,指定参数,对于指定方法可以自动刷新。常用方法
PrintStream(File file) :创建具有指定文件且不带自动行刷新的新打印流。
PrintStream(File file, String csn) :创建具有指定文件名称和字符集且不带自动行刷新的新打印流。
PrintStream(OutputStream out) :创建新的打印流。
PrintStream(OutputStream out, boolean autoFlush) :创建新的打印流。
PrintStream(OutputStream out, boolean autoFlush, String encoding) :创建新的打印流。
PrintStream(String fileName) :创建具有指定文件名称且不带自动行刷新的新打印流。
3. 示例:
当目的是一个字节输出流时,如果使用的println方法,可以在printStream对象上加入一个true参数。这样对于println方法可以进行自动的刷新,而不是等待缓冲区满了再刷新。最终print方法都将具体的数据转成字符串,而且都对IO异常进行了内部处理。
因此一般都使用printStream子类PrintWrite,可以直接操作字符数据,同时也可以指定具体的编码。
import java.io.*;
class PrintStreamDemo
{
public static void main(String[] args) throws IOException
{
BufferedReader bufr =
new BufferedReader(new InputStreamReader(System.in));
PrintWriter out = new PrintWriter(new FileWriter("Test.txt"),true);//打印流关联文件,自动刷新
String line = null;
while((line=bufr.readLine())!=null)
{
out.println(line);
}
//关流
out.close();
bufr.close();
}
}
四、序列流
概述
序列流作用就是将多个读取流合并成一个读取流。实现数据合并。常用方法
一般将合并多个流文件步骤:
1、创建集合,并将流对象添加进集合:ArrayList al = new ArrayList();
2、创建SequenceInputStream对象,指定集合的枚举对象,合并流:SequenceInputStream sis = new SequenceInputStream(Collections.enumeration(al));
3、创建写入流对象,FileOutputStream关联写入文件:FileOutputStream fos = new FileOutputStream(file);
4、利用SequenceInputStream对象和FileOutputStream对象读数据进行反复读写操作:while((len=sis.read(buf))!=-1){
fos.write(buf,0,len);
}
具体的合并请看示例:
import java.io.*;
import java.util.*;
class SplitFileDemo{
private static final String CFG = ".properties";
private static final String SP = ".part";
public static void main(String[] args) throws IOException{
File file = new File("c:\\0.bmp");
File dir = new File("c:\\partfiles");
meger(dir);
}
//数据的合并。
public static void meger(File dir)throws IOException{
if(!(dir.exists() && dir.isDirectory()))
throw new RuntimeException("指定的目录不存在,或者不是正确的目录");
File[] files = dir.listFiles(new SuffixFilter(CFG));
if(files.length==0)
throw new RuntimeException("扩展名.proerpties的文件不存在");
//获取到配置文件
File config = files[0];
//获取配置文件的信息。
Properties prop = new Properties();
FileInputStream fis = new FileInputStream(config);
prop.load(fis);
String fileName = prop.getProperty("filename");//获得文件名
int partcount = Integer.parseInt(prop.getProperty("partcount"));
File[] partFiles = dir.listFiles(new SuffixFilter(SP));
if(partFiles.length!=partcount)
throw new RuntimeException("缺少碎片文件");
ArrayList<FileInputStream> al = new ArrayList<FileInputStream>();
for(int x=0; x<partcount; x++){
al.add(new FileInputStream(new File(dir,x+SP)));
}
Enumeration<FileInputStream> en = Collections.enumeration(al);
SequenceInputStream sis = new SequenceInputStream(en);
File file = new File(dir,fileName);
FileOutputStream fos = new FileOutputStream(file);
byte[] buf = new byte[1024];
int len = 0;
while((len=sis.read(buf))!=-1){
fos.write(buf,0,len);
}
fos.close();
sis.close();
}
因为上面使用了ArrayList,但是ArrayList没有枚举,所以需要用Enumeration创建。这样会比Vector高效。
五、其他
对象序列化:实现Serializable接口,序列化即使将一个对象整个存储到文件中保存,可以实现数据的保存,下次可以将对象从文件中恢复出,只需要此对象实现了Serializable接口即可,注意的两点是,一是为对象添加static long serialVersionUID = 42L;随便指定一个数值,这是这个对象的唯一标识,即有相同标识才可以从文件中恢复出对象;
二是序列化只会序列化堆中的数据,静态数据不会被序列化,transient关键字的也不会。 如果在不需要序列化的对象,则对象前加上transient关键字。
import java.io.*;
class StreamDemo {
public static void main(String[] args) throws Exception{
writeObj();
readObj();
}
public static void readObj()throws Exception{
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("obj.txt"));
Object obj = ois.readObject();//读取一个对象。
System.out.println(obj.toString());
}
public static void writeObj()throws IOException{
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("obj.txt"));
oos.writeObject(new Person("lisi",25)); //写入一个对象。
oos.close();
}
}
class Person implements Serializable{
private static final long serialVersionUID = 42L;
private transient String name;//用transient修饰后name将不会进行序列化
public int age;
Person(String name,int age){
this.name = name;
this.age = age;
}
public String toString(){
return name+":"+age;
}
}
Java序列化就是把对象转换成字节序列,而Java反序列化就是把字节序列还原成Java对象。并且采用Java序列化与反序列化技术,一是可以实现数据的持久化,在MVC模式中很是有用;二是可以对象数据的远程通信。