Java操作文件及目录
IO,即Input/Output
- 把内存中的数据存储到持久化设备上的动作称为输出,Output操作;
- 把持久化设备的数据读取到内存中的动作称为输入,Input操作;
- 一般把输入和输出的动作称为IO操作,IO也分网络IO、文件IO等。
Java文件类File
- 主要是对计算机文件和目录的操作;
- File类表示磁盘中存在的文件和目录;
- File类的包名是
java.io
,实现了Serializable
,Comparable
两大接口以便于其对象可序列化和比较; File.separator
目录分隔符,在不同的系统windows/Linux/Mac有差异。
常用方法:
import java.io.File;
import java.io.IOException;
public class FileTest {
public static void main(String[] args) {
String dir = "/Users/laobai/IdeaProjects/test_01/";
String name = "test_01.iml";
File file = new File(dir);
System.out.println(File.separator);
System.out.println("基本路径 getPath()= " + file.getPath());
System.out.println("文件名 getName()= " + file.getName());
System.out.println("绝对路径 getAbsolutePath= " + file.getAbsolutePath());
System.out.println("父路径 getParent()= " + file.getParent());
System.out.println("是否是绝对路径 isAbsolute()= " + file.isAbsolute());
System.out.println("是否是一个目录 isDirectory()= " + file.isDirectory());
System.out.println("是否是一个文件 isFile()= " + file.isFile());
System.out.println("文件或目录是否存在 exists()= " + file.exists());
System.out.println("目录中的文件和目录的名称所组成字符串数据 list()");
String[] arr = file.list();
for (String temp:arr) {
System.out.println(temp);
}
// 创建指定目录
File mkdirFile = new File(dir+"test");
mkdirFile.mkdir();
// 创建多层级目录
File mkdirsFlie = new File(dir + "test/aa/bb/cc");
mkdirsFlie.mkdirs();
// 创建一个文件
File newFile = new File(dir + "test1.txt");
try {
newFile.createNewFile();
} catch (IOException e) {
throw new RuntimeException(e);
}
// 删除文件
newFile.delete();
}
}
执行结果:
/
基本路径 getPath()= /Users/laobai/IdeaProjects/test_01
文件名 getName()= test_01
绝对路径 getAbsolutePath= /Users/laobai/IdeaProjects/test_01
父路径 getParent()= /Users/laobai/IdeaProjects
是否是绝对路径 isAbsolute()= true
是否是一个目录 isDirectory()= true
是否是一个文件 isFile()= false
文件或目录是否存在 exists()= true
目录中的文件和目录的名称所组成字符串数据 list()
.DS_Store
test
out
test_01.iml
.gitignore
.idea
src
Input、Output Stream流
IO在开发中的使用场景
- IO:Input/Output 即输入输出
- 输入流:外界设备 –> 程序(内存)
- 输出流:程序(内存) –> 外界设备
- 处理数据类型分类
- 字符流:处理字符相关,如处理文本数据(如txt文本),
Reader
/Writer
; - 字节流:处理字节相关,如声音或者图片等二进制,
InputStream
/OutputStream
;
- 字符流:处理字符相关,如处理文本数据(如txt文本),
- 字符流和字节流的区别:
- 字节流以字节(8bit)为单位,字符流以字节流为单位,根据码表映射字符,一次可能读多个字节;
- 字节流可以处理几乎所有文件,字符流只能处理字符流类型的数据;
- 字符流和字节流功能不同,但具有共性内容,通过不断抽象形成4个抽象类,抽象类下面有很多子类是具体的实现
- 字符流
Reader
/Writer
- 字节流
InputStream
/OutputStream
- 字符流

