File类的使用
- File类的理解
(1)File类的一个对象,代表一个文件或一个文件目录(文件夹)。
(2)File类中涉及到关于文件或文件目录的创建、删除、重命名、修改时间、文件大小等方法,并未涉及到写入或读取文件内容的操作。如果需要读取或写入文件内容,必须使用IO流来完成。 - File类的常用构造器
(1)File(String filePath)
(2)File(String parentPath,String childPath)
(3)File(File parentFile,String childPath) - File类的常用方法
方法 | 描述 |
---|---|
String getAbsolutePath() | 获取绝对路径 |
String getPath() | 获取相对路径 |
String getName() | 获取名称 |
String getParent() | 获取上层文件目录路径,若无,返回null |
long length() | 获取文件长度,不能获取目录长度 |
long lastModified() | 获取最后一次修改时间(毫秒值) |
String[] list() | 获取当前目录下的所有文件或所有文件目录的名称数组 |
File[] listFiles() | 获取指定目录下的所有文件或者未按目录的File数组 |
boolean isDirectory() | 判断是否是文件目录 |
boolean isFile() | 判断是否是文件 |
boolean exists() | 判断是否存在 |
boolean canRead() | 判断是否可读 |
boolean canWrite() | 判断是否可写 |
boolean isHidden() | 判断是否隐藏 |
boolean createNewFile() | 创建文件。若文件存在,则不创建,返回false |
boolean mkdir() | 创建文件目录。如果此文件存在,则不创建;如果此文件的上层目录不存在,也不创建。 |
boolean mkdirs() | 创建文件目录,如果上层文件目录不存在,一起创建 |
boolean delete() | 删除文件或文件夹。若要删除一个文件目录,则该文件目录内不能包含文件或者文件目录。 |
IO流概述
- 流的体系结构
分类 | 字节输入流 | 字节输出流 | 字符输入流 | 字符输出流 |
---|---|---|---|---|
抽象基类 | InputStream | OutputStream | Reader | Writer |
访问文件 | FileInputStream | FileOutputStream | FileReader | FileWriter |
访问数组 | ByteArrayInputStream | ByteArrayOutputStream | CharArrayReader | CharArrayWriter |
访问管道 | PipedInputStream | PipedOutputStream | PipedReader | PipedWriter |
访问字符串 | StringReader | StringWriter | ||
缓冲流 | BufferedInputStream | BufferedOutputStream | BufferedReader | BufferedWriter |
转换流 | InputStreamReader | OutputStreamWriter | ||
对象流 | ObjectInputStream | ObjectOutputStream | ||
打印流 | PrintStream | PrintWriter | ||
推回输入流 | PushbackInputStream | PushbackReader | ||
特殊流 | DataInputStream | DataOutputStream |
- 输入输出的标准化过程
(1)输入过程
1)创建File类的对象,指明读取的数据来源。(要求此文件一定要存在)。
2)创建相应的输入流,将File类的对象作为参数,传入流的构造器中。
3)具体的读入过程:创建相应的byte[] 或 char[]。
4)关闭流资源。
(2)输出过程
1)创建File类的对象,指明写出的数据的位置。(不要求此文件一定要存在)。
2)创建相应的输出流,将File类的对象作为参数,传入流的构造器中。
3)具体的写出过程:write(char[]/byte[] buffer,0,len)
4)关闭流资源。
说明:程序中出现的异常需要使用try-catch-finally处理。
节点流(文件流)
1、FileReader的使用
public void testFileReader() {
FileReader fr = null;
try {
//1.File类的实例化
File file = new File("text.txt");
//2.FileReader流的实例化
fr = new FileReader(file);
//3.读入的操作
//read(char[] cbuf):返回每次读入cbuf数组中的字符的个数。如果达到文件末尾,返回-1
char[] cbuf = new char[5];
int len;
while((len = fr.read(cbuf)) != -1){
String str = new String(cbuf,0,len);
System.out.print(str);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if(fr != null){
//4.资源的关闭
try {
fr.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
2、FileWriter的使用
说明:
(1)File对应的硬盘中的文件如果不存在,在输出的过程中,会自动创建此文件。
(2)File对应的硬盘中的文件存在:如果流使用的构造器是FileWriter(file,false) / FileWriter(file),则对原文件的覆盖;如果流使用的构造器是FileWriter(file,true),则不会对原文件覆盖,而是在原文件基础上追加内容。
举例:
public void testFileWriter() {
FileWriter fw = null;
try {
//1.提供File类的对象,指明写出到的文件
File file = new File("text.txt");
//2.提供FileWriter的对象,用于数据的写出
fw = new FileWriter(file,false);
//3.写出的操作
fw.write("I have a dream!");
} catch (IOException e) {
e.printStackTrace();
} finally {
//4.流资源的关闭
if(fw != null){
try {
fw.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
3、文本文件复制
public void testFileReaderFileWriter() {
FileReader fr = null;
FileWriter fw = null;
try {
//1.创建File类的对象,指明读入和写出的文件
File srcFile = new File("text.txt");
File destFile = new File("text1.txt");
//2.创建输入流和输出流的对象
fr = new FileReader(srcFile);
fw = new FileWriter(destFile);
//3.数据的读入和写出操作
char[] cbuf = new char[5];
int len;
while((len = fr.read(cbuf)) != -1){
fw.write(cbuf,0,len);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if(fw != null)
fw.close();
} catch (IOException e) {
e.printStackTrace();
}
try {
if(fr != null)
fr.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
4、FileInputStream / FileOutputStream的使用
说明:
(1)对于文本文件(.txt,.java,.c,.cpp),使用字符流处理。
(2)对于非文本文件(.jpg,.mp3,.mp4,.avi,.doc,.ppt等),使用字节流处理。
举例:(实现图片的复制)
public void testFileInputOutputStream() {
FileInputStream fis = null;
FileOutputStream fos = null;
try {
//1.造文件
File srcFile = new File("picture.jpg");
File destFile = new File("picture1.jpg");
//2.造流
fis = new FileInputStream(srcFile);
fos = new FileOutputStream(destFile);
//3.复制的过程
byte[] buffer = new byte[10];
int len;
while((len = fis.read(buffer)) != -1){
fos.write(buffer,0,len);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if(fos != null){
//4.关闭流
try {
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(fis != null){
try {
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
缓冲流
内部提供了一个缓冲区,提高了流的读写速度。
1、使用BufferedInputStream和BufferedOutputStream处理非文本文件
举例:实现文件的复制。
public void copyFileWithBuffered(String srcPath,String destPath){
BufferedInputStream bis = null;
BufferedOutputStream bos = null;
try {
//1.造文件
File srcFile = new File(srcPath);
File destFile = new File(destPath);
// 造节点流
FileInputStream fis = new FileInputStream((srcFile));
FileOutputStream fos = new FileOutputStream(destFile);
// 造缓冲流
bis = new BufferedInputStream(fis);
bos = new BufferedOutputStream(fos);
//3.复制的细节:读取、写入
byte[] buffer = new byte[1024];
int len;
while((len = bis.read(buffer)) != -1){
bos.write(buffer,0,len);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
//4.资源关闭
//关闭外层流的同时,内层流也会自动的进行关闭。
if(bos != null){
try {
bos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(bis != null){
try {
bis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
2、使用BufferedReader和BufferedWriter处理文本文件
举例:
public void testBufferedReaderBufferedWriter(){
BufferedReader br = null;
BufferedWriter bw = null;
try {
//创建文件和相应的流
br = new BufferedReader(new FileReader(new File("dbcp.txt")));
bw = new BufferedWriter(new FileWriter(new File("dbcp1.txt")));
//读写操作
String data;
while((data = br.readLine()) != null){
bw.write(data);
bw.newLine();//提供换行的操作
}
} catch (IOException e) {
e.printStackTrace();
} finally {
//关闭资源
if(bw != null){
try {
bw.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(br != null){
try {
br.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
转换流
- 概述
(1)InputStreamReader:将一个字节的输入流转换为字符的输入流。
(2)OutputStreamWriter:将一个字符的输出流转换为字节的输出流。
(3)作用:实现字节流与字符流之间的转换。 - 典型实现
public void test1(){
InputStreamReader isr = null;
OutputStreamWriter osw = null;
try {
isr = new InputStreamReader(new FileInputStream(new File("text.txt")), "UTF-8");
osw = new OutputStreamWriter(new FileOutputStream(new File("text_gbk.txt")), "GBK");
char[] cbuf = new char[10];
int read;
while((read = isr.read(cbuf)) != -1){
osw.write(cbuf,0,read);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
isr.close();
} catch (IOException e) {
e.printStackTrace();
}
try {
osw.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
对象流
- 作用
(1)ObjectOutputStream(序列化过程):将内存中的对象转换为存储中的文件,通过网络传输出去。
(2)ObjectInputStream(反序列化过程):将存储中的文件通过网络接收过来,转化为内存中的对象。
注意:ObjectOutputStream和ObjectInputStream不能序列化static和transient修饰的成员变量 - 对象的序列化机制
对象序列化机制允许把内存中的Java对象转换成平台无关的二进制流,从而允许把这种二进制流持久地保存在磁盘上,或通过网络将这种二进制流传输到另一个网络节点。当其它程序获取了这种二进制流,就可以恢复成原来的Java对象。 - 实现序列化的对象所属的类需满足的条件
(1)需要实现接口:Serializable。
(2)当前类需要提供一个全局常量:serialVersionUID。
(3)除了当前类需要实现Serializable接口之外,还必须保证其内部所有属性也必须是可序列化的。(默认情况下,基本数据类型可序列化)。 - 序列化反序列化代码实现
//序列化代码实现
public void testObjectOutputStream(){
ObjectOutputStream oos = null;
try {
oos = new ObjectOutputStream(new FileOutputStream("object.dat"));
oos.writeObject(new String("我爱Java"));
oos.flush();//刷新
//Person为自定义类
oos.writeObject(new Person("小张",23));
oos.flush();
oos.writeObject(new Person("小王",23,1001));
oos.flush();
} catch (IOException e) {
e.printStackTrace();
} finally {
if(oos != null){
//3.
try {
oos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
//反序列化代码实现
public void testObjectInputStream(){
ObjectInputStream ois = null;
try {
ois = new ObjectInputStream(new FileInputStream("object.dat"));
Object obj = ois.readObject();
String str = (String) obj;
Person p = (Person) ois.readObject();
Person p1 = (Person) ois.readObject();
System.out.println(str);
System.out.println(p);
System.out.println(p1);
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
} finally {
if(ois != null){
try {
ois.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
随机存储文件流:RandomAccessFile的使用
- 使用说明
(1)RandomAccessFile直接继承于java.lang.Object类,实现了DataInput和DataOutput接口。
(2)RandomAccessFile既可以作为一个输入流,又可以作为一个输出流。
(3)如果RandomAccessFile作为输出流时,写出到的文件如果不存在,则在执行过程中自动创建。 如果写出到的文件存在,则会对原文件内容进行覆盖。(默认情况下,从头覆盖)。 - 典型代码
public void test1() {
RandomAccessFile raf1 = null;
RandomAccessFile raf2 = null;
try {
raf1 = new RandomAccessFile(new File("picture.jpg"),"r");
raf2 = new RandomAccessFile(new File("picture1.jpg"),"rw");
byte[] buffer = new byte[1024];
int len;
while((len = raf1.read(buffer)) != -1){
raf2.write(buffer,0,len);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if(raf1 != null){
try {
raf1.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(raf2 != null){
try {
raf2.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}