------- android培训、java培训、期待与您交流! ----------
File类
一、简单介绍:File类是IO包中的一个重要类,在对文件的操作中会频繁的用到。File对象就是对
文件和目录名的抽象表示形式,可以通过File对象对文件或目录的属性信息进行操作,File对象也
可以作为参数传递给流的构造函数。
二、File类的一些常见方法:
1>创建文件 boolean createNewFile();
在指定位置创建一个文件,如果文件已经存在,不重新创建,并返回false。
2>创建文件夹 boolean mkdir()和boolean mkdirs();
mkdir只能创建一级目录,而mkdirs可以创建多级目录;
例如:File file = new File("abc\\ab\\a"),ab文件夹不存在的情况下,使用file.mkdir()会返回false。
3>删除 boolean delete()和void deleteOnExit();
使用delete删除失败时返回false,deleteOnExit()是在虚拟机终止时,请求删除此抽象路径名表示的
文件或目录。
4>判断 boolean exists():判断文件是否存在,在判断File对象是文件或者目录时,必须先判断该对
象封装的内容是否存在;boolean isDirectory():判断此抽象路径名表示的文件是否是一个目录;
boolean isFile():判断此抽象路径名表示的文件是否是一个标准文件;boolean isHidden():判断文
件是不是隐藏的。
5>获取信息 getName():返回此抽象路径名表示的文件或目录的名字;getPath();获取文件路径(
封装什么路径获取什么样的路径);getParent();返回绝对路径中的父目录;getAbsolutePath();
获取绝对路径。
三、File类的应用
1>把d:\java目录下的所有.java文件改为.jad文件。
这个练习用到了File类的File[] listFiles(FilenameFilter filter)和boolean renameTo(File dest);
其中listFiles返回抽象路径名数组,这些路径名表示此抽象路径名表示的目录中满足指定过滤器的文件和
目录。FilenameFilter是一个接口,实现此接口中的accept(File dir, String name)方法可以测试指定文
件是否包含在某一文件列表中。而renameTo是重新命名此抽象路径名表示的文件。
import java.io.File;
import java.io.FilenameFilter;
public class RenameDemo {
public static void main(String[] args) {
// 将给定路径名字符串转换为抽象路径名来创建一个新 File实例
File file = new File("d:\\java");
// 返回所有满足指定过滤器的文件
File[] files = file.listFiles(new FilenameFilter() {
@Override
public boolean accept(File dir, String name) {
// dir目录中的文件如果以.java为后缀名,则返回true
return name.endsWith(".java");
}
});
for (File oldFile : files) {
// 获得.java文件的绝对路径
String oldName = oldFile.getAbsolutePath();
// 更改后缀名
String newName = oldName.replace(".java", ".jad");
// 重命名
oldFile.renameTo(new File(newName));
}
}
}
2>列出指定目录下文件或者文件夹,包含子目录中的内容。
import java.io.File;
public class ListAllFileDemo {
public static void main(String[] args) {
// 封装目录
File file = new File("d:\\exam");
listAllFiles(file, 0);
}
/**
* 罗列出file下的所有文件,此方法中由于函数自身又调用了自身,用到了递归。
* 用递归时应注意限定条件和递归的次数,以免造成内存溢出。
*
* @param file
* 指定目录
* @param level
*/
public static void listAllFiles(File file, int level) {
// 打印文件的名字
System.out.println(getSpace(level) + file.getName());
// 罗列出file下的所有文件和目录
File[] childFiles = file.listFiles();
if (childFiles.length != 0) {
// 每往里一层,级别加1
level++;
for (File child : childFiles) {
// 如果子文件仍为目录,那么调用函数自身,否则打印出文件名字
if (child.isDirectory()) {
listAllFiles(child, level);
} else {
System.out.println(getSpace(level) + child.getName());
}
}
}
}
/**
* 获得level级前的空格距离
*
* @param level
* @return
*/
private static String getSpace(int level) {
StringBuilder builder = new StringBuilder();
for (int i = 0; i < level; i++) {
builder.append(" ");
}
return builder.toString();
}
}
3>将一个指定目录下的所有java文件的绝对路径存储到一个文本文件中。
步骤:--建立一个java文件列表文件;
--对指定的目录进行递归,获取所有的java文件的路径;
--将这些路径存储到集合中;
--将集合中的数据写入文件中。
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
public class JavaFilePath {
public static void main(String[] args) {
// 声明java文件路径集合
List<String> javaPaths = new ArrayList<String>();
// 指定要遍历的目录
File dir = new File("d:\\exam");
// 把指定目录中所有java文件的绝对路径存入集合中
pathToList(javaPaths, dir);
// java文件列表文件
File javaListFile = new File("d:\\java.txt");
// 把集合中的数据写入文件中
writeToFile(javaPaths, javaListFile);
}
/**
* 把集合中的数据写入指定的文件中
*
* @param paths
* @param javaListFile
*/
private static void writeToFile(List<String> paths, File javaListFile) {
BufferedWriter bw = null;
try {
bw = new BufferedWriter(new FileWriter(javaListFile));
for (String path : paths) {
bw.write(path);
bw.newLine();
bw.flush();
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
bw.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
/**
* 遍历目录中的所有内容,如果子文件是目录,调用自身函数
* 如果是文件并且后缀名为.java则把文件的绝对路径存入集合中
*
* @param javaPaths
* @param dir
*/
private static void pathToList(List<String> javaPaths, File dir) {
File[] files = dir.listFiles();
for (File file : files) {
if (file.isDirectory()) {
pathToList(javaPaths, file);
} else if (file.getName().endsWith(".java")) {
javaPaths.add(file.getAbsolutePath());
}
}
}
}
Properties类
一、简单介绍:Properties是HashTable的子类,也就是说它具备map集合的特点,而且它里面存
储的键值对都是字符串,不需要泛型。Properties是集合中和IO技术相结合的集合容器,该对象
import java.util.Properties;
import java.util.Set;
public class PropertiesDemo {
public static void main(String[] args) {
setAndGet();
}
/**
* 设置和获取Properties的元素
*/
private static void setAndGet() {
Properties prop = new Properties();
// 设置元素
prop.setProperty("zhangsan", "20");
prop.setProperty("lisi", "30");
prop.setProperty("wangwu", "40");
// 打印集合
System.out.println(prop);
// 获得键为lisi的元素的值并打印
String value = prop.getProperty("lisi");
System.out.println(value);
// 设置键为lisi的值为"32"
prop.setProperty("lisi", "32");
// 遍历集合获得所有元素的key
Set<String> keys = prop.stringPropertyNames();
for (String key : keys) {
System.out.println(key + ":" + prop.getProperty(key));
}
}
}
--------------------打印结果-----------------------
{zhangsan=20, lisi=30, wangwu=40}
30
zhangsan:20
lisi:32
wangwu:40
2>用Properties存取配置文件。
import java.io.*;
import java.util.Properties;
public class PropertiesDemo1 {
public static void main(String[] args) {
File file = new File("d:\\configuration.txt");
method_1(file);
method_2(file);
}
/**
* 将指定文件中的键值数据存储到集合中
*
* @param file
*/
private static void method_1(File file) {
Properties prop = new Properties();
BufferedReader br = null;
try {
br = new BufferedReader(new FileReader(file));
String line = null;
while ((line = br.readLine()) != null) {
// 将文件中的每一行数据用"="分割
String[] arr = line.split("=");
// 等号左边作为键,右边作为值存入集合中
prop.setProperty(arr[0], arr[1]);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (br != null) {
try {
br.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
System.out.println(prop);
}
/**
* 使用Properties的方法存取配置文件
*
* @param file
*/
private static void method_2(File file) {
Properties prop = new Properties();
FileInputStream fis = null;
FileOutputStream fos = null;
try {
fis = new FileInputStream(file);
// load方法的原理实际上就是method_1,把文件中的配置信息加载到集合中
prop.load(fis);
System.out.println(prop);
prop.setProperty("zhangsan", "28");
fos = new FileOutputStream(file);
// 把集合中的数据存入文件中,第二个参数是注释,可写可不写
prop.store(fos, null);
System.out.println(prop);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (fis != null) {
try {
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (fos != null) {
try {
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
--------------------打印结果--------------------
method_1: {zhangsan=20, lisi=30, wangwu=40}
method_2: {zhangsan=20, lisi=30, wangwu=40}
{zhangsan=28, lisi=30, wangwu=40}
3>记录应用程序的运行次数,如果使用次数已到,给出注册提示。
import java.io.*;
import java.util.Properties;
public class PropertiesDemo2 {
public static void main(String[] args) {
File file = new File("d:\\count.ini");
runCount(file);
}
/**
* 用文件记录程序运行的次数,用键值对的形式存储,这样便于阅读和操作数据
*
* @param file
*/
private static void runCount(File file) {
Properties prop = new Properties();
FileInputStream fis = null;
FileOutputStream fos = null;
try {
if (!file.exists()) {
file.createNewFile();
}
fis = new FileInputStream(file);
// 加载配置文件中的数据
prop.load(fis);
int count = 0;
// 获得time的值,即运行的次数
String value = prop.getProperty("time");
if (value != null) {
count = Integer.parseInt(value);
// 如果程序运行超过3次,对用户作出提醒
if (count >= 3) {
System.out.println("使用次数已到,请注册!");
return;
}
}
// 每运行一次,count加1
count++;
// 设置集合中time的值
prop.setProperty("time", "" + count);
fos = new FileOutputStream(file);
// 把集合中的数据重新存入文件中
prop.store(fos, "");
System.out.println(prop);
} catch (Exception e) {
e.printStackTrace();
} finally {
if (fis != null) {
try {
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (fos != null) {
try {
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
---------------------打印结果---------------------
第一次运行:{time=1}
第二次运行:{time=2}
第三次运行:{time=3}
第四次运行:使用次数已到,请注册!
第五次运行:使用次数已到,请注册!
IO包中其它流对象-->打印流
import java.io.*;
public class PrintStreamDemo {
public static void main(String[] args) {
// 源为键盘录入
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String line = null;
// 使用打印流写到控制台,第二个参数为true时,则 println、printf或 format方法将刷新输出缓冲区
PrintWriter pw = new PrintWriter(System.out, true);
try {
while ((line = br.readLine()) != null) {
if ("over".equals(line)) {
break;
}
pw.println((line));
// pw.flush();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
序列流-->SequenceInputStream
import java.io.*;
import java.util.Enumeration;
import java.util.Vector;
public class SequenceStreamDemo {
public static void main(String[] args) {
FileInputStream fis1 = null;
FileInputStream fis2 = null;
FileInputStream fis3 = null;
// 创建需要串联的流对象
try {
fis1 = new FileInputStream("d:\\1.txt");
fis2 = new FileInputStream("d:\\2.txt");
fis3 = new FileInputStream("d:\\3.txt");
} catch (FileNotFoundException e) {
e.printStackTrace();
}
// method_1(fis1, fis2);
method_1(fis1, fis2, fis3);
}
/**
* 由于参数的个数不确定,使用java5的新特性,可变参数
*
* @param streams
*/
private static void method_1(InputStream... streams) {
// 声明合并流
SequenceInputStream sis = null;
File newFile = new File("d:\\new.txt");
FileOutputStream fos = null;
// 如果参数的个数为2,那么直接使用SequenceInputStream(InputStream s1, InputStream s2)
// 构造方法
if (streams.length == 2) {
sis = new SequenceInputStream(streams[0], streams[1]);
} else {
// 把传入的流对象放入集合中
Vector<InputStream> vector = new Vector<InputStream>();
for (InputStream in : streams) {
vector.add(in);
}
Enumeration<InputStream> en = vector.elements();
// 个数大于2,用SequenceInputStream(Enumeration<? extends InputStream> e)
sis = new SequenceInputStream(en);
}
try {
// 把合并流中的所有数据写入指定的文件中
fos = new FileOutputStream(newFile);
int len = 0;
byte[] buf = new byte[1024];
while ((len = sis.read(buf)) != -1) {
fos.write(buf, 0, len);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if (sis != null) {
try {
sis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (fos != null) {
try {
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
练习2:切割文件,即把文件分割成几部分,再把这几部分合并到一个新文件。
import java.io.*;
import java.util.*;
public class SplitFile {
public static void main(String[] args) {
// 源(需要切割的文件)
File file = new File("d:\\abc.jpg");
splitFile(file);
// 目的(合并成的文件)
File newFile = new File("d:\\abc_new.jpg");
FileInputStream fis1 = null;
FileInputStream fis2 = null;
FileInputStream fis3 = null;
// 创建需要合并的流对象
try {
fis1 = new FileInputStream("d:\\1.part");
fis2 = new FileInputStream("d:\\2.part");
fis3 = new FileInputStream("d:\\3.part");
} catch (FileNotFoundException e) {
e.printStackTrace();
}
marge(newFile, fis1, fis2, fis3);
}
/**
* 切割指定的文件
*
* @param file
*/
private static void splitFile(File file) {
int part = 0;
FileInputStream fis = null;
FileOutputStream fos = null;
try {
fis = new FileInputStream(file);
byte[] buf = new byte[1024 * 1024];
int len = 0;
// 读入缓冲区1M数据(如果文件大小不足1M,则读入len个字节)
while ((len = fis.read(buf)) != -1) {
fos = new FileOutputStream("d:\\" + (++part) + ".part");
// 把缓冲区中的数据写入一个文件
fos.write(buf, 0, len);
fos.close();
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if (fis != null) {
try {
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
/**
* 由于参数的个数不确定,使用java5的新特性,可变参数
*
* @param newFile
* 合并数据到新文件
*
* @param streams
*/
private static void marge(File newFile, InputStream... streams) {
// 声明合并流
SequenceInputStream sis = null;
FileOutputStream fos = null;
// 如果参数的个数为2,那么直接使用SequenceInputStream(InputStream s1, InputStream s2)
// 构造方法
if (streams.length == 2) {
sis = new SequenceInputStream(streams[0], streams[1]);
} else {
// 把传入的流对象放入集合中
Vector<InputStream> vector = new Vector<InputStream>();
for (InputStream in : streams) {
vector.add(in);
}
Enumeration<InputStream> en = vector.elements();
// 个数大于2,用SequenceInputStream(Enumeration<? extends InputStream> e)
sis = new SequenceInputStream(en);
}
try {
// 把合并流中的所有数据写入指定的文件中
fos = new FileOutputStream(newFile);
int len = 0;
byte[] buf = new byte[1024];
while ((len = sis.read(buf)) != -1) {
fos.write(buf, 0, len);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if (sis != null) {
try {
sis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (fos != null) {
try {
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
操作对象的流-->ObjectInputStream、ObjectOutputStream
import java.io.*;
public class ObjectStreamDemo {
public static void main(String[] args) {
File file = new File("d:\\person.object");
writeObj(file);
readObj(file);
}
/**
* 读取对象
*
* @param file
*/
private static void readObj(File file) {
ObjectInputStream ois = null;
try {
ois = new ObjectInputStream(new FileInputStream(file));
// 从ObjectInputStream读取对象
Person person = (Person) ois.readObject();
System.out.println(person);
} catch (Exception e) {
e.printStackTrace();
} finally {
if (ois != null) {
try {
ois.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
/**
* 写入对象
*
* @param file
*/
private static void writeObj(File file) {
ObjectOutputStream oos = null;
try {
oos = new ObjectOutputStream(new FileOutputStream(file));
// 将指定的对象写入ObjectOutputStream
oos.writeObject(new Person("zhangsan", 24));
} catch (Exception e) {
e.printStackTrace();
} finally {
if (oos != null) {
try {
oos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
/**
* 实现Serializable接口以启用其序列化功能,序列化接口没有方法或字段,仅用于标识此类可序列化
*
*/
class Person implements Serializable {
/**
* 序列化运行时使用一个称为serialVersionUID的版本号与每个可序列化类相关联, 如果接收
* 者加载的该对象的类的serialVersionUID与对应的发送者的类的版本号不同,则反序列化将
* 会导致InvalidClassException。
* 可序列化类可以通过声明名为"serialVersionUID"的字段(该字段必须是静态 (static)、
* 最终(final)的long型字段)显式声明自己的serialVersionUID,如果可序列化类未显式
* 声明,则序列化运行时将基于该类的各个方面计算该类的默认serialVersionUID值。
*/
private static final long serialVersionUID = 100L;
String name;
// int age;
// 被transient修饰的变量不会被序列化
transient int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public String toString() {
return name + ":" + age;
}
}
-----------------------打印结果----------------------
age的声明前不加transient:zhangsan:24
age的声明前加transient:zhangsan:0
管道流-->PipedInputStream、PipedOutputStream
import java.io.*;
public class PipedStreamDemo {
public static void main(String[] args) {
PipedOutputStream pos = new PipedOutputStream();
PipedInputStream pis = new PipedInputStream();
try {
// 用一个管道输出流对象连接一个管道输入流对象
pos.connect(pis);
// 开启读数据线程和写数据线程
new ReadThread(pis).start();
new WriteThread(pos).start();
} catch (IOException e) {
e.printStackTrace();
}
}
}
class ReadThread extends Thread {
private PipedInputStream in;
public ReadThread(PipedInputStream in) {
this.in = in;
}
@Override
public void run() {
int len = 0;
byte[] buf = new byte[1024];
try {
// 从管道输入流中读取数据,没有数据时,该方法处于阻塞状态
len = in.read(buf);
String s = new String(buf, 0, len);
System.out.println(s);
in.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
class WriteThread extends Thread {
private PipedOutputStream out;
public WriteThread(PipedOutputStream out) {
this.out = out;
}
@Override
public void run() {
try {
// 往管道输出流写数据
out.write("data".getBytes());
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
随机访问文件-->RandomAccessFile
import java.io.*;
public class RandomAccessFileDemo {
public static void main(String[] args) {
RandomAccessFile writeRAF = null;
RandomAccessFile readRAF = null;
try {
// 随机访问文件对象,第一个参数是需要访问的文件,第二个参数定义了对文件的读写权限
writeRAF = new RandomAccessFile("d:\\random.txt", "rw");
readRAF = new RandomAccessFile("d:\\random.txt", "r");
writeFile(writeRAF);
// writeFile(writeRAF, 8 * 3);
// readFile(readRAF);
readFile(readRAF, 8);
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 使用RandomAccessFile读取文件中的数据
*
* @param accessFile
* @throws IOException
*/
private static void readFile(RandomAccessFile accessFile)
throws IOException {
byte[] buf = new byte[4];
accessFile.read(buf);
String name = new String(buf);
int age = accessFile.readInt();
System.out.println("name=" + name + "; age=" + age);
accessFile.close();
}
/**
* 使用RandomAccessFile随机读取文件中的数据
*
* @param accessFile
* @param index
* 设置到此文件开头测量到的文件指针偏移量
* @throws IOException
*/
private static void readFile(RandomAccessFile accessFile, int index)
throws IOException {
accessFile.seek(index);
// 跳过index个字节
// accessFile.skipBytes(index);
readFile(accessFile);
}
/**
* 使用RandomAccessFile向文件中写数据
*
* @param accessFile
* @throws IOException
*/
private static void writeFile(RandomAccessFile accessFile)
throws IOException {
accessFile.write("张三".getBytes());
accessFile.writeInt(45);
accessFile.write("李四".getBytes());
accessFile.writeInt(97);
accessFile.close();
}
/**
* 使用RandomAccessFile向文件中某个位置开始写数据,或修改已有的数据
*
* @param accessFile
* @param index
* @throws IOException
*/
private static void writeFile(RandomAccessFile accessFile, int index)
throws IOException {
accessFile.seek(index);
// accessFile.skipBytes(8);
writeFile(accessFile);
}
}
------------------------------打印结果-------------------------------
调用readFile(readRAF)的打印结果:name=张三; age=45
调用readFile(readRAF, 8)的打印结果:name=李四; age=97
操作基本数据类型的流-->DataInputStream、DataOutputStream
import java.io.*;
public class DataStreamDemo {
public static void main(String[] args) {
writeData();
readData();
writeUTFData();
readUTFData();
}
private static void writeData() {
try {
DataOutputStream dos = new DataOutputStream(new FileOutputStream(
"d:\\data.txt"));
// 将一个boolean值以1-byte值形式写入基础输出流
dos.writeBoolean(true);
// 将一个int值以4-byte值形式写入基础输出流
dos.writeInt(782);
// 使用Double类中的doubleToLongBits方法将double参数转换为一个long值,
// 然后将该long值以8-byte值形式写入基础输出流
dos.writeDouble(4237.3247);
dos.close();
} catch (Exception e) {
e.printStackTrace();
}
}
private static void readData() {
try {
DataInputStream dis = new DataInputStream(new FileInputStream(
"d:\\data.txt"));
// 从所包含的输入流中读取此操作需要的字节
// 读取数据的时候需要按照写入数据的顺序读取相应的字节数,否则读取到的数据与写入的数据不符
boolean b = dis.readBoolean();
int num = dis.readInt();
double d = dis.readDouble();
System.out.println("b=" + b + ", num=" + num + ", d=" + d);
dis.close();
} catch (Exception e) {
e.printStackTrace();
}
}
private static void writeUTFData() {
try {
DataOutputStream dos = new DataOutputStream(new FileOutputStream(
"d:\\utfdata.txt"));
//以与机器无关方式使用UTF-8修改版编码将一个字符串写入基础输出流
//使用该方法写入的数据必须使用相对应的readUTF读取
dos.writeUTF("你好");
dos.close();
} catch (Exception e) {
e.printStackTrace();
}
}
private static void readUTFData() {
try {
DataInputStream dis = new DataInputStream(new FileInputStream(
"d:\\utfdata.txt"));
String utf = dis.readUTF();
System.out.println(utf);
dis.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
--------------------------打印结果---------------------------
b=true, num=782, d=4237.3247
你好
ByteArrayInputStream、ByteArrayOutputStream
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
public class ByteArrayStreamDemo {
public static void main(String[] args) {
// 数据源
ByteArrayInputStream bais = new ByteArrayInputStream(
"abcdefgh".getBytes());
// 数据目的
ByteArrayOutputStream baos = new ByteArrayOutputStream();
// 这个方法可以将此byte数组输出流的全部内容写入到指定的输出流参数中
// baos.writeTo(new FileOutputStream("d:\\byte.txt"));
int b = 0;
while ((b = bais.read()) != -1) {
baos.write(b);
}
System.out.println(baos.toString());
}
}