一、文件File
1.创建文件对象操作
//方式1 new File(String pathname)
File file = new File("d:\\file1.txt");
try{
file.createNewFile();
System.out.println("创建成功");
}catch(IOException e){
e.printStackTrace();
}
//方式2 new File(File parent,String childName)
File parenntFIle = new File("d:\\");
String filename = "file2.txt";
File file = new File(parenntFIle,filename);
try{
file.createNewFile();
System.out.println("创建成功");
}catch(IOException e){
e.printStackTrace();
//方式3 new File(String parent,String chile)
File parenntFIle = "d:\\";
String filename = "file2.txt";
File file = new File(parenntFIle,filename);
try{
file.createNewFile();
System.out.println("创建成功");
}catch(IOException e){
e.printStackTrace();
2.File类的常用方法
方法 | 作用 |
isDirectory() | 是否为文件夹 |
isFile() | 是否为文件 |
getPath() | 得到file的路径 |
getName() | 得到最后一层的名字 |
getParent() | 得到去掉最后一层的路径 |
getParentFile() | 得到父类路径的新文件 |
renameTo() | 改名 |
mkdir() | 创建新文件夹,只能创建一层 |
mkdirs() | 创建新文件夹,可以多层 |
createNewFile() | 创建新文件,只能一层 |
exists() | 路径是否存在 |
delete() | 删除文件或者目录(为空的目录) |
list() | 返回该路径下文件或者文件夹的名字数组 |
listFiles() | 返回该路径下文件或者文件夹组成的File数组 |
separator | 代替文件或文件夹路径的斜线或反斜线,防止跨平台出现错误 |
二、JAVAIO
1.IO流是什么:
存储和读取数据的解决方案
I:input O:output
2.IO流的分类:
(1)流的方向
文件再程序中是以流的形式来操作的
输入流:文件→程序(读取)
输出流:程序→文件(写出)
(2)操作文件类型
字节流:可以操作二进制文件
①字节输入流:InputStream
②字节输出流:OutputStream
字符流:只能操作纯文本文件(用windows系统自带的记事本打开且能读懂的文件:txt文件、md文件、xml文件、lrc文件)
①字符输入流:Reader
②字符输出流:Writer
(3)流的角色的不同
节点流
处理流/包装流
注意:JAVA的IO涉及40多个类,都是从以上4个抽象基类派生的。由这四个类派生出来的子类名称都是以其父类作为子类名后缀。
3FileInputStream字节输入流
操作本地文件的字节输入流,可以把本地文件中的数据读取到程序中来。
public static void main(String[] args) throws IOException {
//1.创建对象
FileInputStream fis = new FileInputStream("a.txt");
//2.读取数据
int b1 = fis.read();
System.out.println(b1);
//3.释放资源
fis.close();
}
注意:
- 如果文件不存在、不是文件是目录或者其他原因不能打开的话,则会抛出FileNotFoundException错误
- read一次读一个字节,而且是读取一个数据就移动一次指针。读出来的是数据在ASCII上对应的数字
- 读到文件末尾了,read方法返回-1
循环读取:
public static void main(String[] args) throws IOException {
//1.创建对象
FileInputStream fis = new FileInputStream("a.txt");
//2.循环读取数据
int b;
while((b = fis.read()) != -1){
System.out.println(b);
}
//3.释放资源
fis.close();
}
4.FileOutputStream字节输出流
FileOutputStream流是指文件字节输出流,专用于输出原始字节流如图像数据等,其继承OutputStream类,拥有输出流的基本特性。
FileOutputStream(String name)
创建一个向具有指定名称的文件中写入数据的文件输出流
FileOutStream(File file)
创建一个向指定File对象表示的文件中写入数据的文件输出流
public static void main(String[] args) throws IOException {
//1.创建对象
FileOutputStream fos = new FileOutputStream("Project\\a.txt");
//2.写出数据
fos.write(97);
//3.释放资源
fos.close();
}
注意:
- 参数是字符串中表示的路径或者是File对象
- 如果文件不存在会创建一个新的文件,但是要保证父级文件是存在的
- 如果文件已经存在,则会清空文件
- write方法的参数是整数,但是实际上写到本地文件中的是整数在ASCII上对应的字符
- 每次使用完流之后都要释放资源
FileOutputStream写数据的三种方式
方法名称 | 说明 |
void write(int b) | 一次写一个字节数据 |
void write(byte[ ] b) | 一次写一个字节数组数据 |
void write(byte[ ] b,int off,int len) | 一次写一个字节数组的部分数据 |
换行写:
Mac: \r Linux: \n Windows: \r\n
public static void main(String[] args) throws IOException {
//1.创建对象
FileOutputStream fos = new FileOutputStream("a.txt");
//2.写出数据
String str1 = "abc";
byte[] bytes1 = str1.getBytes();
fos.write(bytes1);
//再次写出一个换行符\r\n就可以换行了
String wrap = "\r\n";
byte[] bytes2 = wrap.getBytes();
fos.write(bytes2);
String str2 = "def";
byte[] bytes3 = str2.getBytes();
fos.write(bytes3);
//3.释放资源
fos.close();
}
不想清空、追写加入:
FileOutStream(File file,boolean append)
创建一个向指定File对象表示的文件中写入数据的文件输出流,后面的参数是指是否覆盖原文件内容
第二个参数(续写开关)默认为false,表示关闭续写,此时创建对象会清空文件
改为true,表示追加,不覆盖
5.FileReader字符输入流
(1)创建字符输入流对象
构造方法 | 说明 |
public FileReader(File file) | 创建字符输入流关联本地文件 |
public FileReader(String pathname) | 创建字符输入流关联本地文件 |
如果文件不存在,就直接报错
(2)读取数据
成员方法 | 说明 |
public int read() | 读取数据,读到末尾返回-1 |
public int read(char[ ] buffer) | 读取多个数据,读到末尾返回-1 |
按字节进行读取,遇到中文,一次读多个字节,读取后方法的底层还会解码并转成十进制,最终把这个十进制作为返回值
读到文件末尾了,read方法返回-1
(3)释放资源
成员方法 | 说明 |
public int close() | 释放资源/关流 |
无参read:
public static void main(String[] args) throws IOException {
//1.创建对象并关联本地文件
FileReader fr = new FileReader("a.txt");
//2.读取数据
//字符流的底层也是字节流,默认也是一个字节一个字节读取的
//遇到中文会一次读取多个,GBK一次读两个,UFT-8一次读3个
int ch;
while((ch = fr.read()) != -1){
System.out.println(ch);
}
//3.释放资源/关流
fr.close();
}
有参read:
public static void main(String[] args) throws IOException {
//1.创建对象并关联本地文件
FileReader fr = new FileReader("a.txt");
//2.读取数据
char[] str = new char[2];
int len;
while((len = fr.read(str)) != -1){
//把数组中的数据变成字符串再进行打印
System.out.println(new String(str,0,len));
}
//3.释放资源/关流
fr.close();
}
6.FileWriter字符输出流
(1)创建字符输出流对象
构造方法 | 说明 |
public FileWriter(File file) | 创建字符输出流关联本地文件 |
public FileWriter(String pathname) | 创建字符输出流关联本地文件 |
public FileWriter(File file,boolean append) | 创建字符输出流关联本地文件,续写 |
public FileWriter(String pathname,boolean append) | 创建字符输出流关联本地文件续写 |
参数是字符串表示的路径或者File对象都是可以的
如果文件不存在会创建一个新的文件,但是要保证父级路径是存在的
如果文件已经存在,则会清空文件,如果不想清空可以打开续写开关
(2)写出数据
成员方法 | 说明 |
void write(int c) | 写出一个字符 |
void write(String str) | 写出一个字串 |
void write(String str,int off,int len) | 写出一个字串的一部分 |
void write(char[ ] cbuf) | 写出一个字符数组 |
void write(char[ ] cbuf,int off,int len) | 写出一个字符数组的一部分 |
如果write方法的参数是整数,但是实际上写到本地文件中的是整数在字符集上对应的字符
public static void main(String[] args) throws IOException {
FileWriter fw = new FileWriter("a.txt");
//根据字符集的编码方式进行编码,把编码之后的数据写到文件中去
fw.write(12345);
fw.close();
}
public static void main(String[] args) throws IOException {
FileWriter fw = new FileWriter("a.txt");
char[] chars ={'h','e','l','l','o','你','好'};
fw.write(chars);
fw.close();
}
7.BufferedInputStream:字节缓冲输入流、BufferedOutputStream字节缓冲输出流
字节缓冲流提高效率的原理:减少了和硬盘的交互次数
在创建流对象时,会创建一个内置的默认大小的缓冲区数组,通过缓冲区读写,减少系统IO次数,从而提高读写的效率。(内存的执行效率远高于硬盘,所以只需减少和硬盘的交互次数)
如果原文件大小为8192个字节,那么输入流就需要从硬盘中读8192次,也就是和硬盘交互8192次,右边写出数据也需要和硬盘交互8192次,总需要交互2*8192次;缓冲流会创建一个内置的默认8192大小的缓冲区数组,那么输入流只需要从硬盘读1次,右边也只需要交互1次,总需要交互2次
方法名称 | 说明 |
public BufferedInputStream(InputStream is) | 把基本流包装成高级流,提高读取数据的性能 |
public BufferedInputStream(OutputStream is) | 把基本流包装成高级流,提高写出数据的性能 |
一次读写一个字节:
public static void main(String[] args) throws IOException {
BufferedInputStream bis = new BufferedInputStream(new FileInputStream("a.txt"));
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("copy.txt"));
int b;
while((b = bis.read()) != -1){
bos.write(b);
}
bos.close();
bis.close();
}
注意:
缓冲区长度默认8192的字节数组
只需要关闭缓冲流,底层都会会先关闭基本流
速度比基本流要快
一次读写多个字节:
public static void main(String[] args) throws IOException {
BufferedInputStream bis = new BufferedInputStream(new FileInputStream("a.txt"));
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("copy.txt"));
byte[] bytes = new byte[1024];
int len;//表示当前操作的字节个数
while((len = bis.read(bytes)) !=-1){
bos.write(bytes,0,len);
}
bos.close();
bis.close();
}
8.BufferedReader字符缓冲输入流、BufferedWritter字符缓冲输出流
方法名称 | 说明 |
public BufferedReader(Reader r) | 把基本流变成高级流 |
public BufferedWriter(Writer r) | 把基本流变成高级流 |
缓冲区长度默认8192的字符数组,为2*8192个字节
对于字符流提升不明显,对于字符缓冲流而言的关键点是两个特有的方法
特有方法 | 说明 |
public String readLine() | 读取一行数据,如果没有数据可读了,会返回null |
public void newLine() | 跨平台换行 |
readLine():
方法在读取的时候,一次读一整行,遇到回车换行结束,但是他不会把回车换行读到内存当中
读一行:
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new FileReader("a.txt"));
String line = br.readLine();
System.out.println(line);
br.close();
}
读多行:
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new FileReader("a.txt"));
String line;
while((line = br.readLine()) != null){
System.out.println(line);
}
br.close();
}
newLine():
续写开关true要写到FileWriter()方法内
public static void main(String[] args) throws IOException {
BufferedWriter bw = new BufferedWriter(new FileWriter("b.txt,true"));
bw.write("nihao");
bw.newLine();
bw.write("hi");
bw.newLine();
bw.close();
}
9.InputStreamReader转换输入流、OutputStreamReader转换输出流
转换流是字符流和字节流之间的桥梁,字节流可以使用字符流的方法
JDK11之前:
- InputStreamReader(InputStream in):创建一个使用默认字符集的InputStreamReader
- InputStreamReader(InputStream in, String charsetName):创建一个使用命名字符集的InputStreamReader
- OutputStreamWriter(OutputStream out):创建一个使用默认字符集的OutputStreamWriter
- OutputStreamWriter(OutputStream out, String charsetName):创建一个使用命名字符集的OutputStreamWriter
JDK11之后:
- FileReader(File file, Charset charset):创建一个新的FileReader,给出File读取和创建charset
- FileReader(String fileName, Charset charset):创建一个给定文件名称的FileReader,给出File读取和创建charset
10.序列化流、反序列化流
(1)ObjectOutputStream序列化流/对象操作输出流
可以把Java中的对象写到本地文件中
构造方法 | 说明 |
public ObjectOutputStream(OutputStream out) | 把基本流包装成高级流 |
成员方法 | 说明 |
public final void writeObject(object obj) | 把对象序列化(写出)到文件中去 |
public static void main(String[] args) throws IOException {
//1.创建对象
Student stu = new Student("zhangsan",15);
//2.创建序列化流的对象/对象操作输出流
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("a.txt"));
oos.writeObject(stu);
oos.close();
}
注意:使用对象输出流将对象保存到文件时会出现NotSerializableException异常
需要让Javabean类实现Serializable接口
Serializable接口里面是没有抽象方法,标记型接口,一旦实现了这个接口,那么就表示当前的Student类可以被序列化
(2)ObjectInputStream反序列化流/对象操作输入流
可以把序列化到本地文件中的对象,读取到程序中来
构造方法 | 说明 |
public ObjectInputStream(InputStream out) | 把基本流变成高级流 |
成员方法 | 说明 |
public Object readObject() | 把序列化到本地文件中的对象,读到程序中来 |
public static void main(String[] args) throws IOException, ClassNotFoundException {
//1.创建对象
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("a.txt"));
//2.读取数据
Object o = ois.readObject();
//3.打印对象
System.out.println(o);
ois.close();
}
11.打印流
特点:
- 打印流只操作文件目的地,不操作数据源
- 特有的写出方法可以实现,数据原样写出
- 特有的写出方法可以实现自动刷新、自动换行,打印一次数据=写出+换行+刷新
(1)PrintStream字节打印流
构造方法 | 说明 |
public PrintfStream(OutputStream/File/String) | 关联字节 |
public PrintStream(String fileName,Charset charset) | 指定字符编码 |
public PrintfStream(OutputStream out,boolean autoFlush) | 自动刷新 |
public PrintStream(OutputStream out,boolean autoFlush,String encoding) | 指定字符编码且自动刷新 |
(2)PrintWriter字符打印流
成员方法 | 说明 |
public void write(...) | 常规方法:规则跟之前一样,写出字节或者字符串 |
pubilc void println(Xxx xx) | 特有方法:打印任意类型的数据并且换行 |
pubilc void print(Xxx xx) | 特有方法:打印任意类型的数据,不换行 |
pubilc void printf(String format,object...args) | 特有方法:带有占位符的打印语句 |