InputStream
InputStream
是输入字节流的父类,它是一个抽象类,一般使用它的子类。
int read()
:从输入流中读取单个字节,返回0到255范围内的int字节值,字节数据可直接转换为int类型,如果已经到达流末尾而没有可用的字节,则返回-1;int read(byte[] buf)
:从输入流中读取一定数量的字节,并将其存储在缓冲区数组buf中,返回实际读取的字节数;long skip(long n)
:从输入流中跳过并丢弃n个字节的数据;int available()
:返回这个流中有多少个字节数,可以把buf数组长度定义为这个;void close() throws IOException
:关闭输入流并释放与该流关联的系统资源;
常见子类
FileInputStream
抽象类
InputStream
用来具体实现类的创建对象,文件字节输入流,对文件数据以字节的形式进行读取操作;常用构造函数
// 传入所在地址 public FileInputStream(string name) throws FileNotFoundException // 传入文件对象 public FileInputStream(File file) throws FileNotFoundException
import java.io.*; public class Main { public static void main(String[] args) throws IOException { String dir = "/Users/laobai/IdeaProjects/test_01/"; String name = "plscript.txt"; File file = new File(dir, name); InputStream inputStream = new FileInputStream(file); testRead(inputStream); testSkip(inputStream); testReadByteArr(inputStream); } public static void testRead(InputStream inputStream)throws IOException{ int read = inputStream.read(); System.out.println(read); System.out.println((char) read); inputStream.close(); } public static void testSkip(InputStream inputStream)throws IOException{ long skipSize = inputStream.skip(2); int read = inputStream.read(); System.out.println(read); System.out.println((char) read); inputStream.close(); } public static void testReadByteArr(InputStream inputStream) throws IOException{ byte[] buf = new byte[2048]; int length; while ((length = inputStream.read(buf))!=-1){ System.out.println(new String(buf, 0, length)); } inputStream.close(); } }
执行结果:
112 p 99 c ript.cn漂亮的脚本 plscript.cn漂亮的脚本 plscript.cn漂亮的脚本 plscript.cn漂亮的脚本 plscript.cn漂亮的脚本
ByteArrayInputStream
字节数组输入流ObjectInputStream 对
象输入流
OutputStream
OutputStream
是输出字节流的父类,它是一个抽象类
void write(int b)
将指定的字节写入输出流void write(byte[] b)throws IOException
将b.length
个字节的byte数组写入当前输出流void flush() throws IOException
write是写到缓冲区中,可以认为是内存中,当缓冲区满时系统会自动将缓冲区的内容写入文件,但一般还有部分可能会留在内存这个缓冲区中,所以需要调用flush
清空缓冲区数据。void close() throws IOException
关闭输入流并释放与该流关联的系统资源。
常用子类
FileOutputStream
抽象类
OutputStream
用来具体实现类的创建对象,文件字节输出流,对文件数据以字节的形式进行输出的操作;构造函数
// 传入输出的文件地址 public FileOutPutStream(String name) // 传入目标输出的文件对象 public FileOutputStream(File file) // 传入目标输出的文件对象,是否可以追加内容 public FileOutputStream(File file, boolean append)
package test05; import java.io.*; public class test1 { public static void main(String[] args) throws IOException { String dir = "/Users/laobai/IdeaProjects/test_01/"; String name = "plscript.txt"; String target = "tar.txt"; File file = new File(dir, name); InputStream inputStream = new FileInputStream(file); // OutputStream outputStream = new FileOutputStream(dir+File.separator+target); OutputStream outputStream = new FileOutputStream(dir+File.separator+target, true); // testOut(inputStream,outputStream); testOutBuf(inputStream,outputStream); } public static void testOut(InputStream inputStream,OutputStream outputStream) throws IOException { int value = 0; while (value != -1){ value = inputStream.read(); outputStream.write(value); } inputStream.close(); outputStream.close(); } public static void testOutBuf(InputStream inputStream,OutputStream outputStream) throws IOException { byte [] buf = new byte[1024]; int length; while ((length = inputStream.read(buf))!=-1){ outputStream.write(buf, 0, length); } inputStream.close(); outputStream.close(); } }
ByteArrayOutputStream
ObjectOutputStream
缓冲Buffer输入输出字节流
什么是缓冲Buffer?它是内存空间的一部分,在内存空间中预留了一定的存储空间,这些存储空间用来缓冲输入或输出的数据,这部分空间就叫缓冲区,缓冲区是具有一定大小的。
Java IO包中提供了两个缓冲类(高级流):BufferInputStream
和BufferOutputStream
BufferInputStream
BufferInputStream
缓冲字节输入流,通过预先读入一整段原始输入流数据至缓冲区,而外界对BufferInputStream
的读取操作实际上是在缓冲区上进行的。如果读取的数据超过了缓冲区的访问,那么BufferInputStream
负责重新从原始输入流中载入下一截数据填充缓冲区,然后外界继续通过缓冲区进行数据读取。缓冲区的实现:读取缓冲区的内容,当读取超过缓冲区的内容后进行一次磁盘IO,载入一段数据填充缓冲区,下一次对其一般情况就直接从缓冲区读取,减少了磁盘IO。
缓冲区默认大小为8k,
int DEFAULT_BUFFER_SIZE=8192;
常用构造函数
// 对输入流进行包装,里面默认的缓冲区是8k public BufferedInputStream(InputStream in); // 对输入流进行包装,指定创建并指定缓冲区大小 public BufferedInputStream(InputStream in,int size)
常用方法
// 从输入流中读取一个字节 public int read(); // 从字节输入流中给定偏移量处开始将各字节读取到指定的byte数组中 public int read(byte[] buf,int off, int len); // 关闭释放资源 void close();
BufferOutputStream
BufferOutputStream
缓冲字节输出流常用构造函数
// 对输出流进行包装,里面默认的缓冲区是8k public BufferedOutputStream(OutputStream out); // 对输出流进行包装,指定创建并指定缓冲区大小 public BufferedOutputStream(OutputStream out,int size)
常用方法
// 向输出流中输出一个字节 public void write(int b); // 将指定byte数组中从偏移量off开始len个字节写入缓存的输出流 public void write(byte [] buf, int off, int len); // 刷新此缓冲的输出流,强制使所有缓冲的输出自己被写出到底层输出流中 public void flush // 关闭释放资源 void close();
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.util.Arrays;
public class TestCopy {
public static void main(String[] args) {
try {
FileInputStream fileInputStream = new FileInputStream("/Users/laobai/IdeaProjects/test_01/plscript1.txt");
BufferedInputStream bufferedInputStream = new BufferedInputStream(fileInputStream);
FileOutputStream fileOutputStream = new FileOutputStream("/Users/laobai/IdeaProjects/test_01/backup.txt");
BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(fileOutputStream);
int size;
byte [] buf = new byte[1024];
while ((size = bufferedInputStream.read(buf))!=-1) {
bufferedOutputStream.write(buf, 0, size);
}
// 刷新缓冲区的输出流,才可以保证数据全部输出完成
// bufferedOutputStream.flush();
bufferedInputStream.close();
bufferedOutputStream.close();
} catch (Exception e) {
System.out.println(e);
}
}
}
Reader、Writer字符流
字符输入流Reader
Reader
是输入字符流的父类,它是一个抽象类int read()
一个字符一个字符的读取,只能用来操作文本,不能写图片、音频、视频等;int read(char cbuf[])
从输入字符流中读取一定数量的字符,并将其存储在缓冲区数组cbuf中,返回实际读取的字符数,如果已经到达流末尾而没有可用字节,则返回-1;void close() throws IOException
关闭输入流并释放与该流关联的系统资源。
- 常用子类
FileReader
用来读取字符文件的实现类
字符输出流Writer
Writer
是输出字符流的父类,它是一个抽象类public void write(int c) throws IOException
直接将int型数据作为参数的话,是不会写入数字的,而是先将数字按照ASCII码表转换为相应字符,然后写入;public void write(String str) throws IOException
要想实现数字和中文的写入,必须要用String为参数的write;public abstract void write(char cbuf[], int off, int len) throws IOException
将cbuf字符数组的一部分写入到流中,但能不能写len个字符取决于cbuf中是否有那么多;void flush() throws IOException
write是写到缓冲区中,可以任务是内存中,当缓冲区满时系统会自动将缓冲区的内容写入文件,但一般还有一部分有可能会留在内存这个缓冲区中,所以需要调用flush清空缓冲区数据;void close() throws IOException
关闭输入流并释放与该流关联的系统资源。
- 常用子类
FileWriter
用来写出字符文件的实现类
缓冲Buffer输入输出字符流
为了提高单个字符读写的效率,进行字符批量的读写;为了提高字符流读写效率,引入缓冲机制;
BufferedReader
当
BufferedReader
在读取文本文件时,会先尽量从文件中读入字符数据并放满缓冲区,而之后若使用read()方法,会先从缓冲区中进行读取,如果缓冲区数据不足,才会再从文件中读取构造函数
BufferedReader(Reader in) BufferedReader(Reader in ,int sz) 创建一个使用指定大小输入缓冲区的缓冲字符输入流
常用API
boolean ready()
判断是否已经准备好被读取int read()
读取单个字符int read(char[] cbuf, int off, int len)
读取一部分字符到数组里面,从数组下标off处放置length长度的字符String readLine()
读取一整行文本,返回一整行字符串,如果读到行尾了就返回null,返回的一行不包括换行符void close()
关闭流释放资源
BufferedWriter
写入的数据并不会先输出到目的地,而是先存储至缓冲区中。如果缓冲区中的数据满了,才会对目的进行输出
构造函数
BufferedWriter(Writer out) BufferedWriter(Writer out, int sz)
常用API
void write(int c)
希尔一个字符void write(char[] cbuf, int off, int len)
写入字符数组的一部分,通过off和len控制void write(String s, int off, int len)
写入字符数组的一部分,通过off和len控制void newLine()
写入一个换行符号void flush()
清空缓冲区数据void close()
关闭流并释放资源
字符流和字节流的转换
计算机存储的单位是字节,从持久设备读取到程序中是解码,从程序写到持久设备中是编码。
无论是编码还是解码,不同字符集编码名称字符需要不同的个数,因此字节流读取容易出错,比如出现乱码,因此需要一个流,把字节流读取的字节进行缓冲后,再通过字符集解码成字符返回。
InputStreamReader
将字节流转换为字符流,字节流通向字符流的桥梁,如果不指定字符集编码,则解码过程中将使用平台默认的字符编码,如:UTF-8。文本文件存储是A编码,如果以B编码进行读取可能会出现乱码。
构造函数
// 使用系统默认编码集 public InputStreamReader(InputStream in) // 指定编码集创建对象 public InputStreamReader(InputStream in ,String charsetName)
常用API
int read()
int read(char [] cbuf, int off, int len)
int read(char [] cbuf)
void close()
OutputStreamWriter
将字符流转换位字节流,字符流通向字节流的桥梁。如果不指定字符集编码,则解码过程中将使用平台默认的字符编码,如:GBK。
构造函数
// 使用系统默认编码集 public OutputStreamWriter(OutputStream out) // 指定编码集创建对象 public OutputStreamWriter(OutputStream out,String charsetName)
常用API
void write(int c)
void write(char [] cbuf, int off, int len)
void write(String s, int off, int len)
void newLine()
void close()
void flush()
try-with-resource
需要关闭的资源只要实现了java.lang.AutoCloseable
,就可以自动被关闭。
import java.io.*;
public class TryTest {
public static void main(String[] args) {
try (
FileInputStream fileInputStream = new FileInputStream("/Users/laobai/IdeaProjects/test_01/plscript.txt");
BufferedInputStream bufferedInputStream = new BufferedInputStream(fileInputStream);
FileOutputStream outputStream = new FileOutputStream("/Users/laobai/IdeaProjects/test_01/backup.txt");
BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(outputStream);
){
int size;
byte [] buf = new byte[1024];
while ((size = bufferedInputStream.read(buf))!=-1) {
bufferedOutputStream.write(buf,0,size);
}
}catch (Exception e) {
e.printStackTrace();
}
}
}