IO
一、IO概述
1.什么是IO
输入和输出都是相对内存来说的,从硬盘往内存中存就是输入,从内存往硬盘中存就是输出。以下图也可也解释:
2.分类方式
有多种分类方式,一种是按照流的方向进行分类:
以内存作为参考,往内存中去,叫做输入(input),或者叫做读。从内存中出去,叫做输出(output),或者叫做写。
另一种按照读取数据方式不同进行分类:
字节流:一次读取一个字节byte,等同于一次读取8个二进制,这种流是万能的,什么都可以读。
字符流:一次读取一个字符,这种流是为了方便读取普通文本文件而存在的。
3.四大家族
java.io.InputStream 字节输入流
java.io.OutputStream 字节输出流
java.io.Reader 字符输入流
java.io.Writer 字符输出流
四大家族的首领都是抽象类(Abstract),所有的流都实现了Closeable接口,都是可关闭的,都有close()方法。流是一个管道,是内存和硬盘中的通道,用完之后要关闭。
所有的输出流都实现了Flushable接口,都是可刷新的,都有flush()方法,输出流在最终输出之后,要刷新flush一下,这个刷新表示将通道/管道当中剩余未输出的数据强行输出完。如果没有flush(),可能会丢失数据。
注意:以"Stream"结尾的都是字节流,以"Reader/Writer"结尾的都是字符流。
4.需要掌握的流
在java.io下需要掌握的流有16个:
文件专属:
- java.io.FileInputStream
- java.io.FileOutputStream
- java.io.FileReader
- java.io.FileWriter
转换流(将字节流转换成字符流的)
- java.io.InputStreamReader
- java.io.OutputStreamWriter
缓冲流专属:
- java.io.BufferedInputStream
- java.io.BufferedOutputStream
- java.io.BufferedReader
- java.io.BufferedWriter
数据流专属:
- java.io.DataInputStream
- java.io.DataOutputStream
对象专属流:
- java.io.ObjectInputStream
- java.io.ObjectOutputStream
标准输出流:
- java.io.PrintWriter
- java.io.PrintStream
二、文件专属流
文件专属流有FileInputStream、FileOutputStream、FileReader、FileWriter四种,以下重点讲解FileInputStream和FileOutputStram。
1.FileInputStream
FileInputStream是文件字节输入流,完成读的操作(从硬盘到内存),是万能的,任何类型的文件都可以采用这个流来读。
现在有一个文件:test.txt,路径为:C:\Users\DRL\Desktop\test,IDEA中会把"“变成”\",因为java中反斜杠表示转义,以下是使用read的不同方式来读。
1.1 read()
read()方法返回字节的ASCALL码大小,指针指向最后一个字节之后会返回-1,示例图如下:
代码及结果如下:
public static void main(String[] args) {
FileInputStream fis=null;
try {
//创建流
fis=new FileInputStream("C:\\Users\\DRL\\Desktop\\test.txt");
//开始读
int readData=0;
while ((readData=fis.read())!=-1){
System.out.println(readData);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (fis!=null){
try {
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
1.2 read(byte[] b)
使用read()方法一次只能读一个字节,过于慢,可以使用read(byte[ ] b),返回数组中的元素个数,一次最多可以读b.length个字节,往byte数组中读。
当文件中的字节未被读完时,可以再次进行read(byte[] b)方法读取,当文件中的字节全部读完会返回-1。
【注意】:若文件中有7个字节,分别是abcdef,byte数组容量为4,第一次取4个字节为abcd,剩下了两个字节ef,那么第二次取字节会将第一次的前两个覆盖掉,取出的字节为efcd,第三次由于文件中没有可以取出的字节,那么就会返回-1,如下图所示:
代码及结果如下:
public static void main(String[] args) {
FileInputStream fis=null;
try {
fis=new FileInputStream("C:/Users/DRL/Desktop/test.txt");
byte[] bytes=new byte[4];
int readCount=0;
while ((readCount=fis.read(bytes))!=-1){
System.out.print(new String(bytes,0,readCount));
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
1.3 available
方法全称为:int available( ),返回当前流中剩余的没有读到的字节数量,使用方法如下:
public static void main(String[] args) {
FileInputStream fis=null;
try {
//一共有6个字节
fis=new FileInputStream("C:\\Users\\DRL\\Desktop\\test.txt");
int read=fis.read();//读了一个字节
System.out.println(fis.available());//还剩下5个字节没有读
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (fis == null) {
try {
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
这个方法也可以和read(byte[ ] b)配合使用,可以先获取文件中的字节数,然后将其传参给byte数组,直接遍历文件中的字节,使用方法如下:
public static void main(String[] args) {
FileInputStream fis=null;
try {
fis=new FileInputStream("C:\\Users\\DRL\\Desktop\\test.txt");
byte[] bytes=new byte[fis.available()];//使用available方法创建文件中字节大小的数组
int readCount=0;
while ((readCount=fis.read(bytes))!=-1){
System.out.println(new String(bytes));
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (fis == null) {
try {
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
1.4 skip
方法的全称是:long skip(long n),将会跳过n个字节,使用方法如下:
public static void main(String[] args) {
FileInputStream fis=null;
try {
fis=new FileInputStream("C:\\Users\\DRL\\Desktop\\test.txt");
byte[] bytes=new byte[fis.available()];//使用available方法创建文件中字节大小的数组
int readCount=0;
fis.skip(3);
//while循环之后是def,跳过了3个字节,将abc跳过了
while ((readCount=fis.read(bytes))!=-1){
System.out.println(new String(bytes));
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (fis == null) {
try {
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
2.FileOutputStream
文件字节输出流,负责写,从内存到硬盘。
FileOutputStream的构造方法有两种,一种是只带有文件名的构造方法,这种很有可能会将原先文件中的数据清空,然后重写入新数据。另一种是带有两个参数,分别是文件名和boolean类型的参数append,若为true,则将数据写入原文件末尾,若为false,则将数据写入文件中的原数据全部删除,然后写上新数据。代码和文档截图如下:
public static void main(String[] args) {
FileOutputStream fos=null;
try {
//创建流,并将数据写入"myFile"文件的末尾处
fos=new FileOutputStream("myFile",true);
//创建流,并将文件"myFile"中的数据清除之后添加新的数据
// fos=new FileOutputStream("myFile",false);
//先给byte数组中添加数据
byte[] bytes={102,103,104,105};
fos.write(bytes);
//写完之后要刷新
fos.flush();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (fos != null) {
try {
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
2.1 写入字符串
要向文件中写入字符串类型数据时,需要先将字符串转换成buye数组,然后向文件中写入byte数组,代码如下:
public static void main(String[] args) {
FileOutputStream fos=null;
try {
fos=new FileOutputStream("myFile",false);
String a="我爱中国!";
//将字符串转换为byte数组
byte[] bytes=a.getBytes();
//写入文件
fos.write(bytes);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (fos != null) {
try {
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
2.2 拷贝文件
【注意】:FileInputStream和FileOutputStream对任何文件都可以进行读写!
利用FileInputStream和FileOutputStream进行文件的拷贝,比如有一个文件需要从D盘拷到C盘,拷贝过程中,将文件从D盘中读到内存中,同时将文件从内存写入到D盘中,以下是拷贝的简单实现:
public static void main(String[] args) {
BufferedReader br=null;
String s;
try {
// //创建文件输入字节流
// FileInputStream in=new FileInputStream("myFile");
// //由于字节流无法直接作为参数传入BufferedReader中,需要转换流将其转换成字符流
// InputStreamReader reader=new InputStreamReader(in);
// //将转换好的fis参入BufferedReader中
// br=new BufferedReader(reader);
//合并之后如下一行即可解决
br=new BufferedReader(new InputStreamReader(new FileInputStream("myFile")));
while ((s=br.readLine())!=null){
System.out.println(s);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if(br!=null){
try {
br.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
3.FileReader
【注意】:word文件不是普通文本,故不能用FileReader来读。
FileReader是文件字符输入流,需要用char数组来存,只能读取普通文本,在读取文本时比较方便快捷,FileReader的使用方式和FileInputStream类似,以下是其使用方法:
public static void main(String[] args) {
FileReader reader=null;
try {
//构造输入流
reader=new FileReader("myFile");
//创建字符数组来存储从内存读到的字符
char[] chars=new char[10];
int readCount=0;
//开始读
while ((readCount=reader.read(chars))!=-1){
System.out.print(new String(chars,0,readCount));
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally {
if (reader != null) {
try {
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
4.FileWriter
【注意】:word不是普通文本,故不能用FileWriter来写。
FileWriter是文件字符输出流,只能输出普通文本,其和FileOutputStream使用方式类似。
Writer的构造方法有两种,一种是只带有文件名的构造方法,这种很有可能会将原先文件中的数据清空,然后重写入新数据。另一种是带有两个参数,分别是文件名和boolean类型的参数append,若为true,则将数据写入原文件末尾,若为false,则将数据写入文件中的原数据全部删除,然后写上新数据。代码和文档截图如下:
public static void main(String[] args) {
FileWriter writer=null;
try {
//构造文件输出流对象
writer=new FileWriter("copyFile");
//char数组中存入要输出给文件的数据
char[] chars={'你','好','吗','?'};
writer.write(chars);
//刷新
writer.flush();
} catch (IOException e) {
e.printStackTrace();
}finally {
if (writer != null) {
try {
writer.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
FileWriter也可以直接写入字符串,以下为示例代码:
public static void main(String[] args) {
FileWriter writer=null;
try {
//构造文件输出流对象
writer=new FileWriter("copyFile");
//char数组中存入要输出给文件的数据
String s="你现在过的怎么样?";
writer.write(s);
//刷新
writer.flush();
} catch (IOException e) {
e.printStackTrace();
}finally {
if (writer != null) {
try {
writer.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
4.1 拷贝文件
利用FileReader和FileWriter来拷贝文本文件。
【注意】:只能拷贝文本文件,word文件也不可以!代码如下:
public static void main(String[] args) {
FileReader reader=null;
FileWriter writer=null;
try {
//构造文件输入流对象
reader=new FileReader("myFile");
//构造文件输出流对象
writer=new FileWriter("copyFile");
int readCount=0;
//char数组,用来暂时存放要拷贝的数据
char[] chars=new char[5];
while ((readCount=reader.read(chars))!=-1){
writer.write(new String(chars,0,readCount));
}
//刷新
writer.flush();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
finally {
if (reader!=null){
try {
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (writer!=null){
try {
writer.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
三、缓冲流
1.BufferedReader
带有缓冲区的字符输入流,使用这个流的时候不需要自定义char/byte数组,自带缓冲。
构造BufferedReader对象时,需要传入另外一个字符流作为参数,并且这个流叫做节点流,外部负责包装的流叫做包装流或处理流。若想要传入字节流,那么需要将字节流转换成字符流,用InputStreamReader/OutputStreamWriter来转换,使用方法如下:
public static void main(String[] args) {
BufferedReader br=null;
String s;
try {
//创建文件输入字节流
FileInputStream in=new FileInputStream("myFile");
//由于字节流无法直接作为参数传入BufferedReader中,需要转换流将其转换成字符流
InputStreamReader reader=new InputStreamReader(in);
//将转换好的fis参入BufferedReader中
br=new BufferedReader(reader);
while ((s=br.readLine())!=null){
System.out.println(s);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if(br!=null){
try {
br.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
对于下面这个程序代码来说,BufferedReader就是包装流/处理流,FileReader就是节点流。要关闭流时,只需要关闭包装流/处理流,节点流在底层已经被关闭了。
//构建BufferedReader之前需要构建一个字节流进行参数传入
FileReader fileReader=new FileReader("myFile");
//构建BufferedReader,并传入fileReader参数
reader=new BufferedReader(fileReader);
1.1 readLine方法
方法全称为:String readLine(),返回值为String类型,可以一行一行读文本,但不带换行符,在读完一行之后需要手动换行,当文本中数据读完时会返回null,使用方法如下:
public static void main(String[] args) {
BufferedReader bufferedReader=null;
String s=null;
try {
bufferedReader=new BufferedReader(new FileReader("myFile"));
while ((s=bufferedReader.readLine())!=null){
System.out.println(s);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally {
if (bufferedReader!=null){
try {
bufferedReader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
2.BufferedWriter
BufferedWriter是缓冲输出流,和BufferedReader用法一样,要传字符输出流参数,若想传字节输出流参数的话,需要用OutputStreamWriter来将字节流转换成字符流,使用方法如下:
public static void main(String[] args) {
//创建BufferedWriter对象
BufferedWriter bw=null;
try {
//构建BufferedWriter对象
// bw=new BufferedWriter(new FileWriter("copyFile"));
//若要将字节输出流作为参数传进去,则需要OutputStreamWriter进行转换
bw=new BufferedWriter(new OutputStreamWriter(new FileOutputStream("copyFile")));
bw.write("你好呀!");
bw.flush();
} catch (IOException e) {
e.printStackTrace();
}finally {
if (bw!=null){
try {
bw.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
2.1拷贝文件
利用缓冲流拷贝文件,以下是节点流为字符流的例子,如果节点流为字节流,那么需要将子节点转换为字符流再进行传参:
public static void main(String[] args) {
BufferedReader br=null;
BufferedWriter bw=null;
String s=null;
try {
//利用字符流输入输出进行拷贝文件
br=new BufferedReader(new FileReader("myFile"));
bw=new BufferedWriter(new FileWriter("copyFile"));
//利用字节流作为节点流,则需要将字节流转换为字符流
br=new BufferedReader(new InputStreamReader(new FileInputStream("myFile")));
bw=new BufferedWriter(new OutputStreamWriter(new FileOutputStream("copyFile")));
while((s=br.readLine())!=null){
bw.write(s);
bw.write("\n");
}
//输出流用完要刷新
bw.flush();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (br!=null){
try {
br.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (bw!=null){
try {
bw.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
四、数据流(了解)
数据专属的流,这个流可以将数据连通数据的类型一并写入文件。
【注意】:这个文件不是普通文档(用记事本打不开)。
1.DataOutputStream
数据输出字节流,需要传入节点流,并且节点流也为字节流,使用DataOutputStream流输出,不仅会将数据输出,也会将数据的类型输出,用记事本打开会乱码,这种文件只能用DataInputStream输入,所以这个流用的不多,以下是其使用方法:
public static void main(String[] args) {
DataOutputStream dos=null;
try {
//构造数据输出字节流,需要传入节点流
dos=new DataOutputStream(new FileOutputStream("myFile",false));
byte b=10;
short s=20;
int i=100;
long l=500L;
char c='a';
//将以上数据输出文件中,不仅会将数据本身输出,也会将数据类型一并输出
dos.writeByte(b);
dos.writeShort(s);
dos.writeInt(i);
dos.writeLong(l);
dos.writeChar(c);
//刷新
dos.flush();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally{
if(dos!=null){
dos.close();
}
}
}
输出结果用记事本打开之后乱码,如下:
2.DataInoutStream
数据输入字节流,用数据输出字节流输出的文件只能用这个流来读,代码如下:
public static void main(String[] args) {
DataInputStream dis=null;
try {
//构造数据输入字节流对象,并传入节点流
dis=new DataInputStream(new FileInputStream("myFile"));
byte b=dis.readByte();
short s=dis.readShort();
int i=dis.readInt();
long l=dis.readLong();
char c=dis.readChar();
System.out.println(b);
System.out.println(s);
System.out.println(i);
System.out.println(l);
System.out.println(c);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally {
if (dis!=null){
try {
dis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
五、标准输出流
1.PrintStream
标准的字节输出流,默认输出到控制台,标准输出流不需要关闭,标准输出流其实就是经常使用的System.out.println(),使用代码如下:
public static void main(String[] args) {
//联合起来写
System.out.println("hello!");
//分开写也可以
PrintStream ps=System.out;
ps.println("hello!");
}
1.1 改变标准输出位置
可以改变标准输出位置到文件中,这个也是日志实现的原理,以下为改变输出到文件中的代码:
public static void main(String[] args) {
//改变标准输出到文件中
try {
//将标准输出到控制台改到输出到"myFile"文件中
System.setOut(new PrintStream(new FileOutputStream("myFile")));
System.out.println("你好呀!");
System.out.println("你是谁?");
System.out.println("我是你爹!");
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
1.2 日志实现
可以通过改变标准输出流的输出位置,实现日志功能,下面是日志实现及测试代码:
日志实现代码:
public static void log(String message){
try {
//将标准输出流指向一个文件
PrintStream ps=new PrintStream(new FileOutputStream("log.txt",true));
//改变输出方向
System.setOut(ps);
//记录当前时间
Date nowDate=new Date();
//改变时间格式
SimpleDateFormat sdf=new SimpleDateFormat();
String setString=sdf.format(nowDate);
System.out.println(setString+":"+message);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
测试:
public static void main(String[] args){
logger.log("调用了gc()方法,建议使用垃圾回收机制");
logger.log("发生了类加载异常");
logger.log("发生了空指针异常");
}
结果:
六、对象流
1.序列化和反序列化
序列化:Serialize,java对象存储到文件中,将java对象的状态保存下来的过程。
反序列化:DeSerialize,将硬盘上的数据重新恢复成到内存当中,恢复成java对象。
2.ObjectOutputStream
ObjectOutputStream是用来序列化的,在创建ObjectOutputStream时需要传参字节输出流,并且使用writeObject()方法对对象进行序列化时需要给自定义类型实现"Serializable"接口,这个接口里不用重写任何方法,只是为了得到序列化版本号。
序列化之后不能直接用记事本打开文件,只能用对象输入字节流打开,使用方法如下:
public class Test01 {
public static void main(String[] args) throws Exception{
//new对象时需要传入字节输出流对象
ObjectOutputStream oos=new ObjectOutputStream(new FileOutputStream("student"));
//序列化
oos.writeObject(new Student(11,"张三"));
//刷新
oos.flush();
//关闭
oos.close();
}
}
class Student implements Serializable{
private int id;
private String name;
public Student(int id, String name) {
this.id = id;
this.name = name;
}
public Student() {
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "Student{" +
"id=" + id +
", name='" + name + '\'' +
'}';
}
}
2.1 序列化多个对象
当需要同时序列化多个对象时,可以将这些对象装在集合中,然后序列中集合即可,代码如下:
【注意】:
Student类需要继承Serializable接口,这个接口中是个空的,也不用实现任何方法,但继承这个接口后会有一个序列码,JVM可以识别出来。
要读取时按照正常流程读即可,读取时返回的Object类型就是存进去的集合类型,可以直接强转成List集合然后遍历。
public static void main(String[] args) throws Exception{
//创建集合,将对象装进集合中
List<Student> list=new ArrayList<>();
list.add(new Student(18,"张三"));
list.add(new Student(20,"李四"));
list.add(new Student(25,"王麻子"));
//创建对象输出字节流对象
ObjectOutputStream oos=new ObjectOutputStream(new FileOutputStream("students"));
//开始序列化
oos.writeObject(list);
//刷新
oos.flush();
//关闭
oos.close();
}
3.ObjectInputStream
ObjectInputStream是对硬盘上的文件进行反序列化,就是进行读操作,与ObjectInputStream使用方法相似。
被ObjectOutputStream序列化之后的文件只能用ObjectOutputStream来读取,以下是使用方法:
public static void main(String[] args) throws Exception{
//创建对象输入字节流
ObjectInputStream ois=new ObjectInputStream(new FileInputStream("student"));
Object o = ois.readObject();
System.out.println(o);
}
4.transient关键字
当不想让类中的某个元素被序列化的时候,可以给这个元素前加上"transient"关键字,这个关键字表示“游离的”,不参加序列化操作。
不参加序列化的元素在进行反序列化的时候,对象的这个属性会为null,即使存进去的时候这个属性是有值的。
5.序列化版本号
上面提到参与序列化的自定义类型需要继承Serializable接口,但这个接口中没有任何方法,但JVM看到这个接口后会自动生成一个序列化版本号,但序列化版本号有什么作用呢,以下例子可以说明:
十年前有一个实体类被序列化了,十年后需要优化程序,给实体类中添加了一个属性,然后进行反序列化会异常,十年之前生成的本地序列号和现在生成的序列号不同,报错如下:
java.io.InvalidClassException: com.drl.Connection.Student;
local class incompatible:
stream classdesc serialVersionUID = -8551277354121190554(十年后)
local class serialVersionUID = -8062692542557784925(十年前)
java语言中是采用什么机制区分类的?
第一:首先通过类名来区分类,若类名不一样肯定不是一个类
第二:如果类名一样,靠序列化版本号进行区分
【重要】:凡是一个类实现了Serializabel接口,建议给该类提供一个固定不变的序列化版本号,以后这个类即使改变了,但是版本号不变,java虚拟机会认为是一个类,就不会报错,可参考ArrayList:
七、File类常用方法
File类和四大家族没有关系,所以File类不能完成文件的读和写。
File是文件名和路径名的抽象表示形式。D:\work\blog,这是一个File对象,C:\Users\DRL\Desktop\test.txt,这也是一个File对象。一个File对象有可能是目录,也有可能是文件。
1.exist
方法全称为:boolean exist(),判断File中的文件路径是否存在,存在返回true,不存在返回false,以下为使用方法:
public static void main(String[] args) {
File file=new File("D:\\file");
boolean exists = file.exists();
System.out.println(exists);//此时文件中没有此路径,返回false
}
2.creatNewFile
方法全称为:boolean creatNewFile(),在创建File对象时需要传入路径,在此路径下创建文件,若创建成功返回true,若创建失败返回false,代码和新建文件如下:
public static void main(String[] args) {
File file=new File("D:\\file");
boolean exists = file.exists();
System.out.println(exists);//此时文件中没有此路径,返回false
try {
//在"D:/file"创建file文件
boolean newFile = file.createNewFile();
System.out.println(newFile);
} catch (IOException e) {
e.printStackTrace();
}
}
3.mkdir
方法全称为:boolean mkdir(),在路径的位置上创建目录,创建成功返回true,创建失败返回false。
【注意】:当此目录上有creatNewFile()方法创建的文件时,则不会创建文件夹目录。
public static void main(String[] args) {
//创建File文件对象
File file=new File("D://file");
//在"D://file"位置上创建目录
boolean mkdir = file.mkdir();
System.out.println(mkdir);
}
4.mkdirs
方法全程为:boolean mkdirs(),创建多层目录,需在路径中添加多层,如下代码和结果:
public static void main(String[] args) {
//创建File文件对象
File file=new File("D:/file/test1/test2");
//在"D:/file"位置上创建目录
boolean mkdirs = file.mkdirs();
System.out.println(mkdirs);
}
5.getParent
方法全程为:String getParent(),获取当前路径的父路径,使用方法如下:
public static void main(String[] args) {
//创建File文件对象
File file=new File("D:/file/test1/test2");
//获取当前路径的父路径
String parent = file.getParent();//D:\file\test1
System.out.println(parent);
}
6.getAbsolutePath
方法全称为:String getAbsolutePath(),获取当前文件的绝对路径,使用方法如下:
【注意】:idea上的文件路径和所在的项目目录是一个级别的。
public static void main(String[] args) {
//创建File对象
File file=new File("myFile");
//获取"myFile"的绝对路径
System.out.println(file.getAbsolutePath());//E:\work\learnBySelf\collection\myFile
}
7.listFiles
方法全称为:File[ ] listFiles(),获取当前目录下的所有子目录和文件,使用方法和结果如下:
public static void main(String[] args) {
File file=new File("D:\\个人");
File[] files = file.listFiles();
for (File file1 : files) {
System.out.println(file1.getAbsolutePath());
}
}
输出结果:
原文件目录
八、IO与Properties联合使用
可以用IO将普通文件中的配置属性读取出来,以下为使用方法:
public static void main(String[] args) throws Exception{
//创建文件输出字节流对象(字符流也可以),test是放着配置信息的普通文本文件
FileInputStream fis=new FileInputStream("test");
//创建Properties对象
Properties properties=new Properties();
//使用load方法将文件中的数据加载到对象中来
properties.load(fis);
Object username = properties.get("username");
System.out.println(username);
String password = properties.getProperty("password");
System.out.println(password);
}