异常处理

捕获异常

***try … catch:***捕获异常

**多 ctach 语句:**从上到下匹配,匹配成功后不再继续匹配(子类必须写在前面)

***finally:***最后执行(可不写)

1
2
3
4
5
6
7
8
9
10
11
12
public static void main(String[] args) {
try {
process1();
process2();
process3();
} catch (IOException | NumberFormatException e) {
// IOException或NumberFormatException
System.out.println("Bad input");
} catch (Exception e) {
System.out.println("Unknown error");
}
}

抛出异常

**printStackTrace():**从下往上看,看调用层次,来调试错误

抛出异常:

  1. 创建 Exception 实例

  2. throw 抛出

    1
    2
    3
    4
    5
    void process2(String s) {
    if (s==null) {
    throw new NullPointerException();
    }
    }

**防止异常覆盖:**传入 Exception 实例

1
2
3
4
5
6
7
8
9
10
static void process1() {
try {
process2();
} catch (NullPointerException e) {
throw new IllegalArgumentException(e);
}
}
static void process2() {
throw new NullPointerException();
}

**防止异常屏蔽:**用 origin 保存异常,调用 Throwable.addSuppressed()

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// exception
public class Main {
public static void main(String[] args) throws Exception {
Exception origin = null;
try {
System.out.println(Integer.parseInt("abc"));
} catch (Exception e) {
origin = e;
throw e;
} finally {
Exception e = new IllegalArgumentException();
if (origin != null) {
e.addSuppressed(origin);
}
throw e;
}
}
}

自定义异常

标准库常用异常:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
Exception
├─ RuntimeException
│ ├─ NullPointerException
│ ├─ IndexOutOfBoundsException
│ ├─ SecurityException
│ └─ IllegalArgumentException
│ └─ NumberFormatException
├─ IOException
│ ├─ UnsupportedCharsetException
│ ├─ FileNotFoundException
│ └─ SocketException
├─ ParseException
├─ GeneralSecurityException
├─ SQLException
└─ TimeoutException

自定义根异常:BaseException

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
public class BaseException extends RuntimeException {
public BaseException() {
super();
}

public BaseException(String message, Throwable cause) {
super(message, cause);
}

public BaseException(String message) {
super(message);
}

public BaseException(Throwable cause) {
super(cause);
}
}
public class UserNotFoundException extends BaseException {
}
public class LoginFailedException extends BaseException {
}

反射

Class

JVM为每个加载的 classinterface 创建 Class 实例来保存信息

**反射:**通过 Class 实例获取 class 信息的方法(Class 实例在JVM中是唯一的)

获取 Class 实例:

  1. Class cls = String.class;

  2. String s = "Hello";

    Class cls = s.getClass();

  3. Class s = Class.forName("java.lang.String");

**动态加载:**执行程序时,用到JVM才加载 class

访问字段

获取字段:

  1. Class.getField("..."):根据字段名获取 public 字段(包括父类)
  2. Class.getDeclaredFiedl("..."):根据字段名获取当前类的字段(不包括父类)
  3. Class.getFields():获取所有 public 的字段(包括父类)
  4. Class.getDeclaredFields():获取当前类的所有字段(不包括父类)

Field 对象:

  • Field.getName():返回字段名

  • Field.getType():返回字段类型

  • Field.getModifiers():返回字段修饰符

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    public final class String {
    private final byte[] value;
    }
    Field f = String.class.getDeclaredField("value");
    f.getName(); // "value"
    f.getType(); // class [B 表示byte[]类型
    int m = f.getModifiers();
    Modifier.isFinal(m); // true
    Modifier.isPublic(m); // false
    Modifier.isProtected(m); // false
    Modifier.isPrivate(m); // true
    Modifier.isStatic(m); // false

访问 private 字段:Field.setAccessible(true);

设置字段:Field.set(Object, Object)(实例,待修改的值)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
// reflection
import java.lang.reflect.Field;
public class Main {

public static void main(String[] args) throws Exception {
Object p = new Person("Xiao Ming");
Class c = p.getClass();
Field f = c.getDeclaredField("name");
f.setAccessible(true);
Object value = f.get(p);
System.out.println(value); // "Xiao Ming"
f.set(p, "Xiao Hong");
System.out.println(p.getName()); // "Xiao Hong"
}
}
class Person {
private String name;

public Person(String name) {
this.name = name;
}
}

调用方法

