一、File类
(一) 概述
1.java.io.File
类是文件和目录路径名的抽象表示,主要用于文件和目录的创建。
2.我么可以使用File类的方法
-
创建、删除、获取一个文件/文件夹
-
判断文件是否存在
-
对文件进行遍历
-
获取文件的大小
File类是一个与系统无关的类,任何操作系统都可以使用这个类中的方法。
3、重点 -
file:文件
-
directory:文件夹/目录
-
path:路径
(二)File类的静态成员变量 -
static String pathSeparator
与系统有关的路径分隔符,为了方便,它被表示为一个字符串。 -
static char pathSeparatorChar
与系统有关的路径分隔符。 -
static String separator
与系统有关的默认名称分隔符,为了方便,它被表示为一个字符串。 -
static char separatorChar
与系统有关的默认名称分隔符。
(三)绝对路径和相对路径
1、绝对路径:是一个完整的路径,以盘符开始的路径。
2、相对路径:是一个简化的路径,相对指的是相对于当前项目的根目录。
注意: -
路径不区分大小写
-
路径中文件名称分隔符windows中使用两个反斜杠
(四)File的构造方法 -
File(File parent, String child)
根据 parent 抽象路径名和 child 路径名字符串创建一个新 File 实例。
好处
父路径是File类型,可以使用File的方法对路径进行一些操作,再使用路径创建对象。 -
File(String pathname)
通过将给定路径名字符串转换为抽象路径名来创建一个新 File 实例。
参数
1、参数为字符串的路径名称
2、路径可以是以文件结尾也可以是以文件夹结尾
3、路径可也是相对路径也可以是绝对路径
4、路径可也是存在也可以是不存在
5、创建File对象,只要把字符串路径封装为File对象,不考虑真假路径的情况 -
File(String parent, String child)
根据 parent 路径名字符串和 child 路径名字符串创建一个新 File 实例。
好处
父路径和子路径可以单独书写,使用起来非常灵活,父路径子路径都可以变化。 -
File(URI uri)
通过将给定的 file: URI 转换为一个抽象路径名来创建一个新的 File 实例
(五)获取功能的方法 -
public String getAbsolutePath()
:返回File的绝对路径名字符串
无论路径是绝对的还是相对的,返回的都是绝对路径。 -
public String getPath()
:将此File转换为路径名字符串 -
public String getName()
:返回由此File表示的文件或目录的名称。 -
public long length()
:返回由此File表示的文件的长度。 -
注意:
-
获取的是构造方法指定文件的大小,以字节为单位。
-
文件夹没有大小概念不能获取文件夹大小。
-
如果构造方法给出的路径不存在,那么该方法返回0.
public class F1 {
public static void main(String[] args) {
show1();
show2();
show3();
show4();
}
private static void show4() {
File f = new File("C:\\Users\\阚开豪\\Desktop\\javaFile\\a.txt");
long length = f.length();
System.out.println(length);
}
private static void show3() {
File f1 = new File("C:\\Users\\阚开豪\\Desktop\\javaFile\\a.txt");
String ab1 =f1.getPath();
System.out.println(ab1);
File f2 = new File("C:\\Users\\阚开豪\\Desktop\\javaFile\\a.txt");
String ab2 =f1.getName();
System.out.println(ab2);
}
private static void show2() {
File f1 = new File("C:\\Users\\阚开豪\\Desktop\\javaFile\\a.txt");
String ab1 =f1.getPath();
System.out.println(ab1);
File f2 =new File("a.txt");
String ab2 = f2.getPath();
System.out.println(ab2);
//返回的为绝对路径
}
private static void show1() {
File f1 = new File("C:\\Users\\阚开豪\\Desktop\\javaFile\\a.txt");
String ab1 = f1.getAbsolutePath();
System.out.println(ab1);
File f2 =new File("a.txt");
String ab2 = f2.getAbsolutePath();
System.out.println(ab2);
}
}
输出为:
C:\Users\阚开豪\Desktop\javaFile\a.txt
C:\Users\阚开豪\IdeaProjects\java练习\a.txt
C:\Users\阚开豪\Desktop\javaFile\a.txt
a.txt
C:\Users\阚开豪\Desktop\javaFile\a.txt
a.txt
5
(六)File类判断功能的方法
public boolean exists( )
:此File表示的文件或目录是否实际存在。public boolean isDirectory( )
:此File表示的是否为目录。public boolean isFile( )
:此File表示的是否为文件。- 测试代码:
import java.io.File;
public class F2 {
public static void main(String[] args) {
File f1 = new File("C:\\Users\\阚开豪\\Desktop\\javaFile\\a.txt");
File f2 =new File("C:\\Users\\阚开豪\\Desktop\\javaFile");
//判断是否存在
System.out.println("存在?"+f1.exists());
System.out.println("存在?"+f2.exists());
//判断是文件还是目录
System.out.println("是文件?"+f2.isFile());
System.out.println("是目录?"+f2.isDirectory());
}
}
输出为:
存在?true
存在?true
是文件?false
是目录?true
(七)创建删除功能的方法
-
public boolean creatNewFile( )
:当且仅当具有该名称的文件尚不存在的时候,创建一个新的文件。 -
public boolean delete ( )
:删除由此File表示的文件或者目录。 -
pubic boolean mkdir( )
:创建由此File表示的目录 -
public boolean mikdirs( )
:创建由此File表示的目录,包括任何必需但不存在的目录。 -
测试代码
import java.io.File;
import java.io.IOException;
public class F3 {
public static void main(String[] args) {
//文件的创建
File f= new File("a.txt");
System.out.println("是否存在"+f.exists());
try {
System.out.println("是否创建"+f.createNewFile());
} catch (IOException e) {
e.printStackTrace();
}
System.out.println("是否存在"+f.exists());
//目录的创建
File f1=new File("test");
System.out.println("是否存在"+f1.exists());
System.out.println("是否创建"+f1.mkdir());
System.out.println("是否存在"+f1.exists());
//创建多级目录
File f2 =new File("test\\t1");
System.out.println("是否存在"+f1.exists());
System.out.println("是否创建"+f1.mkdirs());
System.out.println("是否存在"+f1.exists());
//删除目录
f2.delete();
System.out.println("是否存在"+f2.exists());
}
}
输出为
是否存在true
是否创建false
是否存在true
是否存在true
是否创建false
是否存在true
是否存在true
是否创建false
是否存在true
是否存在false
(八)目录的遍历
public String[ ] list( )
:返回一个Strings数组,表示该File目录中的所有子文件或目录。public File[ ] listFiles( )
:返回一个File数组,表示该File目录中的所有的子文件或目录。- 测试代码:
import java.io.File;
public class F4 {
public static void main(String[] args) {
File dir = new File("C:\\Users\\阚开豪\\Desktop\\javaFile");
//获取当前目录下的文件以及文件夹名称
String [] names = dir.list();
for(String name:names){
System.out.println(name);
}
//获取当前目录下的文件以及文件夹对象,只要拿到了文件都西昂,那么就可以获取更多信息
File [] files = dir.listFiles();
for(File file:files){
System.out.println(file);
}
}
}
输出为:
a.txt
b.txt
c.txt
C:\Users\阚开豪\Desktop\javaFile\a.txt
C:\Users\阚开豪\Desktop\javaFile\b.txt
C:\Users\阚开豪\Desktop\javaFile\c.txt
二、递归
(一)概述
- 递归:指在当前方法内调用自己的这种现象
- 递归的分类:
- 递归分为两种,直接递归和间接递归
- 直接递归成为方法本身调用自己
- 间接递归可以A方法调用B方法,B方法调用C方法,C方法调用A方法
- 注意事项:
- 递归一定要有条件限定,保证递归停止否则会发生栈内存溢出
- 递归中虽然有限定条件但是递归次数不能太多,否则会发生栈内存溢出。
- 构造方法,禁止递归
(二)递归打印多级目录
分析:多级目录的打印实际就是目录的嵌套。遍历之前无从知道有多少级目录,所以需要使用递归实现。
代码实现:
import java.io.File;
public class F5 {
public static void main(String[] args) {
File file =new File("C:\\Users\\阚开豪\\Desktop\\javaFile");
getALLfile(file);
}
private static void getALLfile(File file) {
File [] files =file.listFiles();
for(File f:files){
if(f.isDirectory())
getALLfile(f);
else
System.out.println(f);
}
}
}
输出为:
C:\Users\阚开豪\Desktop\javaFile\a\a.txt
C:\Users\阚开豪\Desktop\javaFile\a\b.txt
C:\Users\阚开豪\Desktop\javaFile\a\c.txt
C:\Users\阚开豪\Desktop\javaFile\b\d.txt
C:\Users\阚开豪\Desktop\javaFile\e.txt
C:\Users\阚开豪\Desktop\javaFile\f.doc
(三)FileFiter过滤器的原理和使用
FileFilter过滤器的使用和原理
在File类中有两个和ListFiles重载的方法,方法的参数传递的就是过滤器。
FIle[ ] Listfiles( FileFilter filter )
java.io.FileFilter
接口:用于抽象路径名(File)过滤器。
- 作用:用来过滤文件(File对象)
- 抽象方法:用来过滤文件(File)
boolean accept(File pathname)
:测试指定抽象路径名是否应该包含在某个路径名的列表中。
参数:
File pathname:使用ListFiles方法遍历目录,得到每一个文件对象。
File [ ] ListFiles (FilenameFilter filter)
java.io.FilenameFilter
接口:实现此接口的类实例可以用于过滤文件器文件名
- 作用:用于过滤文件名称
- 抽象方法:用来过滤文件的方法
boolean accept( File dir, String name )
:测试指定文件是否应该包含在某一文件列表当中。
参数:
File dir:构造方法中传递的被遍历的目录
String name:使用ListFiles方法遍历目录,获取的每一个文件/文件夹名称。
注意:两个过滤器接口没有实现类,需要我们自己写实现类,重写过滤的方法accept,在方法中定义过滤的规则。
import java.io.File;
import java.io.FileFilter;
public class Fmpl implements FileFilter {
@Override
public boolean accept(File pathname) {
if(pathname.isDirectory()){
return true;
}
return pathname.getName().toLowerCase().endsWith(".java");
}
}
import java.io.File;
public class F {
public static void main(String[] args) {
File file =new File("C:\\Users\\阚开豪\\Desktop\\javaFile");
getALLfile(file);
}
private static void getALLfile(File file) {
File [] files =file.listFiles(new Fmpl());
for(File f:files){
if(f.isDirectory())
getALLfile(f);
else
System.out.println(f);
}
}
}
输出为:C:\Users\阚开豪\Desktop\javaFile\g.java
Lambda优化
import java.io.File;
public class F {
public static void main(String[] args) {
File file =new File("C:\\Users\\阚开豪\\Desktop\\javaFile");
getALLfile(file);
}
private static void getALLfile(File file) {
File[] files = file.listFiles(pathname ->
pathname.isDirectory()||pathname.getName().
toLowerCase().endsWith(".java"));
for(File f:files){
if(f.isDirectory())
getALLfile(f);
else
System.out.println(f);
}
}
}
三、IO概述
(一)IO简介和分类
- 我们把数据的传输,可以看作是数据流动,按照流动的方向以内存为基准分为输入和输出,即流向内存的是输入流,流出内存的是输出流。
- Java中I/O操作主要指使用
java.io
包下内容进行输入输出操作。输入也叫做读取数据,输出也叫写出数据。
分类 - 输入流:把数据从其他设备上读取到内存的流
- 输出流:把数据从内存中写出到其他设备的流。
- 格局数据类型分为:字节流和字符流。
1个字符=2个字节;1个字节=8个二进制位。
输入流 | 输出流 |
---|---|
字节输入流 InputStrean | 字节输出流 OutputStream |
字符输入流 Reader | 字符输出流 Writer |
注意:一切皆为字节。
(二)字节输出流【OutputStream】
java.io.OutpuStream
:此抽象类是表示输出字节流的所有类的超类。
成员方法:
pubilc void coles( )
:关闭此输出流并释放与此流相关联的任何系统资源public void flush( )
:刷新此输出流并强制任何缓冲的输出字节被写出。public void write( byte[ ] b )
:将b.length字节从指定的字节数组写入此输出流。public void write( byte[ ] b, int off, int len)
:从指定的字节数组中写入len字节,从偏移量off开始输出到此输出流。public abstract void write(int b)
:将指定的字节输出流。
FileOutputStream
java.io.FileOutputStream
:文件字节输出流- 作用:把内存中的数据写入到硬盘的文件中。
构造方法 FileOutputStream(String name)
:创建一个 向具有指定名称的文件中写入数据的输出文件流。FileOutputStream(File file)
:创建一个向指定File对象表示的文件中写入数据的文件输出流。- 参数:写入数据的目的
String name:目的是一个文件的路径。
File file:目的是一个文件 - 构造方法的作用:
- 创建一个FileOutputStream对象
- 根据构造方法中传递的文件/文件路径,创建一个空的文件。
- 会把FileOutputStream对象指向创建好的文件。
写入数据的原理:
java程序 -> JVM -> OS(操作系统)-> OS调用写数据的方法 -> 把数据写入到文件中
字节输出流的使用步骤:
1.创建一个FileOutputStream对象,构造方法中传递写入数据的目的地
2. 调用write方法,把数据写到文件中
3. 释放资源
测试代码
import java.io.FileOutputStream;
import java.io.IOException;
public class FileOut1 {
public static void main(String[] args) throws IOException {
FileOutputStream fos =new FileOutputStream
("C:\\Users\\阚开豪\\Desktop\\javaFile\\e.txt");
fos.write(98);
fos.close();
}
}
注意:任意的文本编辑器打开文件时,都会查询编码表把字节转换为字符表示。
字节输出流写多个字节的方法
public void write( byte[ ] b )
:将b.length字节从指定的字节数组写入此输出流。
注意:
- 如果写的第一个字节是正数(0-127),查询ASCII表
- 如果第一个字节是负数,那第一个字节会和第二个字节两个字节组成一个中文表示,查询GBK。`
public class FileOut2 {
public static void main(String[] args) throws IOException {
FileOutputStream fos1 = new FileOutputStream
("C:\\Users\\阚开豪\\Desktop\\javaFile\\e.txt");
//byte [] b={65,66,67,68}; ABCD
byte [] b={-65,-9,90,80};//亏ZP
fos1.write(b);
fos1.close();
}
}
public void write( byte[ ] b, int off, int len)
:从指定的字节数组中写入len字节,从偏移量off开始输出到此输出流。int off
:数组开始的索引int len
:几个字节
import java.io.FileOutputStream;
import java.io.IOException;
public class FileOut2 {
public static void main(String[] args) throws IOException {
FileOutputStream fos = new FileOutputStream
("C:\\Users\\阚开豪\\Desktop\\javaFile\\e.txt");
byte [] b={65,66,67,68};//ABCD
fos.write(b,2,2);//CD
/*写入字符的方法:使用String类中的方法把字符串转化为字符数组
byte[ ] getBytes()
*/
byte [] b1 = "你好Java!".getBytes();
fos.write(b1);//CD你好Java!
fos.close();
}
}
(三)字节输入流【InputStream】
java.io.InputStream
:字节输入流。此抽象类是表示字节输入流的所有类的超类。
定义所有子类共性的方法int read()
:从输入流中读取数据的下一个字节。int read(byte [ ])
:从输入流中读取一定数量的字节,并将其存储在缓冲区数组b中。void close( )
:关闭此输入流释放与该流关联的所有系统资源。
构造方法FileInputStream(String name)
- `FileInputStream(File file)
- 参数
`String name:文件的路径
File file:文件
作用
1. 会创建一个FIleInputStream对象
2. 会把该对象指定构造方法中要读取的文件
字节输入流读取一个字节
字节输入流的使用步骤(重点):- 创建FileInputStream对象,构造方法中绑定要读取的数据源
- 使用该对象中的方法read,读取文件
- 释放资源
import java.io.FileInputStream;
import java.io.IOException;
public class FileIn1 {
public static void main(String[] args) throws IOException {
FileInputStream fis = new FileInputStream("C:\\Users\\阚开豪\\Desktop\\javaFile\\e.txt");
while (true){
int len = fis.read();
if(len==-1)
break;
System.out.println(len);
}
fis.close();
}
}
字节输入流读取多个字节
int read (byte [ ] b )
:从输入流读取一定数量的字节,并将其存储到缓冲区数组b中。
- byte[ ]作用:起到缓冲作用,存储每次读取到的多个字节,数组的长度一般定义为1024(1kb)或者1024整数倍。
- 返回值int是每次读取的有效字节个数
- String类的构造方法
String ( byte [ ] bytes)
:把字节数组转换为字符串String ( byte[ ] bytes, int offset, int ength)
:把字节数组的一部分转换为字符串 offset:数组的开始索引 length:转换的字节个数
import java.io.FileInputStream;
import java.io.IOException;
public class FileIn2 {
public static void main(String[] args) throws IOException {
FileInputStream fis = new FileInputStream("C:\\Users\\阚开豪\\Desktop\\javaFile\\e.txt");
byte[] bytes = new byte[1024];
int len =0;
while(fis.read(bytes)!=-1){
System.out.println(new String(bytes));//CD你好Java!
}
}
}
字节流练习:文件复制
文件复制的步骤
- 创建一个字节输入流对象,构造方法中绑定要输入的数据源
- 创建一个字节输出流对象,构造方法中绑定要写入的目的地
- 使用字节输入流对象中的方法read读取文件
- 使用字节输出流的方法write,把读取到的字节写入目的地文件中
- 释放资源
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
public class Filea {
public static void main(String[] args) throws IOException {
FileInputStream fis = new FileInputStream("C:\\Users\\阚开豪\\Desktop\\javaFile\\e.txt");
FileOutputStream fos =new FileOutputStream("C:\\Users\\阚开豪\\Desktop\\javaFile\\b\\d.txt");
byte [] bytes =new byte[1024];
int len=0;
while((len=fis.read(bytes))!=-1){
fos.write(bytes,0,len);
}
fis.close();
fos.close();
}
}
使用字节流读取中文文件
1个中文
GBK:占用两个字节
UTF-8:占用三个字节
(四)字符输入流【Reader】
java.io.Reader
:字符输入流,是字符输入流最顶层父类,定义了一些共性的成员方法,是一个抽象类。
共性的成员方法int read( )
:读取单个字符并返回int read( char [ ] cbuf )
:一次读取多个字符,将字符读入数组。void close( )
:关闭该流并释放与之关联的所有资源。java.io.FileReader extends InputStremReader extends Reader
FileReader:文件字符输入流
作用:把硬盘文件中的数据以字符的方式读取到内存中
构造方法:FileReader( String filename)
FileReader(File file)
参数:读取文件的数据源
String filename:文件的路径
File file:一个文件
FileReader构造方法作用:
1. 创建一个FileReader对象
2. 会把FileReader对象指向要读取的文件
字符输入流使用步骤
- 创建FileReade对象,构造方法中绑定要读取的数据源
- 使用FileReader对象中的方法read读取文件
- 释放资源
import java.io.FileReader;
import java.io.IOException;
public class Fr1 {
public static void main(String[] args) throws IOException {
FileReader fr=new FileReader("C:\\Users\\阚开豪\\Desktop\\javaFile\\e.txt");
/*int len=0;
while((len=fr.read())!=-1){
System.out.println((char)len);
}*/
char [] cs =new char[1024];
int len1=0;
while((len1=fr.read(cs))!=-1){
System.out.println(new String(cs,0,len1));
}
fr.close();
}
}
(五)字符输出流【Writer】
java.io.Writer
:字符输出流,是所有字符输出流最顶层父类,是一个抽象类。
共性的成员方法void write(int c)
:写入单个字符void write( char [ ] cbuf )
:写入字符数组abstract void write( char [ ] cbuf, int off, int len)
:写入字符数组的某一部分,off数组开始索引,len写的字符个数。void write( String str)
:写入字符串void write( String str, int off ,int len)
:写入字符串的一部分,off字符串的开始索引,len写的字符个数。void flush( )
:刷新该流的缓冲void colse( )
:关闭此流
FileWriter:文件字符输出流
作用:把内存中字符数据写入到文件中。
构造方法:
-FileWriter( File file)
:根据给定的File对象构造一个FileWriter对象。
-FileWriter(String filename)
:根据给定的文件名构成一个FileWriter对象。
参数:写入数据的目的地
- String filename:文件的路径
- File file:一个文件
构造方法的作用:
1. 会创建一个FileWriter对象
2. 会根据构造方法中传递的文件/文件路径,创建文件
3. 会把FileWriter对象指向创建好的文件
字符输出流的使用步骤:
1. 创建FileWriter对象,构造方法中绑定要写入数据的目的地
2. 使用FileWriter中的方法write,把数据写到内存缓冲区中(字符转换为字节的过程)
3. 使用FileWriter中的方法flush,把内存缓冲区中的数据,刷新到文件中
4. 释放资源(会先把内存缓冲区中的数据刷新到文件中)
import java.io.FileWriter;
import java.io.IOException;
public class Fw {
public static void main(String[] args) throws IOException {
FileWriter fw = new FileWriter("C:\\Users\\阚开豪\\Desktop\\javaFile\\e.txt");
fw.write(98);
fw.flush();
}
}
关闭和刷新的区别
flush
:刷新缓冲区,流对象可以继续使用colse
:先刷新缓冲区,再通知系统释放资源。流对象不可以再被使用了。
字符数据流写数据的其他方法
void write( char[ ] cbuf)
:写入字符数组abstract void write(char [ ] cbuf ,int off, int len)
:写入字符数组的某一部分,off数组的开始索引,len写的字符个数void write( String str)
:写入字符串void write( String str,int off, int len)
:写入字符串的某一部分,off字符串的开始索引,len写的字符个数。
import java.io.FileWriter;
import java.io.IOException;
public class Fwelse {
public static void main(String[] args) throws IOException {
FileWriter fw =new FileWriter("C:\\Users\\阚开豪\\Desktop\\javaFile\\e.txt");
char [] cs={'a','b','c','d'};
fw.write(cs);
fw.write(cs,1,3);
fw.write("你好");
fw.write("世界",2,3);
fw.close();
}
}
续写和换行
import java.io.FileWriter;
import java.io.IOException;
public class Fw1 {
public static void main(String[] args) throws IOException {
FileWriter fw =new FileWriter("C:\\Users\\阚开豪\\Desktop\\javaFile\\e.txt",true);
fw.write("zhangsan");
fw.write("\n\n");
fw.write("java");
fw.close();
}
}
(六)异常处理
格式
try {
可能会出现异常的代码
}catch(异常类 变量名){
异常的处理逻辑
}finally{
一定会指定的代码
资源释放
}
- jdk1.7以前格式
import java.io.FileWriter;
import java.io.IOException;
public class Fe {
public static void main(String[] args) {
FileWriter fw =null;
try{
fw =new FileWriter("C:\\Users\\阚开豪\\Desktop\\javaFile\\z.txt");
}catch (IOException e){
System.out.println(e);
}finally {
if(fw!=null){
try{
fw.close();
}catch (IOException e){
e.printStackTrace();
}
}
}
}
}
jdk7
try(定义流对象;定义流对象...){
可能会出现异常的代码
}catch(异常类变量 变量名){
异常处理逻辑
}
jdk9
A a= new A();
B b=new B():
try(a,b){
可能会出现异常的代码
}catch(异常类变量 变量名){
异常处理逻辑
}
四、属性集
(一)概述
java.util.Properties
集合extengds Hashtabe<k,v> implemrnts Map<k,v>
Properties
类表示一个持久的属性集,可以保存在流中或从流中加载。Properties
集合是一个唯一和IO流相结合的集合。
1. 可以使用方法store,把集合中临时数据持久化写入硬盘中存储。
2. 可以使用方法load,把硬盘中保存的文件,读取到集合中使用Properties
是一个双列集合,key和value默认都是字符串。Properties
集合中有一操作字符串的特有方法
Object setProperty(String key,String value)
:调用Hashtable方法put。String getProperty(String key)
:通过key找到value值,此方法相当于Map集合中的get(key)方法。Set<String> stringPropertyNames()
:返回此属性列表中的键集。
import java.util.Properties;
import java.util.Set;
public class Pm {
public static void main(String[] args) {
Properties prop = new Properties();
prop.setProperty("zhangsan","shanghai");
prop.setProperty("lisi","beijing");
prop.setProperty("zhaosi","xian");
Set<String> set =prop.stringPropertyNames();
for(String key : set){
String values = prop.getProperty(key);
System.out.println(key+"=="+values);
}
}
}
(二)store方法
void store(OutputStream out,String comments)
void store(Writer writer,String comments)
- 参数:
1. OutputStream out:字节输出流,不能写入中文
2. Writer writer:字节输出流,可以写中文
3. String comments:注释。不能使用中文,一般使用空字符串。 - 使用步骤:
1. 创建Properties集合对象,添加数据
2. 创建流对象,构造方法中绑定要输出的目的地
3. 使用方法store,把集合中临时数据,持久化写入到硬盘中存储。
4. 释放资源
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Properties;
import java.util.Set;
public class Pm {
public static void main(String[] args) throws IOException {
Properties prop = new Properties();
prop.setProperty("zhangsan","shanghai");
prop.setProperty("lisi","beijing");
prop.setProperty("zhaosi","xian");
/*FileWriter fw =new FileWriter("C:\\Users\\阚开豪\\Desktop\\javaFile\\e.txt");
prop.store(fw,"C:\\Users\\阚开豪\\Desktop\\javaFile\\b\\d.txt");
fw.close();*/
prop.store(new FileOutputStream("C:\\Users\\阚开豪\\Desktop\\javaFile\\b\\d.txt"),"");
}
}
(三)load方法
void load(InputStream inStream)
void load(Reader reader)
- 参数:
1. InputStream inStream:字节输入流,不能读取含有中文的键值对
2. Reader reader:字符输入流,能读取含有中文的键值对 - 使用步骤
1. 创建Properties集合对象
2. 使用Properties集合对象方法load读取保存键值对的文件
3. 遍历集合 - 注意:
存储键值对的文件中可以使用#进行注释。
import java.io.*;
import java.util.Properties;
import java.util.Set;
public class Pm {
public static void main(String[] args) throws IOException {
Properties prop = new Properties();
prop.setProperty("zhangsan","shanghai");
prop.setProperty("lisi","beijing");
prop.setProperty("zhaosi","xian");
//prop.load(new FileReader("C:\\Users\\阚开豪\\Desktop\\javaFile\\e.txt"));
prop.load(new FileInputStream("C:\\Users\\阚开豪\\Desktop\\javaFile\\e.txt"));
Set <String> set =prop.stringPropertyNames();
for(String key:set){
String value = prop.getProperty(key);
System.out.println(key+" "+value);
}
}
}
五、缓冲流
(一)概述
缓冲流也叫高效流,是对四个基本的FilesXxx
流的增强。
- 字节缓冲流:
BufferedInuputStream
`BufferedOutputStream - 字符缓冲流:
BufferedReader
BufferderedWriter
- 缓冲流的基本原理,是在创建流对象时,会创建一个内置的默认大小的缓冲区数组,通过缓冲区读写,减少系统的IO次数,从而提高读写的效率
(二)字节缓冲输出流 java.io.BufferedOutputStream extends OutputStream
- 构造方法
BufferedOutputStream(OutputStream out)
:创建一个新的缓冲输出流,将数据写入指定的底层输出流BufferedOutputStream(OutputStream out, int size)
:创建一个新的缓冲输出流,将具有指定缓冲区大小的数据写入指定的底层输出流
- 参数:
- OutputStream:字节输出流
- int size:指定缓冲流内部缓冲区的大小,不指定默认
- 使用步骤
- 创建FileOutputStream对象,构造方法中绑定要输出的目的地
- 创建BufferedOutputStream对象,构造方法中传递FileOutputStream对象,提高效率
- 使用write方法,把数据写入到内部缓冲区中
- 使用flush方法,把内部缓冲区中的数据,刷新到文件中
- 释放资源(会先调用flush方法刷新数据,第四步可省略)
import java.io.BufferedOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;
public class BFO {
public static void main(String[] args)throws IOException {
FileOutputStream fos = new FileOutputStream("C:\\Users\\阚开豪\\Desktop\\javaFile\\e.txt");
BufferedOutputStream bos = new BufferedOutputStream(fos);
bos.write("Hello,java!".getBytes());
bos.flush();
bos.close();
}
}
文件复制
- 创建字节缓冲输入流对象,构造方法中传递字节输入流
- 创建字节缓冲输出流对象,构造方法中传递字节输出流
- 使用字节缓冲输出流方法read,读取文件
- 使用方法write,把读取到的数据写入到内部缓冲区中
- 释放资源(会先把缓冲区中的数据,刷新到文件中)
(三)字符缓冲输出流
java.io.BufferdWriter extends Writer
构造方法BufferedWriter( Writer out )
:创建一个使用默认大小的输出缓冲区的缓冲字符输出流BufferedWriter( Writer out, int sz)
:创建一个使用给定大小的输出缓冲区的新缓冲字符输出流
参数Writer out
:字符输出流int sz
:指定缓冲区的大小,不写默认大小
特有的成员方法void newline( )
:写入一个行分隔符。
使用步骤
- 创建字符缓冲输出流对象,构造方法中传递字符输出流
- 调用字符缓冲输出流对象中方法write,把数据写到内存缓冲区中
- 调用方法flush,把内存缓冲区的数据刷新到文件中
- 释放资源
import java.io.*;
public class BFO {
public static void main(String[] args)throws IOException {
BufferedWriter bw = new BufferedWriter(new FileWriter("C:\\Users\\阚开豪\\Desktop\\javaFile\\e.txt"));
for (int i = 0; i < 10; i++) {
bw.write("你好Java!");
bw.newLine();
}
bw.flush();
bw.close();
}
}
(五)字符缓冲输入流
构造方法
BufferedReader( Reader in )
:创建一个使用默认大小输入缓冲区的缓冲字符输入流BufferedReader( Reader in , int sz)
:创建一个使用指定大小输入缓冲区的缓冲字符输入流
参数- Reader in :字符输入流
特有的成员方法 String readline( )
:读取一个文本行。读取一行数据的行的终止符号。(黄行,回车,回车后加换行)- 返回值:包含该行内容的字符串,不包含任何终止符,如果到达流末尾,则返回null。
使用步骤
- 创建字符缓冲输入流对象,构造方法中传递字符输入流
- 使用字符缓冲输入流中的方法read/readline读取文本
- 释放资源
import java.io.*;
public class BFO {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new FileReader("C:\\Users\\阚开豪\\Desktop\\javaFile\\e.txt"));
String line;
while ((line = br.readLine()) != null) {
System.out.println(line);
}
br.close();
}
}
六、转换流
(一)字符编码和字符集
字符编码
- 编码:字符(能看懂的)-- 字节(看不懂的)
- 解码:字节(看不懂的)-- 字符(能看懂的)
字符编码:就是一套自然语言的字符与二进制之间的对应规则。
编码表:生活中文字和计算机中二进制的对应规则
字符集:也叫编码表。是一个系统支持的所有字符的合集,包括个国家文字、标点符号、图像符号和数字。常见的有- ASCII字符集
- GBK字符集
- Unicode字符集
(二)转换输出流
java.io.OutputStreamWriter extends Writer
OutputStreamWriter
:是字符流通向字节流的桥梁,使用指定的charset将要写入流中的字符编码成字节。
构造方法OutputStreamWriter(OutputStream out)
:创建使用默认字符编码的OutputStreamWriter。OutputStreamWriter(OutputStream out, String charsetName)
:创建使用指定字符集的OutputStreamWriter。
参数OutputStream out
:字节输出流,可以用来写转换之后的字节到文件中String charsetName
:指定的编码表名称,不区分大小写(UTF-8、GBK…)
使用步骤
- 创建OutputStreamWriter对象,构造方法中传递字节输出流和指定的编码表名称
- 使用OutputStreamWriter中的方法write,把字符转换为字节存储缓冲区中
- 使用flush方法,把内存缓冲区的字节刷新到文件中
- 释放资源
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
public class OS {
public static void main(String[] args) throws IOException{
write_utf();
write_gbk();
}
private static void write_utf() throws IOException {
OutputStreamWriter osw =new OutputStreamWriter(new FileOutputStream("C:\\Users\\阚开豪\\Desktop\\javaFile\\e.txt"),"utf-8");
osw.write("你好");
osw.flush();
osw.close();
}
private static void write_gbk() throws IOException{
OutputStreamWriter osw =new OutputStreamWriter(new FileOutputStream("C:\\Users\\阚开豪\\Desktop\\javaFile\\e.txt"),"gbk");
osw.write("你好");
osw.flush();
osw.close();
}
}
(三)转换输入流
java.io.InputStreamReader extends Reader
InputStreamReader
:是字节流通向字符流的桥梁,它使用指定的charset读取字节并将其解码为字符。`
构造方法InputStream(InputStream in)
:创建一个使用默认字符集的InputStreamReader。InuputStreamReader(InputStram in, String charsetName)
:创建使用指定字符集的的InputStreamReader。
参数
InputStream in
:字节输入流,用来读取文件中保存的字节String charsetName
:指定编码表名称。不指定默认使用UTF-8。
使用步骤:- 创建InputStream对象,构造方法中传递字节输入流和指定的编码表名称
- 使用InputStreamReader对象中的方法read读取文件
- 释放资源
注意事项:构造方法中的指定编码表名称要和文件的编码相同。
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
public class IS {
public static void main(String[] args) throws IOException {
read_utf();
read_gbk();
}
private static void read_gbk() throws IOException {
InputStreamReader isr = new InputStreamReader(new FileInputStream("C:\\Users\\阚开豪\\Desktop\\javaFile\\e.txt"),"gbk");
int len=0;
while ((len=isr.read())!=-1){
System.out.println((char)len);
}
isr.close();
}
private static void read_utf() throws IOException{
InputStreamReader isr = new InputStreamReader(new FileInputStream("C:\\Users\\阚开豪\\Desktop\\javaFile\\e.txt"),"utf-8");
int len=0;
while ((len=isr.read())!=-1){
System.out.println((char)len);
}
isr.close();
}
}
案例:转换文件编码
- 指定GBK编码的转换流读取文件
- 使用UTF-8编码的转换流写出文件
import java.io.*;
public class IOS {
public static void main(String[] args) throws IOException {
InputStreamReader isr =new InputStreamReader(new FileInputStream("C:\\Users\\阚开豪\\Desktop\\javaFile\\e.txt"),"GBK");
OutputStreamWriter osw =new OutputStreamWriter(new FileOutputStream("C:\\Users\\阚开豪\\Desktop\\javaFile\\z.txt"),"UTF-8");
int len=0;
while((len=isr.read())!=-1){
osw.write(len);
}
osw.close();
isr.close();
}
}
七、序列化和反序列化
(一)概述
- 把对象以流的方式写入到文件中保存。叫写对象也叫对象的序列化。
- 对象中包含的不仅仅是字符,使用字节流。(ObjectOutputStream:对象的序列化流)
- 把文件中保存的对象以流的方式读取出来,叫读对象也叫对象的反序列化。
- 读取的文件保存的都是字节,使用字节流(ObjectInputStream:对象的反序列化流)
(二)对象的序列化流
java.io.ObjectOutputStream extends OutpuStream
- 作用:把对象以流的方式写入到文件保存
构造方法
-ObjectOutputStream(OutputStream out)
:创建写入指定OutputStream的ObjectOutputputStream。
-参数:OutputStream out:字节输出流
特有的成员方法 void writeObject(Objecr obj)
:将指定的对象写入ObjectOutputStream。
使用步骤- 创建ObjectOutputStream对象,构造方法中传递字节输出流
- 使用方法writeObject;把对象写入到文件中
- 释放资源
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
public class OOS {
public static void main(String[] args) throws IOException {
ObjectOutputStream oos =new ObjectOutputStream(new FileOutputStream("C:\\Users\\阚开豪\\Desktop\\javaFile\\e.txt"));
oos.writeObject(new Person("zhangsan",18));
oos.close();
}
}
注意:序列化和反序列化时会抛出没有序列化异常。
- 通过实现
java.io.Serializable
接口启用序列化功能。
(三)对象的反序列化流 java.io.ObjectInputStream extends InputStream
- 作用:把文件中保存的对象,以流的方式读取出来使用
构造方法
-ObjectInputStream(InputStream in)
:创建从指定InputStream读取的ObjectInputStream。- 参数:InputStream in:字节输入流
特有的成员方法 Object readObject( )
从ObjectInputStream读取对象。
使用步骤
- 创建ObjectInputStream对象,构造方法中国传递字节输入流
- 使用ObjectInputStream对象中的方法readObject读取保存对象的文件
- 释放资源
- 使用读取出来的对象(打印)
- 参数:InputStream in:字节输入流
import java.io.FileInputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
public class OIS {
public static void main(String[] args) throws IOException, ClassNotFoundException {
ObjectInputStream ois =new ObjectInputStream(new FileInputStream("C:\\Users\\阚开豪\\Desktop\\javaFile\\e.txt"));
Object o =ois.readObject();
System.out.println(o);
ois.close();
}
}
反序列化的前提
- 类必须实现Serializable
- 必须存在类对应的class文件
(四)瞬态关键字 - static关键字:静态
静态优先于非静态加载到内存中。
被static修饰的成员变量不能被序列化,序列化的都是对象 - transient关键字:瞬态
被transient修饰成员变量不能被序列化。
(五)反序列化操作异常处理
- 在class文件在序列化对象后发生修改,反序列化会失败并抛出
InvalidClassException
异常,原因如下:- 该类的序列版本号与从流中读取的类描述的版本号不匹配
- 该类包含未知数据类型
- 该类没有可访问的无参数构造方法
-解决方法
加入序列版本号
-private static final long serialVersionUID = long int
;
(六)案例:序列化集合
- 将存储的集合对象序列化后输出
import java.io.*;
import java.util.ArrayList;
public class OOIIS {
public static void main(String[] args) throws IOException, ClassNotFoundException {
ArrayList<Person> list = new ArrayList<>();
list.add(new Person("zhangsan",18));
list.add(new Person("lisi",90));
list.add(new Person("wangmazi",25));
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("C:\\Users\\阚开豪\\Desktop\\javaFile\\e.txt"));
oos.writeObject(list);
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("C:\\Users\\阚开豪\\Desktop\\javaFile\\e.txt"));
Object o = ois.readObject();
ArrayList<Person> list1 = (ArrayList<Person>) o;
for(Person p:list1){
System.out.println(p);
}
ois.close();
oos.close();
}
}
八、打印流
(一)概述
-java.io.PrintStream
:打印流。为其他输出流添加了功能,使它们能够方便地打印各种数据值表示形式。
- 特点:
1. 只负责数据的输出,不负责数据的读取。
2. 与其他输出流不同,打印流不会抛出IO异常。
3. 有特有的方法,print和println。
(二)使用
构造方法
-PrintStream(File file)
:输出的目的地是一个文件
-PrintStream(OutputStream out)
:输出的目的地是一个字节输出流
-PrintStream(String fileName)
:输出的目的地是一个文件路径
注意
1. 如果使用继承自父类的write方法写数据,那么查看数据的时候会查询编码表
2. 如果使用在自己特有的方法写数据,写的数据原样输出。
import java.io.FileNotFoundException;
import java.io.PrintStream;
public class PSM {
public static void main(String[] args) throws FileNotFoundException {
PrintStream psm = new PrintStream("C:\\Users\\阚开豪\\Desktop\\javaFile\\e.txt");
psm.write(97);//a
psm.println(97);//97
}
}
- 使用
System.setOut
方法改变输出语句的目的地改为参数中传递的打印流的目的地。 static void setOut(PrintStream Out)
:重新分配标准输出流
import java.io.FileNotFoundException;
import java.io.PrintStream;
public class PSM {
public static void main(String[] args) throws FileNotFoundException {
PrintStream psm = new PrintStream("C:\\Users\\阚开豪\\Desktop\\javaFile\\e.txt");
System.setOut(psm);
System.out.println("Hello,java!");
psm.close();
}
}