外观
IO流
File类
File是文件类,提供Java程序到文件的通道,使用File可以对文件进行操作。
File类的构造方法:
File(String pathname):pathname指文件名。以文件名实例化File对象。File(String parent, String child):parent指父文件夹,child指子文件或子文件夹。以父文件夹和子文件夹的组合路径实例化File对象。
File类的成员方法:
exists():若文件存在,返回true,否则返回false。delete():删除此文件。若成功删除返回true,否则返回false。createNewFile():创建文件。若创建成功返回true,否则返回false。若路径不存在或拒绝访问会抛出IOException异常。getName():返回文件的名称。length():返回文件的大小,单位是字节数。lastModified():返回文件最后编辑的毫秒数。isHidden():若文件处于隐藏状态则返回true,否则返回false。isDirectory():判断此文件对象的操作对象是否是文件夹,若是则返回true,否则返回false。isFile():判断此文件对象的操作对象是否是文件,若是返回true,否则返回false。
在使用完文件之后要及时关闭文件。
package IO;
import java.io.File;
import java.io.IOException;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
public class ClassFile {
public static void main(String[] args) {
//File类的三种构造方法
File file1 = new File("word.txt"); //File(文件名) 此时它所操作的文件位于这个代码保存的位置
File file2 = new File("A:/", "word.txt"); //file(父文件夹,文件名)
File file3 = new File("A:/");
File file4 = new File(file3, "word.txt");//File(其他File对象,文件名)
//File既可以操作文件,还可以创建文件夹
//File类常用方法
File f1 = new File("test.txt");
System.out.println("文件是否存在: " + f1.exists()); //exists()方法用于判断此文件是否存在
if (f1.exists()) { //若文件存在则删除文件
boolean delete = f1.delete(); //delete()方法可以删除文件 返回是否成功删除此文件的布尔值
System.out.println("文件是否删除成功:" + delete);
}
try {
boolean create = f1.createNewFile(); //createNewFile()用于创建文件 若成功创建会返回true 若此文件存在则不会创建此文件
System.out.println("文件是否创建成功:" + create);
} catch (IOException e) { //若路径不存在或拒绝访问则抛出IO异常
e.printStackTrace();
}
File f2 = new File("test.txt");
System.out.println("f1和f2是同一个对象吗:" + (f1 == f2));
System.out.println("f1和f2操作的是同一个文件吗:" + f1.equals(f2));
File f3 = new File("src/com/IO/test.txt");
System.out.println("文件的名称:" + f3.getName());
System.out.println("文件的字节数:" + f3.length());
System.out.println("文件的最后修改时间:" + f3.lastModified());//注意此处为毫秒值
System.out.println("文件是否隐藏:" + f3.isHidden());
System.out.println("是否是文件夹:" + f3.isDirectory());
System.out.println("是否是文件:" + f3.isFile());
DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
System.out.println("文件的最后修改时间:" + df.format(f3.lastModified()));
}
}运行结果:
文件是否存在: false
文件是否创建成功:true
f1和f2是同一个对象吗:false
f1和f2操作的是同一个文件吗:true
文件的名称:test.txt
文件的字节数:0
文件的最后修改时间:0
文件是否隐藏:false
是否是文件夹:false
是否是文件:false
文件的最后修改时间:1970-01-01 08:00:00字节流
字节流分为字节输出流和字节输入流,输出流指程序输出到文件中,输入流指程序从文件读取内容。
首先介绍字节输出流。字节输出流的类名为FileOutputStream。若要使用,首先要先实例化FileOutputStream类。该类的构造方法如下。
FileOutputStream(File file):使用文件file实例化字节输出流对象。其中file是一个已经实例化的File对象,实例化之后,这个字节输出流操作的文件对象就是File对象的操作文件了。FileOutputStream(File file, boolean append):若append参数为true代表以追加模式向文件中写入内容,即向文件中写入的内容会追加到文件末尾。
在实例化字节输出流后,调用这个对象的成员方法就可以对操作此文件了。下面是字节输出流的一些成员方法。
write(b):向文件中写入内容,其中写入的内容为b,即字节码,该方法没有返回值,若发生IO错误则会抛出IOException异常。close():关闭此字节流。若文件不需要再写入内容了或者不再使用了要及时关闭字节流以释放文件资源。
接下来介绍字节输入流。字节输入流的类名为FileInputStream。若要使用,需要先使用new FileInputStream(file)实例化字节输入流,参数这里不再赘述。之后使用此对象的read(b)即可读取文件中的内容,其中b为之前定义的缓冲区。该方法会返回一个整型值,代表成功读取的字节数。最后使用完字节输入流要及时关闭,以释放文件。
package IO.a;
import java.io.*;
public class a {
public static void main(String[] args){
//字节输入流和字节输出流
File f1 = new File("src/IO/a/a.txt"); //首先创建File对象 构造方法的参数就写文件的路径就可以了 注意和类的格式区分开
FileOutputStream fout = null;
try {
fout = new FileOutputStream(f1);
//创建字节输出流对象 参数是已经实例化的File对象 该字符输出流的操作对象就是这个File指定的文件
//在构造方法中,它还可以加上一个Boolean类型的参数,若此参数为true,则代表将数据写入文件末尾,若没有此参数或为false则为覆盖模式
byte[] b = "这是一个字符串".getBytes();//字节输入流只能根据字节码向文件写入信息,因此使用b存储字节码
fout.write(b); //先将字符串转换成字节码 然后用字节输出流对象的成员方法write()向参数中写入内容 该方法没有返回值
} catch (IOException e) {
e.printStackTrace();
} finally {
if (fout != null) {
try {
fout.close(); //最后需要关闭文件
} catch (IOException e) {
e.printStackTrace();
}
}
}
File f2 = new File("src/IO/a/a.txt");
FileInputStream fin = null;
try {
fin = new FileInputStream(f2);
byte[] buffer = new byte[1024];//作为缓冲区
int length = fin.read(buffer); //read()一次性读取文件的内容并返回成功读取到的字节数 若没有成功读取到内容或者读取到末尾则返回-1
/*
* 因为缓冲区的长度为1024,如果文件的字节数不足1024,在字节流读取到末尾的时候,没有内容的部分将全部是空格
* 因为read()方法会返回一个int值,存储的是成功读取的字节数,因此使用length保存
* 在将字节编码转换为字符串的时候,使用String类的第三个构造方法即可去掉空格
* */
String content = new String(buffer, 0, length); //将字节码转换为字符串 直接调用String的构造方法即可
System.out.println("文件内容是:" + content);
} catch (IOException e) {
e.printStackTrace();
} finally {
if (fin != null) {
try {
fin.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}运行结果:
文件内容是:这是一个字符串字符流
由于字节流向文件中写入内容或从文件中是以字节为单位的,在处理中文字符或者外文字符时一个字符往往占据多个字节,若编码等问题处理不当会产生乱码。因此字符流便因此而生。字符流在处理文件时是以字符为单位的,这样无论是英文字符还是中文字符,无论一个字符占据多少个字节,都不会发生乱码。
因为字符流对应字节流,因此字符流也分为字符输入流和字符输出流。首先介绍字符输出流。
字符输出流的类名为FileWriter。使用字符输出流之前需要先实例化,语法是new FileWriter(File file)。这个构造方法有一种重载方式,即FileWriter(File file, boolean append),其中append表示是否以追加方式写入文件。在实例化此对象之后,使用此对象的成员方法write(str)即可写入字符串,其中str为字符串,因为字符流是以字符为单位操作文件的,因此不需要将str转换为字节数组。若发生IO错误则会抛出IOException异常。在最后,需要及时关闭字符输出流,使用close()。
接下来介绍字符输入流。字符输入流的类名为FileReader。字符输入流在使用前也需要实例化,语法是new FileReader(file),其中file是一个File对象。在实例化此对象之后还需要准备一个字符缓冲区,如char[] buffer = new buffer[length]。在实例化这两个类之后,调用FileReader对象的read(buffer)方法即可读取字符,读取的字符将会存取到buffer中,需要特别注意这个缓冲区应是字符缓冲区。该方法会返回一个整型值,代表成功读取的字符数量。在最后使用完字节输入流需要即使关闭,调用对象的close()方法即可关闭。
package IO.b;
import java.io.*;
public class b {
public static void main(String[] args) {
/*
* 由于英文字母仅占一个字节,在使用字节流时较方便,但每个汉字占2个字节,使用字节流会很麻烦甚至可能产生乱码
* 因此这里演示更为方便的字符流
* 字符流会读取每个字符,字符包括汉字和字母,因此不容易引发乱码等问题
* */
File f1 = new File("src/IO/b/b.txt");
FileWriter fw = null;
try {
fw = new FileWriter(f1);
String str = "明月几时有,把酒问青天";
fw.write(str); //字符输出流的write()方法不需要将字符串转换成字节数组 因为此时编译器会将此字符串转换成字符数组 当然也可以使用字符数组作为参数
} catch (IOException e) {
e.printStackTrace();
} finally {
if (fw != null) {
try {
fw.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
File f2 = new File("src/IO/b/b.txt");
FileReader fr = null;
try {
fr = new FileReader(f2);
char[] buffer = new char[1024]; //字符流读取的是字符,所以要用char[]作为缓冲区
int length = fr.read(buffer);
String content = new String(buffer, 0, length);
System.out.println("文件的内容是:" + content);
} catch (IOException e) {
e.printStackTrace();
} finally {
if (fr != null) {
try {
fr.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}运行结果:
文件的内容是:明月几时有,把酒问青天带缓冲区的字节流
带缓冲区的字节流相比字节流来说,它封装了缓冲区,效果是可以提高读取文件的效率。
首先介绍带缓冲区的字节输出流。带缓冲区的字节输出流对应的类名为BufferedOutputStream。在使用这个类之前,首先实例化File类,语法是new File(path)然后将此File对象作为参数实例化FileOutputStream类,语法是new FileOutputStream(file),最后使用此FileOutputStream对象实例化BufferedOutputStream,语法是new BufferedOutputStream(fo),其中fo是之前实例化的FileOutputStream对象。之后使用这个BufferedOutputStream对象的write(b)就可以将内容写入文件,其中b代表内容对应的字节数组。但是需要注意,使用write方法后,内容是先写入缓冲区,在文件关闭后或缓冲区满后才会写入文件。因此可以使用flush()刷新缓冲区,刷新后缓冲区的内容就可以写入文件,或者也可以关闭文件,内容也会在文件被关闭后被写入文件中。在最后要按顺序及时关闭缓冲字节输出流,字节输出流。
接下来介绍带缓冲区的字节输入流。带缓冲区的字节输入流对应的类名为BufferedInputStream。使用此类前需要先实例化File类,然后使用此File对象实例化FileInputStream类,在使用FileInputStream实例化new BufferedInputStream(fi),其中fi为FileInputStream对象。在实例化之后,还需要准备一个缓冲区,假如命名为buf,那么调用前面实例化的FileInputStream对象的read(buf)方法即可读取内容,读取后文件的内容就会存到buf中。该方法还会返回成功读取的字节数。在最后要及时按顺序关闭缓冲字节输入流、字节输入流。
需要注意的是,在使用带有缓冲区的字节流时不是不需要手动创建缓冲区了,是它在内存中进行包装而优化了性能。
package IO.c;
import java.io.*;
public class c {
public static void main(String[] args) {
//字节输入流和字符输出流都需要手动定义缓冲区 对性能有影响 使用缓冲字节流可以提高性能
//相当于给字符流包装起来,添加了一个缓冲区的作用
File f1 = new File("src/IO/c/c.txt");
FileOutputStream fout = null;
BufferedOutputStream bout = null;
try {
fout = new FileOutputStream(f1); //先创建没有缓冲区的字节输出流
bout = new BufferedOutputStream(fout); //再使用带有缓冲区的缓冲字节输出流将它包装起来
bout.write("人生自古谁无死".getBytes()); //注意区别不是不需要手动创建缓冲区了 是它在内存中进行包装而优化了性能
bout.flush(); //该方法可以在缓冲区还没有被写满的时候强制将缓冲区的内容写入到文件中
} catch (IOException e) {
e.printStackTrace();
} finally {
if (bout != null) { //这里要注意流关闭的顺序,先创建的后关闭,否则会出现流未关闭的IOException异常
try {
bout.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (fout != null) {
try {
fout.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
File file2 = new File("src/IO/c/c.txt");
FileInputStream fin = null;
BufferedInputStream bin = null;
try {
fin = new FileInputStream(file2);
bin = new BufferedInputStream(fin); //这里也是先创建字节输入流再使用缓冲字节输入流包装 其他没有什么
byte[] buffer = new byte[1024];
int length = bin.read(buffer);
String content = new String(buffer, 0, length);
System.out.println("文件的内容是:" + content);
} catch (IOException e) {
e.printStackTrace();
}finally {
if (bin != null) { //这里要注意流关闭的顺序,先创建的后关闭,否则会出现流未关闭的IOException异常
try {
assert bout != null;
bout.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (fin != null) {
try {
assert fout != null;
fout.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}运行结果:
文件的内容是:人生自古谁无死带缓冲区的字符流
缓冲字符流对应的是字符流。
先介绍如何使用缓冲字符输出流。缓冲字符流的类名为BufferedWriter,需要先实例化File类,语法是new File(path),其中path代表路径,然后实例化FileWriter,语法是new FileWriter(file),其中file是之前实例化的file对象,最后就可以实例化BufferedWriter类,语法是new BufferedWriter(fw),其中fw为之前实例化的FileWriter对象。它们之间是互相包装的关系。获取缓冲字符输出流的对象之后,就可以写入内容了。调用write(str)方法来向文件中写入字符串,其中str代表要写入的字符串;调用newLine()向文件中写入换行符。最后要关闭上面创建的三个对象,关闭顺序是先关闭缓冲字符输出流,然后关闭字符输出流。
接下来介绍如何使用缓冲字符输入流。缓冲字符输入流的类名为BufferedReader。需要先实例化File对象,然后使用此File对象实例化FileReader类,最后使用此FileReader对象实例化BufferedReader,之后就可以使用read(buf)方法就可以读取文件并将文件内容存储到缓冲区buf中。该方法会返回一个整型值,代表成功读取的字符数。最后还是要按顺序关闭前面创建的两个对象。
package IO.d;
import java.io.*;
public class d {
public static void main(String[] args) throws IOException {
//本文件演示缓冲字符流 该流对应的是字符流 就像缓冲字符流对应字符流一样
File file1 = new File("src/IO/d/d.txt");
FileWriter fw;
BufferedWriter bw;
fw = new FileWriter(file1);
bw = new BufferedWriter(fw); //也是先创建字符流 然后使用缓冲字符流包装
bw.write("人生自古谁无死");
bw.newLine(); //写入一个换行符
bw.write("留取丹心照汗青");
bw.close();
fw.close();
File file2 = new File("src/IO/d/d.txt");
FileReader fr;
BufferedReader br;
fr = new FileReader(file2);
br = new BufferedReader(fr);
char[] content = new char[1024];
int length = br.read(content);
String str = new String(content, 0, length);
System.out.println("文件内容是:" + str);
br.close();
fr.close();
}
}运行结果:
文件内容是:人生自古谁无死
留取丹心照汗青数据流
数据流不按照规则、可以随意地向文件中读取内容或写入内容,但是读取的数据类型的顺序要和写入时的保持一致。这里不做讲解。
package IO.e;
import java.io.*;
public class e {
public static void main(String[] args) throws IOException {
//这里介绍数据输入流和数据输出流
//数据流也是包装其他流的流 通过数据流可以使用无关于系统的方式读取数据
File file = new File("src/IO/e/e.txt");
FileOutputStream fileOutputStream = new FileOutputStream(file);
DataOutputStream dataOutputStream = new DataOutputStream(fileOutputStream);
dataOutputStream.writeUTF("这是一段文字");
dataOutputStream.writeInt(123);
dataOutputStream.writeBoolean(true);
//虽然这些方法实际写出的文件不可直接读取,但是可以通过下面的语句读取
FileInputStream fileInputStream = new FileInputStream(file);
DataInputStream dataInputStream = new DataInputStream(fileInputStream);
System.out.println("dataInputStream.readUTF() = " + dataInputStream.readUTF());
System.out.println("dataInputStream.readInt() = " + dataInputStream.readInt());
System.out.println("dataInputStream.readBoolean() = " + dataInputStream.readBoolean());
fileOutputStream.close();
dataOutputStream.close();
fileInputStream.close();
dataInputStream.close();
}
}运行结果:
dataInputStream.readUTF() = 这是一段文字
dataInputStream.readInt() = 123
dataInputStream.readBoolean() = true