获取方法:

  1. Class.getMethod("..",Class...):获取某个 public 方法(包括父类)
  2. Class.getDeclaredMethod("..",Class...):获取当前类的方法(不包括父类)
  3. Class.getMethods():获取所有 public 方法(包括父类)
  4. Class.getDeclaredMethods():获取当前类的所有方法(不包括父类)

Method 对象:

  • Method.getName():返回方法名
  • Method.getReturnType():返回方法返回类型
  • Method.getParameterTypes():返回方法参数类型(Class数组)
  • Method.getModifiers():返回方法修饰符

调用方法:

  • Method.invoke(Object,...)(实例,方法参数)
  • Method.invoke(null,...):调用静态方法

访问非 public 字段:Method.setAccessible(true)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// reflection
import java.lang.reflect.Method;

public class Main {
public static void main(String[] args) throws Exception {
Person p = new Person();
Method m = p.getClass().getDeclaredMethod("setName", String.class);
m.setAccessible(true);
m.invoke(p, "Bob");
System.out.println(p.name);
}
}

class Person {
String name;
private void setName(String name) {
this.name = name;
}
}

**多态:**调用实际类型的覆写方法

调用构造方法

通过反射创建新实例:Person p = Person.class.newInstance();(只能调用该类的public无参数构造方法)

**Constructor 对象:**获取当前类的构造方法(不是父类)

  1. getConstructor(Class...):获取某个 public 的构造方法
  2. getDeclaredConstructor(Class...):获取某个构造方法
  3. getConstructors():获取所有 public 的构造方法
  4. getDeclaredConstructors():获取所有构造方法

访问非 public 构造方法:Constructor.setAccessible(true)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import java.lang.reflect.Constructor;

public class Main {
public static void main(String[] args) throws Exception {
// 获取构造方法Integer(int):
Constructor cons1 = Integer.class.getConstructor(int.class);
// 调用构造方法:
Integer n1 = (Integer) cons1.newInstance(123);
System.out.println(n1);

// 获取构造方法Integer(String)
Constructor cons2 = Integer.class.getConstructor(String.class);
Integer n2 = (Integer) cons2.newInstance("456");
System.out.println(n2);
}
}

获取继承关系

获取父类的 Class:Class.getSuperclass()

获取接口:Class.getInterfaces();(不包括父类接口)

1
2
3
4
5
6
7
8
9
10
11
12
// reflection
import java.lang.reflect.Method;

public class Main {
public static void main(String[] args) throws Exception {
Class s = Integer.class;
Class[] is = s.getInterfaces();
for (Class i : is) {
System.out.println(i);
}
}
}

集合

泛型

IO

**InputStream / OutputStream:**IO流(字节流),以 byte (字节)为最小单位

**Reader / Writer:**字符流,以 char 为最小单位

