Java的文件操作, 主要包含两类操作:
- 文件系统相关的操作, 比如创建文件, 文件改名的操作等
- 文件内容相关的操作
目录
File类:
典型方法:
?查看文件名,路径名
?是否是文件或者目录
?创建/删除文件
?创建目录
?显示路径下的目录或文件
?文件改名
文件读写
FileInputStream
OutputStream
Reader
Writer
文件操作案例
File类:
构造方法:
构造方法内可以写绝对路径,也可以写相对路径.?
典型方法:
查看文件名,路径名
public static void main(String[] args) throws IOException {
File file = new File("./test.txt");
System.out.println(file.getParent()); // 获取到文件的父目录
System.out.println(file.getName()); // 获取到文件名
System.out.println(file.getPath()); // 获取到文件路径(构造 File 的时候指定的路径)
System.out.println(file.getAbsolutePath()); // 获取到绝对路径(简单拼接)
System.out.println(file.getCanonicalPath()); // 获取到绝对路径
}
?是否是文件或者目录
public static void main(String[] args) {
File f = new File("./test.txt");
System.out.println(f.exists());
System.out.println(f.isDirectory());
System.out.println(f.isFile());
}
?创建/删除文件
public static void main3(String[] args) throws IOException {
// 文件的创建和删除
File f = new File("./test.txt");
System.out.println(f.exists());
System.out.println("创建文件");
f.createNewFile();
System.out.println("创建文件结束");
System.out.println(f.exists());
// f.delete();
// System.out.println("删除成功");
}
?创建目录
public static void main4(String[] args) {
File f = new File("./aaa/bbb/ccc/ddd");
// f.mkdir();
f.mkdirs();
System.out.println(f.isDirectory());
}
?显示路径下的目录或文件
public static void main5(String[] args) {
File f = new File("./");
System.out.println(Arrays.toString(f.list()));
System.out.println(Arrays.toString(f.listFiles()));
}
?文件改名
public static void main(String[] args) {
File f = new File("./aaa");
File f2 = new File("./zzz");
f.renameTo(f2);
}
??
文件读写
针对文件的读写, Java提供了一组类:
- 字节流对象, 针对二进制文件, 以字节为单位进行读写
- 字符流对象, 针对文本文件, 以字符为单位进行读写
具体的类如下:?
read方法
一个字节一个字节读, 这样子read的返回值是这个字节(-1 为结束标志)
public static void main1(String[] args) {
InputStream inputStream = null;
try {
inputStream = new FileInputStream("./test.txt");
//尝试一个一个字节的读, 把整个文件都读完.
while (true) {
int b = inputStream.read();
if (b == -1) {
// 读到了文件末尾
break;
}
System.out.println(b);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
//读完之后要记得关闭文件, 释放资源~
try {
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
但是这样子在外面创建InputStream对象, 再使用finally释放的方法太麻烦.
可以写在try()内, 就可以自动释放,如下:
//简写
public static void main2(String[] args) {
try (InputStream inputStream1 = new FileInputStream("./test.txt")) {
while (true) {
int b = inputStream1.read();
if (b == -1) {
break;
}
System.out.println(b);
}
} catch (IOException e) {
e.printStackTrace();
}
}
归为数组再读, 返回值是字符的个数
public static void main3(String[] args) {
//读的放入数组
try (InputStream inputStream2 = new FileInputStream("./test.txt")) {
// 一次读取若干个字节.
while (true) {
byte[] buffer = new byte[1024];//1024只是一个象征值, len才是数组长度
int len = inputStream2.read(buffer);
if (len == -1) {
// 如果返回 -1 说明读取完毕了
break;
}
for (int i = 0; i < len; i++) {
System.out.println(buffer[i]);
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
与上面是一样的结果, 都是以字节形式表示?
OutputStream
写操作同理:
public static void main(String[] args) {
try (OutputStream outputStream = new FileOutputStream("./test.txt")) {
// outputStream.write(97);
// outputStream.write(98);
// outputStream.write(99);
byte[] buffer = new byte[]{100, 101, 102};
outputStream.write(buffer);
} catch (IOException e) {
e.printStackTrace();
}
}
不过这里的写操作, 默认是直接覆盖原来的数据的, 追加数据只要再构造方法种加 true?
try (OutputStream outputStream = new FileOutputStream("./test.txt", true))
Reader
这是以字符的方式打印数据
public static void main(String[] args) {
try (Reader reader = new FileReader("./test.txt")) {
// 按照字符来读.
while (true) {
char[] buffer = new char[1024];
int len = reader.read(buffer);
if (len == -1) {
break;
}
String s = new String(buffer, 0, len);
System.out.println(s);
}
} catch (IOException e) {
e.printStackTrace();
}
}
结果如下, 以字符的形式输出?
Writer
如同字节流的写法类似:
public static void main(String[] args) {
try (Writer writer = new FileWriter("./test.txt", true)) {
writer.write("xyz");
} catch (IOException e) {
e.printStackTrace();
}
}
??
文件操作案例
先输入要扫描的目录, 以及要删除的文件名
public class Test1 {
public static void main(String[] args) throws IOException {
// 1. 先输入要扫描的目录, 以及要删除的文件名
Scanner scanner = new Scanner(System.in);
System.out.println("请输入要扫描的路径:");
String rootDir = scanner.nextLine();
System.out.println("请输入要删除的文件名:");
String toDeleteDir = scanner.nextLine();
//判断路径是否正确
File rootFile = new File(rootDir);
if (!rootFile.isDirectory()){
System.out.println("路径输入错误");
return;
}
// 2. 遍历目录, 把指定目录 中的所有文件和子目录都遍历一遍, 从而找到要删除的文件
scanDir(rootFile, toDeleteDir);
}
private static void scanDir(File rootFile, String toDeleteDir) throws IOException {
File[] files = rootFile.listFiles();
//判断目录是否为空
if (files == null){
return;
}
for (File f : files) {
//先判断是否是文件
if (f.isFile()){
//包含文件名就删除, 不包含继续递归
if (f.getName().contains(toDeleteDir)){
deleteDir(f);
}
}else if (f.isDirectory()){//如果是目录就递归
scanDir(f, toDeleteDir);
}
}
}
private static void deleteDir(File f) throws IOException {
System.out.println(f.getCanonicalPath() + " 确认要删除吗? (Y/n)");
Scanner scanner = new Scanner(System.in);
String choice = scanner.next();
if (choice.equals("Y") || choice.equals("y")) {
f.delete();
System.out.println("文件删除成功!");
} else {
System.out.println("文件取消删除!");
}
}
}
?进行普通文件的复制
public class Test2 {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.println("请输入源文件:>");
String rootFilePath = scanner.nextLine();
System.out.println("请输入目标文件:>");
String toFilePath = scanner.nextLine();
File rootFile = new File(rootFilePath);
if (!rootFile.isFile()){
System.out.println("输入路径不正确");
return ;
}
try(InputStream inputStream = new FileInputStream(rootFile)){
try(OutputStream outputStream = new FileOutputStream(toFilePath)){
//先读
byte[] bytes = new byte[1024];
while (true){
int len = inputStream.read(bytes);
if (len == -1){
break;
}
//只把len长度的数据放入数组
outputStream.write(bytes, 0, len);
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
?扫描指定目录,并找到名称或者内容中包含指定字符的所有普通文件(不包含目录)
public class Test3 {
public static void main(String[] args) throws IOException {
Scanner scanner = new Scanner(System.in);
System.out.println("输入源路径:>");
String rootDirPath = scanner.nextLine();
System.out.println("输入查询的关键字:>");
String word = scanner.nextLine();
File rootDir = new File(rootDirPath);
if (!rootDir.isDirectory()){
System.out.println("源路径错误");
return;
}
scanDir(rootDir, word);
}
private static void scanDir(File rootFile, String word) throws IOException {
//列出rootDir的内容
File[] files = rootFile.listFiles();
if (files == null){
return ;
}
//遍历所有内容
for (File f : files) {
if (f.isFile()){
if (containWord(f, word)){
System.out.println(f.getCanonicalPath());
}
}else if (f.isDirectory()){
scanDir(f, word);
}
}
}
//把文件中的内容拿出来
private static boolean containWord(File f, String word) {
StringBuilder stringBuilder = new StringBuilder();
try(Reader reader = new FileReader(f)){
//对于字符输入用buffer
char[] buffer = new char[1024];
while (true){
int len = reader.read(buffer);
if (len == -1){
break;
}
stringBuilder.append(buffer, 0, len);
}
} catch (IOException e) {
e.printStackTrace();
}
// indexOf 返回的是子串的下标. 如果 word 在 stringBuilder 中不存在, 则返回下标为 -1
return stringBuilder.indexOf(word) != -1;
}
}
??
谢谢你看到这, 一起加油ヽ( ̄ω ̄( ̄ω ̄〃)ゝ
|