File常用操作
// 相对于 当前项目根目录
File f = new File("src/b.properties");// 存在对应的文件
//f = new File("src/abcd.properties");// 不存在对应的文件
// 访问属性
System.out.println("文件名:"+f.getName());
System.out.println("路径名:"+f.getPath());
System.out.println("绝对路径:"+f.getAbsolutePath());//
System.out.println("父目录路径:"+f.getParent());
System.out.println("父目录File对象:"+f.getParentFile());
System.out.println("大小:"+f.length());// 单位: 字节
System.out.println("最后一次的修改时间:" + new Date(f.lastModified()));
System.out.println("是否存在:"+f.exists());//
System.out.println("是否可读:"+f.canRead());
System.out.println("是否可写:"+f.canWrite());
System.out.println("是否为普通文件:"+f.isFile());//
System.out.println("是否为目录:"+f.isDirectory());//
System.out.println("是否为隐藏文件:"+f.isHidden());
其他
private static void f1() {
File f = new File("src/a.txt");
// 创建一个空的(普通)文件, 成功返回 true
try {
// 文件所在目录必须真实存在
boolean flag = f.createNewFile();
System.out.println("createNewFile:"+flag);
} catch (IOException e) {
e.printStackTrace();
}
}
private static void f2() {
// 重命名(也可以用于移动文件), 成功返回true
File f = new File("src/a.txt");
// 参数新的File对象, 只改名称, 则所在目录不能修改; 如果移动,则可以修改目录
File f2 = new File(f.getParentFile(), "aaa.txt");
boolean renameTo = f.renameTo(f2);// 只改名称
System.out.println("renameTo1:"+renameTo);
// 移动
f2 = new File("src/aaa.txt");
// src的上一级目录
File parentFile = f2.getParentFile().getParentFile();
boolean renameTo2 = f2.renameTo(new File(parentFile, f2.getName()));
System.out.println("renameTo2:"+renameTo2);
}
private static void f3() {
// 删除File, 成功返回true
File f = new File("aaa.txt");
// 删除目录时,目录必须是空的
System.out.println("delete:"+f.delete());
}
private static void f4() {
// 创建目录, 成功返回true
File f = new File("abc");
boolean mkdir = f.mkdir();
System.out.println("mkdir:"+mkdir);
File f2 = new File("abc/qw/xyz");
// 父目录如果不存在,则创建失败
boolean mkdir2 = f2.mkdir();
System.out.println("mkdir2:"+mkdir2);
// 级联创建目录, 即路径中所有不存在的目录会被自动的依次创建
boolean mkdirs = f2.mkdirs();
System.out.println("mkdirs:"+mkdirs);
}
private static void f5() {
File f = new File("src");
// 获取当前目录下的 所有子文件的 名称
String[] list = f.list();
// for (String fileName : list) {
// System.out.println(fileName);
// }
System.out.println("----------");
// 获取当前目录下的 所有子文件的 File对象
File[] listFiles = f.listFiles();
// for (File file : listFiles) {
// System.out.println(file.getAbsolutePath());
// }
System.out.println("-----------");
// 筛选/过滤
String[] list2 = f.list(new FilenameFilter() {
// 返回 true 表示留下, 返回 false 表示过滤、不留下
@Override
public boolean accept(File dir, String name) {
// 参数 dir 当前文件所在目录, name 当前文件名
// 保留 properties 文件
return name.endsWith(".properties");
}
});
// for (String fileName : list2) {
// System.out.println(fileName);
// }
File[] listFiles2 = f.listFiles(new FileFilter() {
// 返回 true 表示留下, 返回 false 表示过滤、不留下
@Override
public boolean accept(File f) {
// 参数 f 是当前文件对象
// 保留 properties 文件
return f.isFile() ?
f.getName().endsWith(".properties")
: false;
}
});
for (File file : listFiles2) {
System.out.println(file.getAbsolutePath());
}
}
输入流
private static void f2() {
// jdk7 语法 try-with-resource, 能够自动关闭外部资源
try (
// 在此处定义流对象, 此时操作结束后, 会自动关闭资源
FileInputStream fis = new FileInputStream("src/code15/io/a.txt");
// 只要是实现了 AutoCloseable 接口的 类的对象, 都可以在此定义
) {
byte[] buffer = new byte[4];
int length = 0;
while ( (length = fis.read(buffer)) != -1) {
// 不能加换行, 如果有中文, 容易出现中文乱码
System.out.print(new String(buffer, 0, length));
// 不建议把字节转换为 字符
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
private static void f1() {
FileInputStream fis = null;
try {
// 传入 根据路径构建的 File对象
//FileInputStream fis = new FileInputStream(new File("src/code15/io/a.txt"));
// 传入文件的路径
fis = new FileInputStream("src/code15/io/a.txt");
// 一次读取一个字节, 返回int类型的表示, 会处于阻塞状态, 如果读取到文件末尾, 则返回 -1
//int read = fis.read();
//System.out.println((char)read);
//byte[] buffer = new byte[4];
// 一次读取部分字节到指定数组中, 返回本次读取到的字节数, 如果读取到文件末尾, 则返回 -1
//int length = fis.read(buffer);
// for (int i = 0; i < length; i++) {
// System.out.print((char) buffer[i]);
// }
//System.out.print(new String(buffer, 0, length));
// 获取当前流中可读取的字节数
int available = fis.available();
// 对于普通文件操作, 第一次取的值, 一般是 当前文件的大小
System.out.println("available:"+available);
byte[] buffer = new byte[4];
int length = 0;
while ( (length = fis.read(buffer)) != -1) {
// 不能加换行, 如果有中文, 容易出现中文乱码
System.out.print(new String(buffer, 0, length));
// 不建议把字节转换为 字符
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (null != fis) {
try {
// 释放资源
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
字节数组输入输出流
private static void f2() {
try (
// 把内容写出到 内部的字节数组中
ByteArrayOutputStream baos = new ByteArrayOutputStream();
) {
baos.write('c');// 不能写中文
baos.write("hello".getBytes());
baos.flush();
// 获取 当前流中保存的 所有字节
byte[] byteArray = baos.toByteArray();
System.out.println("byteArray:" + new String(byteArray));
// 把 字节数组输出流中保存的 字节全部写入到 其他的字节输出流中
// 此处的效果是, 会把 字节数组输出流中内容保存到指定文件中
baos.writeTo(new FileOutputStream("src/code15/io/xyz.txt"));
} catch (IOException e) {
e.printStackTrace();
}
}
private static void f1() {
byte[] data = "hello world".getBytes();
try (
// 把 字节数组交给 字节数组输入流进行操作
// 操作的不是外部资源, 是内存中的数据, 不需要 释放资源
InputStream is = new ByteArrayInputStream(data);
) {
int d = 0;
while ( (d = is.read()) != -1 ) {
System.out.print((char) d );
}
} catch (IOException e) {
e.printStackTrace();
}
}
对象的序列化
private static void f1() {
User u1 = new User(1, "tom", 22);
User u2 = new User(2, "jerry", 24);
List<User> list = Arrays.asList(u1, u2);
// 序列化
try (
FileOutputStream fos = new FileOutputStream("src/code15/io/users.data");
// 对于此类的包装流等,只需要关闭外层的流即可, 内部的流就会被自动关闭
ObjectOutputStream oos = new ObjectOutputStream(fos);
) {
// 一次输出一个对象
oos.writeObject(u1);
oos.writeObject(u2);
oos.writeObject(list);
// 刷新
oos.flush();
System.out.println("序列化成功");
} catch (IOException e) {
e.printStackTrace();
}
}
反序列化
private static void f2() {
// 反序列化
try (
ObjectInputStream ois = new ObjectInputStream(
new FileInputStream("src/code15/io/users.data"));
){
// 一次读一个对象
// 读和写的顺序必须一致
User u1 = (User) ois.readObject();
User u2 = (User) ois.readObject();
System.out.println(u1);
System.out.println(u2);
List<User> list = (List<User>) ois.readObject();
System.out.println(list);
System.out.println("反序列化成功");
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
亦或加密解密案例
/**
* 加密或解密文件<br>
* 加密后的文件以 _encrypt 结尾 <br>
* 内部使用 异或 操作
* @param path 需要加密或解密的文件路径
* @param pwd 密码
*/
public static void encryptOrDecryptFile(String path, int pwd) {
File f = new File(path);
if (!f.isFile()) {
throw new IllegalArgumentException("["+path+"]不是文件");
}
String suffix = "_encrypt";
String name = f.getName();
// 默认加密, 获取加密后的名称
String newName = name + suffix;
if (name.endsWith(suffix)) {
// 是解密操作, 获取解密后的名称
newName = name.replace(suffix, "");
}
// 加密
try (
FileInputStream fis = new FileInputStream(f);
FileOutputStream fos = new FileOutputStream(
new File(f.getParentFile(), newName));
) {
int read = -1;
while ( ( read = fis.read() ) != -1 ) {
// 异或 加密、解密
int c = read ^ pwd;
fos.write(c);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}