File 对象
- 构造file对象既可以传入绝对路径,也可以传入相对路径
注意Windows平台使用\作为路径分隔符,在Java字符串中需要用两个\表示一个\ ;Linux平台使用/作为路径分隔符
构造一个File对象,即使传入的文件或目录不存在,代码也不会出错,因为构造一个File对象,并不会导致任何磁盘操作。只有当我们调用File对象的某些方法的时候,才真正进行磁盘操作
public class FileTest {
public static void main(String[] args) {
File file = new File("D:\\test.txt");
System.out.println(file);
/*getPath 构造器传入的路径*/
System.out.println(file.getPath());
/*getAbsolutepath 绝对路径*/
System.out.println(file.getAbsolutePath());
/*getCannonicalPath 规范路径*/
System.out.println(file.getCanonicalPath());
}
}
- File对象既可以表示文件,也可以表示目录,isFile(),判断该File对象是否是一个已存在的文件,调用isDirectory(),判断该File对象是否是一个已存在的目录
- 用File对象获取到一个文件时,还可以进一步判断文件的权限和大小
boolean canRead():是否可读;
boolean canWrite():是否可写;
boolean canExecute():是否可执行;
long length():文件字节大小。
- 当File对象表示一个文件时,可以通过createNewFile()创建一个新文件,用delete()删除该文件
- 当File对象表示一个目录时,可以使用list()和listFiles()列出目录下的文件和子目录名。listFiles()提供了一系列重载方法,可以过滤不想要的文件和目录
- File对象如果表示一个目录,可以通过以下方法创建和删除目录:
boolean mkdir():创建当前File对象表示的目录;
boolean mkdirs():创建当前File对象表示的目录,并在必要时将不存在的父目录也创建出来;
boolean delete():删除当前File对象表示的目录,当前目录必须为空才能删除成功。
InputStream
InputStream并不是一个接口,而是一个抽象类,它是所有输入流的超类,这个抽象类定义的一个最重要的方法就是int read(),这个方法会读取输入流的下一个字节,并返回字节表示的int值(0~255),如果已读到末尾,返回-1表示不能继续读取了
FileInputStream
FileInputStream是InputStream的一个子类,FileInputStream就是从文件流中读取数据
public class FileTest {
public static void main(String[] args) throws IOException {
FileInputStream fileInputStream = new FileInputStream("D:\\test.txt");
int read = fileInputStream.read();
while(read!=-1){
System.out.println(read);
read=fileInputStream.read();
}
fileInputStream.close();
}
}
应用程序在运行的过程中,如果打开了一个文件进行读写,完成后要及时地关闭,以便让操作系统把资源释放掉,否则,应用程序占用的资源会越来越多,不但白白占用内存,还会影响其他应用程序的运行
缓冲
一次读取多个字节时,需要先定义一个byte[]数组作为缓冲区,read()方法会尽可能多地读取字节到缓冲区, 但不会超过缓冲区的大小。read()方法的返回值不再是字节的int值,而是返回实际读取了多少个字节。如果返回-1,表示没有更多的数据了
public class FileTest {
public static void main(String[] args) throws IOException {
FileInputStream fileInputStream = new FileInputStream("D:\\test.txt");
byte[] bytes = new byte[3];
/*i表示读取的字节数*/
int i = fileInputStream.read(bytes);
System.out.println(i);
while (i!=-1){
for (int j = 0; j < bytes.length; j++) {
System.out.println(bytes[j]);
}
System.out.println("------");
i=fileInputStream.read(bytes);
System.out.println(i);
}
fileInputStream.close();
}
}
在调用InputStream的read()方法读取数据时,我们说read()方法是阻塞的,必须等read()方法返回后才能继续,因为读取IO流相比执行普通代码,速度会慢很多
FileOutStream
OutputStream也是抽象类,它是所有输出流的超类。这个抽象类定义的一个最重要的方法就是void write(int b),这个方法会写入一个字节到输出流
OutputStream还提供了一个flush()方法,它的目的是将缓冲区的内容真正输出到目的地,因为向磁盘、网络写入数据的时候,把输出的字节先放到内存的一个缓冲区里(本质上就是一个byte[]数组),等到缓冲区写满了,再一次性写入文件或者网络;通常情况下,我们不需要调用这个flush()方法,因为缓冲区写满了OutputStream会自动调用它
public class FileOutStreamTest {
public static void main(String[] args) throws IOException {
FileOutputStream fileOutputStream = new FileOutputStream("D:\\test.txt");
fileOutputStream.write(77); // M
fileOutputStream.write(77);
fileOutputStream.write(77);
fileOutputStream.write("hello".getBytes("UTF-8"));
fileOutputStream.close();
}
}
序列化
序列化是指把一个Java对象变成二进制内容,这个二进制内容本质上就是一个byte[]数组,序列化后可以把byte[]保存到文件中,或者把byte[]通过网络传输到远程,这样,就相当于把Java对象存储到文件或者通过网络传输出去了;把一个二进制内容(也就是byte[]数组)变回Java对象即是反序列化,保存到文件中的byte[]数组又可以“变回”Java对象,或者从网络上读取byte[]并把它“变回”Java对象
一个Java对象要能序列化,必须实现一个特殊的java.io.Serializable接口,Serializable接口没有定义任何方法,它是一个空接口。我们把这样的空接口称为“标记接口”(Marker Interface),实现了标记接口的类仅仅是给自身贴了个“标记”,并没有增加任何方法
反序列化时,由JVM直接构造出Java对象,不调用构造方法,构造方法内部的代码,在反序列化时根本不可能执行
Java的序列化机制仅适用于Java,如果需要与其它语言交换数据,必须使用通用的序列化方法,例如JSON
Reader
Reader是Java的IO库提供的另一个输入流接口。和InputStream的区别是,InputStream是一个字节流,即以byte为单位读取,而Reader是一个字符流,即以char为单位读取
InputStream | Reader |
---|---|
字节流,以byte为单位 | 字符流,以char为单位 |
读取字节(-1,0~255):int read() | 读取字符(-1,0~65535):int read() |
读到字节数组:int read(byte[] b) | 读到字符数组:int read(char[] c) |
FileReader
public class FileReaderTest {
public static void main(String[] args) throws IOException {
FileReader reader = new FileReader("D:\\test.txt");
char[] chars = new char[3];
int i = reader.read(chars);
while(i!=-1){
for (int j = 0; j < chars.length; j++) {
System.out.println(chars[j]);
}
i=reader.read(chars);
}
reader.close();
}
}
Writer
Reader是带编码转换器的InputStream,它把byte转换为char,而Writer就是带编码转换器的OutputStream,它把char转换为byte并输出
public class FileReaderTest {
public static void main(String[] args) throws IOException {
FileWriter writer = new FileWriter("D:\\test.txt");
writer.write('H');
writer.write('e');
writer.write('l');
writer.write("hello".toCharArray());
writer.close();
}
}