同步 vs 异步:

  1. 同步:读写IO时代码必须等待数据返回后才继续执行后续代码 (java.io
  2. 异步:读写IO时仅发出请求,然后立刻执行后续代码 (java.nio

File 对象

既可以表示文件,也可以表示目录

**创建:**需要传入路径

  1. 绝对路径:

    • Windows:File f = new File("C:\\Windows\\notepad.exe");
    • Linux:File f = new File("/usr/bin/javac");
  2. 相对路径:. 表示当前目录,.. 表示上级目录

    1
    2
    3
    4
    // 假设当前目录是C:\Docs
    File f1 = new File("sub\\javac"); // 绝对路径是C:\Docs\sub\javac
    File f3 = new File(".\\sub\\javac"); // 绝对路径是C:\Docs\sub\javac
    File f3 = new File("..\\sub\\javac"); // 绝对路径是C:\sub\javac

文件和目录

是否是已存在的文件:isFile()

是否是已存在的目录:isDirectory()

是否可读:canRead()

是否可写:canWrite()

是否可执行:canExecute()

文件字节大小:length()

创建和删除文件

创建文件:File.createNewFile()

删除文件:File.delete()

临时文件:

1
2
3
4
5
6
7
8
9
10
import java.io.*;

public class Main {
public static void main(String[] args) throws IOException {
File f = File.createTempFile("tmp-", ".txt"); // 提供临时文件的前缀和后缀
f.deleteOnExit(); // JVM退出时自动删除
System.out.println(f.isFile());
System.out.println(f.getAbsolutePath());
}
}

遍历文件和目录

列出目录下文件和子目录:

  • File.list()
  • File.listFiles()

File 对象表示目录:

  • mkdir():创建当前File对象表示的目录
  • mkdirs():创建当前File对象表示的目录(必要时将不存在的父目录也创建出来)
  • delete():删除当前File对象表示的目录(当前目录必须为空才能删除成功)

日期与时间

正则表达式

正则表达式:构成搜索模式的字符序列。在文本中搜索数据时,可以使用此搜索模式来描述要搜索的内容。

正则表达式可以是单个字符,也可以是更复杂的模式

则表达式可用于执行所有类型的文本搜索文本替换 操作。

导入 java.util.regex 包来使用正则表达式,该软件包包括一下类:

  • Pattern 类:定义模式(用于搜索)
  • Matchaer 类:用于搜索模式
  • PatternSyntaxException 类:异常类 - 指示正则表达式模式中的语法错误
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class Main {
public static void main(String[] args) {

String text = "Hello World";
Pattern pattern = Pattern.compile("hello", Pattern.CASE_INSENSITIVE);
Matcher matcher = pattern.matcher(text);
if(matcher.find()) {
System.out.println("Match found");
} else {
System.out.println("Match not found");
}
}
}

在句子中搜索单词 “hello”:

  • Pattern.compile():创建模式。

    第一个参数指示正在搜索的模式,第二个参数有一个标志,指示搜索应不区分大小写。第二个参数是可选的。

  • matcher():在字符串中搜索模式。它返回一个 Matcher 对象,其中包含有关所执行搜索的信息

  • 如果在字符串中找到模式,则 find() 方法返回 true,如果未找到模式,则返回 false

flags

compile()方法中的标志会更改搜索的执行方式。以下是其中的一些:

  • Pattern.CASE_INSENSITIVE - 执行搜索时,将忽略字母的大小写。
  • Pattern.LITERAL - 模式中的特殊字符将没有任何特殊含义,在执行搜索时将被视为普通字符。
  • Pattern.UNICODE_CASE - 将它与 CASE_INSENSITIVE 标志一起使用,也可以忽略英文字母表以外的字母的大小写

正则表达式模式

Pattern.compile() 方法的第一个参数是 pattern。它描述了正在搜索的内容。

方括号用于查找字符范围:

表示 描述
[abc] 匹配括号内的任意字符
[^abc] 匹配非括号内的字符
[0-9] 匹配0-9之间的字符

元字符是具有特殊含义的字符:

元字符 描述
| 匹配多个模式中的任意一个,cat|dog|fish只要它们中的任意一个出现在文本中,就算匹配成功
. 匹配任何单个字符,除了换行符 \n
^ 匹配字符串的开始位置,如^Hello
$ F匹配字符串的结束位置,如World$
\d 匹配任何数字字符
\s 匹配任何空白字符(如空格、制表符、换行符等)
\b 匹配单词边界,\bWORD 匹配以 “WORD” 开头的单词,WORD\b 匹配以 “WORD” 结尾的单词
\uxxxx 匹配由四个十六进制数字表示的 Unicode 字符,\u0041 匹配 Unicode 字符 ‘A’

量词定义数量:

量词 描述
n+ 匹配包含至少一个 n 的字符串(即 n 至少出现一次)
n* 匹配包含零个或多个 n 的字符串(即 n 可以出现任意次,包括零次)
n? 匹配包含零个或一个 n 的字符串(即 n 要么出现一次,要么不出现)
n{x} 匹配包含恰好 X 个 n 的字符串
n{x,y} 匹配包含 X 到 Y 个 n 的字符串
n{x,} 匹配包含至少 X 个 n 的字符串

线程

线程允许程序通过同时执行多项事务来更高效地运行,可用于在后台执行复杂的任务,而不会中断主程序。

创建:

  • 扩展 Thread 类并覆盖其 run()

    1
    2
    3
    4
    5
    public class Main extends Thread {
    public void run() {
    System.out.println("This code is running in a thread");
    }
    }
  • 实现 Runnable 接口:

    1
    2
    3
    4
    5
    public class Main implements Runnable {
    public void run() {
    System.out.println("This code is running in a thread");
    }
    }

运行:

  • 扩展 Thread 类:创建该类的实例并调用 start() 方法来运行

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    public class Main extends Thread {
    public static void main(String[] args) {
    Main thread = new Main();
    thread.start();
    System.out.println("This code is outside of the thread");
    }
    public void run() {
    System.out.println("This code is running in a thread");
    }
    }
  • 实现 Runnable 接口:将类的实例传递给 Thread 对象的构造函数,然后调用线程的 start() 方法

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    public class Main implements Runnable {
    public static void main(String[] args) {
    Main obj = new Main();
    Thread thread = new Thread(obj);
    thread.start();
    System.out.println("This code is outside of the thread");
    }
    public void run() {
    System.out.println("This code is running in a thread");
    }
    }

extends 和 implements 的区别:

当一个类扩展 Thread 类时,你不能扩展任何其他类。但通过实现 Runnable 接口,也可以从另一个类扩展,例如: class MyClass extends OtherClass implements Runnable .

并发

由于线程与程序的其他部分同时运行,因此无法知道代码将按什么顺序运行。当线程和主程序读取和写入相同的变量时,这些值是不可预测的。由此产生的问题称为并发问题。

例如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public class Main extends Thread {
public static int amount = 0;

public static void main(String[] args) {
Main thread = new Main();
thread.start();
System.out.println(amount);
amount++;
System.out.println(amount);
}

public void run() {
amount++;
}
}

有时会输出 0 2,有时会输出 0 1

为避免并发问题,最好在线程之间共享尽可能少的属性。如果需要共享属性,一种可能的解决方案是使用 isAlive() 方法检查线程是否已经运行完毕,然后再使用任何 线程可以更改的属性。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
public class Main extends Thread {
public static int amount = 0;

public static void main(String[] args) {
Main thread = new Main();
thread.start();
// Wait for the thread to finish
while(thread.isAlive()) {
System.out.println("Waiting...");
}
// Update amount and print its value
System.out.println("Main: " + amount);
amount++;
System.out.println("Main: " + amount);
}
public void run() {
amount++;
}
}
/*Waiting...
Waiting...
Waiting...
Waiting...
Main: 1
Main: 2*/

Lambda

Java 8 中添加,lambda 表达式是一个简短的代码块,它接受参数并返回一个值。Lambda 表达式类似于方法,但它们不需要名称,并且可以直接在方法的主体中实现

语法:

  • 一个参数

    1
    parameter -> expression
  • 多个参数

    1
    (parameter1, parameter2) -> expression
  • 为了执行更复杂的作,可以将代码块与大括号一起使用。如果 lambda 表达式需要返回一个值,则代码块应具有 return 语句。

    1
    (parameter1, parameter2) -> { code block }

使用:

  • 作为方法的参数:

    ArrayListforEach() 方法中使用 lambda 表达式来打印列表中的每一项

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    import java.util.ArrayList;

    public class Main {
    public static void main(String[] args) {
    ArrayList<Integer> numbers = new ArrayList<Integer>();
    numbers.add(5);
    numbers.add(9);
    numbers.add(8);
    numbers.add(1);
    numbers.forEach( (n) -> { System.out.println(n); } );
    }
    }

    当方法参数类型是接口时,Lambda 表达式可以存储在变量中。Lambda 表达式需要匹配接口方法的参数数量和返回类型

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    import java.util.ArrayList;
    import java.util.function.Consumer;

    public class Main {
    public static void main(String[] args) {
    ArrayList<Integer> numbers = new ArrayList<Integer>();
    numbers.add(5);
    numbers.add(9);
    numbers.add(8);
    numbers.add(1);
    Consumer<Integer> method = (n) -> { System.out.println(n); };
    numbers.forEach( method );
    }
    }

    Java 内置了许多此类接口,例如列表使用的 Consumer 接口(位于 java.util 包中)

  • 作为函数式接口的实现:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    interface StringFunction {
    String run(String str);
    }

    public class Main {
    public static void main(String[] args) {
    StringFunction exclaim = (s) -> s + "!";
    StringFunction ask = (s) -> s + "?";
    printFormatted("Hello", exclaim);
    printFormatted("Hello", ask);
    }
    public static void printFormatted(String str, StringFunction format) {
    String result = format.run(str);
    System.out.println(result);
    }
    }

高级排序

ComparatorComparable 接口允许您指定用于对对象进行排序的规则

Comparator

Comparator 接口:使用compare()方法创建一个类,来比较两个对象

compare() 方法:返回一个数字

  • 如果第一个对象应位于列表中的第一个,则为负数
  • 如果第二个对象应位于列表中的第一个,则为正数
  • 如果 顺序 无关紧要,则为零
1
2
3
4
5
6
7
8
9
10
11
12
13
// Sort Car objects by year
class SortByYear implements Comparator {
public int compare(Object obj1, Object obj2) {
// Make sure that the objects are Car objects
Car a = (Car) obj1;
Car b = (Car) obj2;

// Compare the objects
if (a.year < b.year) return -1; // The first car has a smaller year
if (a.year > b.year) return 1; // The first car has a larger year
return 0; // Both cars have the same year
}
}

**使用:**将其作为参数传递给排序方法

1
2
3
// Use a comparator to sort the cars
Comparator myComparator = new SortByYear();
Collections.sort(myCars, myComparator);

例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;

// Define a Car class
class Car {
public String brand;
public String model;
public int year;

public Car(String b, String m, int y) {
brand = b;
model = m;
year = y;
}
}

// Create a comparator
class SortByYear implements Comparator {
public int compare(Object obj1, Object obj2) {
// Make sure that the objects are Car objects
Car a = (Car) obj1;
Car b = (Car) obj2;

// Compare the year of both objects
if (a.year < b.year) return -1; // The first car has a smaller year
if (a.year > b.year) return 1; // The first car has a larger year
return 0; // Both cars have the same year
}
}

public class Main {
public static void main(String[] args) {
// Create a list of cars
ArrayList<Car> myCars = new ArrayList<Car>();
myCars.add(new Car("BMW", "X5", 1999));
myCars.add(new Car("Honda", "Accord", 2006));
myCars.add(new Car("Ford", "Mustang", 1970));

// Use a comparator to sort the cars
Comparator myComparator = new SortByYear();
Collections.sort(myCars, myComparator);

// Display the cars
for (Car c : myCars) {
System.out.println(c.brand + " " + c.model + " " + c.year);
}
}
}

Lambda:

将比较器替换为 lambda 表达式,该表达式具有与 compare() 方法相同的参数和返回值(代码更短)

1
2
3
4
5
6
7
Collections.sort(myCars, (obj1, obj2) -> {
Car a = (Car) obj1;
Car b = (Car) obj2;
if (a.year < b.year) return -1;
if (a.year > b.year) return 1;
return 0;
});

Comparable

Comparable 接口:使用 compareTo() 方法指定自己的排序规则

compareTo() 方法:将对象作为参数,把 comparable 与参数进行比较,返回一个数字

  • 如果 Comparable 排在列表的首位,则为负数
  • 如果另一个对象应该在列表中排在第一位,则为整数
  • 如果 顺序 无关紧要,则为零
1
2
3
4
5
6
7
8
9
10
11
12
class Car implements Comparable {
public String brand;
public String model;
public int year;

// Decide how this object compares to other objects
public int compareTo(Object obj) {
Car other = (Car)obj;
if(year < other.year) return -1; // This object is smaller than the other one
if(year > other.year) return 1; // This object is larger than the other one
return 0; // Both objects are the same
}

使用:

Comparable 是接口而不是比较器

许多Java类实现了 Comparable 接口,如StringInteger,所以它们不需要比较器排序

1
2
3
4
5
6
7
8
9
10
11
12
13
class Car implements Comparable {
public String brand;
public String model;
public int year;

// Decide how this object compares to other objects
public int compareTo(Object obj) {
Car other = (Car)obj;
if(year < other.year) return -1; // This object is smaller than the other one
if(year > other.year) return 1; // This object is larger than the other one
return 0; // Both objects are the same
}
}

例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;

// Define a Car class which is comparable
class Car implements Comparable {
public String brand;
public String model;
public int year;

public Car(String b, String m, int y) {
brand = b;
model = m;
year = y;
}

// Decide how this object compares to other objects
public int compareTo(Object obj) {
Car other = (Car)obj;
if(year < other.year) return -1; // This object is smaller than the other one
if(year > other.year) return 1; // This object is larger than the other one
return 0; // Both objects are the same
}
}

public class Main {
public static void main(String[] args) {
// Create a list of cars
ArrayList<Car> myCars = new ArrayList<Car>();
myCars.add(new Car("BMW", "X5", 1999));
myCars.add(new Car("Honda", "Accord", 2006));
myCars.add(new Car("Ford", "Mustang", 1970));

// Sort the cars
Collections.sort(myCars);

// Display the cars
for (Car c : myCars) {
System.out.println(c.brand + " " + c.model + " " + c.year);
}
}
}

技巧

正向:

1
return a.year - b.year;

反向:

1
return b.year - a.year;

区别

  • comparator:具有一种方法的对象

  • comparable:将自身与其他对象进行比较的对象

使用 Comparable 接口会更容易,但 Comparator 接口功能更强大,因为它允许您对任何类型的对象进行排序,即使您无法更改其代码

文件操作

java.io 包中的 File 类允许我们处理文件

**使用 file 类:**创建该类的对象,并指定文件名或目录名称

1
2
3
import java.io.File;  // Import the File class

File myObj = new File("filename.txt"); // Specify the filename

File 类的方法:

方法 类型 描述
canRead() Boolean 测试文件是否可读
canWrite() Boolean 测试文件是否可写
createNewFile() Boolean 创建一个空的文件。如果文件已经存在,则返回 false;如果文件成功创建,则返回 true
delete() Boolean 删除文件。如果文件成功删除,则返回 true;如果删除失败或文件不存在,则返回 false
exists() Boolean 测试文件是否存在
getName() String 返回文件的名称(即不包括路径部分)
getAbsolutePath() String 返回文件的绝对路径
length() Long 返回文件的大小,单位是字节(byte)
list() String[] 如果文件是一个目录,返回该目录下所有文件和子目录的名称数组
mkdir() Boolean 创建一个目录

创建:createNewFile()

文件成功创建: true,文件已存在: false。注意:该方法必须包含在 try...catch,因为如果发生错误(如果由于某种原因无法创建文件),它会抛出 IOException

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import java.io.File;  // Import the File class
import java.io.IOException; // Import the IOException class to handle errors

public class CreateFile {
public static void main(String[] args) {
try {
File myObj = new File("filename.txt");
if (myObj.createNewFile()) {
System.out.println("File created: " + myObj.getName());
} else {
System.out.println("File already exists.");
}
} catch (IOException e) {
System.out.println("An error occurred.");
e.printStackTrace();
}
}
}

在特定目录中创建:

1
File myObj = new File("C:\\Users\\MyName\\filename.txt");

Mac、Linux可直接编写路径

写入文件:

FileWriterwrite(),完成写入后用 close() 关闭。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import java.io.FileWriter;   // Import the FileWriter class
import java.io.IOException; // Import the IOException class to handle errors

public class WriteToFile {
public static void main(String[] args) {
try {
FileWriter myWriter = new FileWriter("filename.txt");
myWriter.write("Files in Java might be tricky, but it is fun enough!");
myWriter.close();
System.out.println("Successfully wrote to the file.");
} catch (IOException e) {
System.out.println("An error occurred.");
e.printStackTrace();
}
}
}

读取:Scanner

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
import java.io.File;  // Import the File class
import java.io.FileNotFoundException; // Import this class to handle errors
import java.util.Scanner; // Import the Scanner class to read text files

public class ReadFile {
public static void main(String[] args) {
try {
File myObj = new File("filename.txt");
Scanner myReader = new Scanner(myObj);
while (myReader.hasNextLine()) {
String data = myReader.nextLine();
System.out.println(data);
}
myReader.close();
} catch (FileNotFoundException e) {
System.out.println("An error occurred.");
e.printStackTrace();
}
}
}

获取文件信息:File 方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import java.io.File;  // Import the File class

public class GetFileInfo {
public static void main(String[] args) {
File myObj = new File("filename.txt");
if (myObj.exists()) {
System.out.println("File name: " + myObj.getName());
System.out.println("Absolute path: " + myObj.getAbsolutePath());
System.out.println("Writeable: " + myObj.canWrite());
System.out.println("Readable " + myObj.canRead());
System.out.println("File size in bytes " + myObj.length());
} else {
System.out.println("The file does not exist.");
}
}
}

注意:Java API 中有许多可用的类可用于在 Java 中读取和写入文件: FileReader, BufferedReader, Files, Scanner, FileInputStream, FileWriter, BufferedWriter, FileOutputStream 等。使用哪一个取决于你正在使用的 Java 版本,你是否需要读取字节或字符,以及文件/行的大小等

删除文件:delete()

1
2
3
4
5
6
7
8
9
10
11
12
import java.io.File;  // Import the File class

public class DeleteFile {
public static void main(String[] args) {
File myObj = new File("filename.txt");
if (myObj.delete()) {
System.out.println("Deleted the file: " + myObj.getName());
} else {
System.out.println("Failed to delete the file.");
}
}
}

**删除文件夹:**删除文件夹的前提是 文件夹必须为空

1
2
3
4
5
6
7
8
9
10
11
12
import java.io.File; 

public class DeleteFolder {
public static void main(String[] args) {
File myObj = new File("C:\\Users\\MyName\\Test");
if (myObj.delete()) {
System.out.println("Deleted the folder: " + myObj.getName());
} else {
System.out.println("Failed to delete the folder.");
}
}
}