File类
这里简单说下我对这个类的理解,我认为File类就是一个抽象的东西,可以开解成它在我们创建对象时传入的路径,将这个路径看成是一个类,然后计算机内部就用这个路径去操作文件。
构造方法:
File(String pathname) 通过将给定的路径名字符串转换为抽象路径名来创建新的File实例
File(String parent, String child) 从父路径名字符串和子路径名字符串创建新的File实例
File(File parent, String child) 从父抽象路径名和子路径名字符串创建新的 File实例
常用方法:
特别注意list()返回的是字符串类型的文件名称,listFile()方法返回的是文件类型
对文件进行操作的常用操作
//================================对文件进行操作的方法=====================
File file=new File("D:\\javatest\\aa.txt");
//判断文件是否存在
if (!file.exists()){
//创建如果文件不存在则创建文件
boolean newFile = file.createNewFile();
}
System.out.println("文件长度:"+file.length());
System.out.println("是否是文件:"+file.isFile());
System.out.println("是否是目录:"+file.isDirectory());
System.out.println("是否存在这份文件:"+file.exists());
System.out.println("是否是可执行文件:"+file.canExecute());
System.out.println("是否是可读文件:"+file.canRead());
System.out.println("是否是可写文件:"+file.canWrite());
System.out.println("是否是隐藏文件"+file.isHidden());
System.out.println("文件名称:"+file.getName());
System.out.println("文件路径:"+file.getParent());
System.out.println("文件绝对路径:"+file.getAbsolutePath());
System.out.println("文件的相对路径:"+file.getAbsoluteFile());
System.out.println("文件父路径:"+file.getParent());
System.out.println("文件父路径:"+file.getParentFile());
System.out.println("文件可用总空间大小:"+file.getTotalSpace());
System.out.println("文件可用空间大小:"+file.getFreeSpace());
System.out.println("文件最后修改时间:"+file.lastModified());
System.out.println("文件是否删除成功:"+file.delete());
对目录经常操作的常用方法
//====================================文件目录操作==========================================
File dir=new File("D:\\javatest\\c");
//判断目录是否为存在
if (!dir.exists()){
//如果不存在则创建
boolean issc = dir.mkdir();//创建的前提是父目录存在,否则包空指针异常
dir.mkdirs();//创建多级目录,不需要父目录存在
System.out.println("目录是否创建成功:"+issc);
}
System.out.println("是否是目录:"+dir.isDirectory());
System.out.println("是否是文件:"+dir.isFile());
System.out.println("目录下所有文件和目录名称");
String[] list = dir.list();
Arrays.stream(list).forEach(s-> System.out.println(s));
System.out.println("目录下所有文件的路径");
//获取目录下所有文件
File[] files = dir.listFiles();
Arrays.stream(files).forEach(s-> System.out.println(s));
//通过过滤获取目录下所有文件问.jpg结尾的文件
File[] files1 = dir.listFiles(pathname -> pathname.getName().endsWith(".jpg"));
Arrays.stream(files1).forEach(s-> System.out.println("目录下文件名为.jsp结尾的文件名:"+s));
i/o流
流可以看成是文件传输中的管道,那边要输出或者输入要先先将管道连好,不管输入还是输出另一头连接的是一个泳池,不会直接流到目的地。
InputStream字节输入流
常用实现类:FileInputStream
作用将文件的以字节为单位传到内存中,创建对象时传入的参数是一个文件类型的对象,或者说是一个文件的路径(至于原因可我上面说过可以将路径看成文件)
//如果文件不存在,系统会报错
FileInputStream fis = new FileInputStream("D:\\javatest\\a.txt");
常用方法:
使用read()方法对数据进行读
byte[] b=new byte[10];
int lent;
while((lent=fis.read(b))!=-1){//lent是实际读取到数组数组缓冲区中元素的个数
System.out.println(new String(b));
}
OutputStream字节输出流
OutputStream跟InputStream大致相同
获取对象方法如下:
//如果文件不存在,系统会自动帮创建一个文件,如果参数没有设置,后面写入的字节会覆盖前面的,定义为true则在后面追加写
FileOutputStream fos=new FileOutputStream("D:\\javatest\\a.txt",true);
void write(int b)
将指定的字节写入此文件输出流 一次写一个字节数据
void write(byte[] b)
将 b.length字节从指定的字节数组写入此文件输出流 一次写一个字节数组数据
void write(byte[] b, int off, int len)
将 len字节从指定的字节数组开始,从偏移量off开始写入此文件输出流 一次写一个字节数组的部分数据
FileRead文件字符输入流与bufferedRead字符缓冲流
由于字节流是一次对一个字节进行操作的,而中文以gbk规则编码是两个字节一个汉字,utf-8是三个字节一个汉字,以utf-8编码格式为例:如果使用字节流对汉字进行操作就会产生只读到或者写入三分之一个字符这样就会产生乱码。所以就产生了字符流,由于中文编码第一个字节肯定是负数所以当读到一个字节是负数之后,在根据编码规则连续读入几个字节后再对字节进行翻译,这样就不会导致乱码了。所以字符流一次是对一个字符进行操作。
FileRead的构造方法
FileReader(File file)在给定从中读取数据的 File 的情况下创建一个新 FileReader对象
FileReader(String fileName)在给定从中读取数据的文件名的情况下创建一个新 FileReader对象
我的理解是既然是要使用流来传输数据,那么参数肯定是一个要传输的文件啊,而以前说过了,文件类其实就是一个文件路径
常用方法:
int read() 一次读一个字符数据
int read(char[] cbuf) 一次读一个字符数组数据
//一次读取一个字符
int r= fr.read();
//一次读取多个字符
char[] c=new char[1024];
int len;
System.out.println("---------------------");
while((len= fr.read(c))!=-1){
System.out.println(new String(c));
}
BufferdRead字符输出缓冲流
BufferedReader:从字符输入流读取文本,缓冲字符,以提供字符,数组和行的高效读取,可以指定缓冲区大小,或者可以使用默认大小。 默认值足够大,可用于大多数用途
构造方法:
BufferedReader(Reader in) 创建字符缓冲输入流对象 (它是对字符流进行一个加强,所以参数肯定是要被加强的流啊)
常用方法:
int read() 一次读一个字符数据
int read(char[] cbuf) 一次读一个字符数组数据
注意:跟字符流一样的只是多了个readLine()读一行的方法,原理是遇到r/n就结束,而且readLine()读取到最后返回的是null而read()最后读取到的是-1;read()方法返回的是读取字节个数,readline()方法返回的是读取的值
补充小知识点:/r/n是Windows的换行,/ r是苹果系统的换行,/n是linux的换行
//创建字符缓冲流对象,在已有的基础上进行缓冲,提高读取效率
BufferedReader br=new BufferedReader(fr);
//方法跟字符流差不多,但是多了个readLine()方法一次读取一行
String str;
//readLine()读取到最后返回的是null而read()最后读取到的是-1;
System.out.println("---------------------");
while((str=br.readLine())!=null){
System.out.println(str);
}
//先开后关,后开先关
br.close();
fr.close();
FileWriter文件字符输入流与bufferedWriter字符缓冲流
构造方法:
FileWriter(File file)根据给定的 File 对象构造一个 FileWriter 对象
FileWriter(File file, boolean append)根据给定的 File 对象构造一个 FileWriter 对象
FileWriter(String fileName)根据给定的文件名构造一个 FileWriter 对象
FileWriter(String fileName, boolean append)根据给定的文件名以及指示是否附加写入数据的 boolean 值来构造 FileWriter 对象
常用方法:
void write(int c)写一个字符
void write(char[] cbuf)写入一个字符数组
void write(char[] cbuf, int off, int len)写入字符数组的一部分
void write(String str)写一个字符串
void write(String str, int off, int len)写一个字符串的一部分
跟BufferedRead一样,都有一个新方法,他的新方法为newline()可以看做是一个换行符。
小心得:字节输入流只能输出int类型的会根据编码表转换,byte[]数组,其中数组可以设置输入一部分,
字符输入流可以输入int类型,char[]类型,String类型的数据,其中数组跟字符串可以设置偏移量
总结:字符流跟缓流的方法大致一样
FileWriter fw=new FileWriter("d:\\javatest\\b.txt");
//一次写入一个字符
fw.write(97);
//写入一个字符数组
char[] c={'a','b','c','d','e','f'};
fw.write(c);
//写入一个字符数组的一部分
fw.write(c,0,3);
//写入一个字符串
String str="hello word,你好世界";
fw.write(str);
//写入字符串的一部分
fw.write(str,0,4);
fw.close();
转换流
-
InputStreamReader:是从字节流到字符流的桥梁,父类是Reader
它读取字节,并使用指定的编码将其解码为字符
它使用的字符集可以由名称指定,也可以被明确指定,或者可以接受平台的默认字符集
-
OutputStreamWriter:是从字符流到字节流的桥梁,父类是Writer
是从字符流到字节流的桥梁,使用指定的编码将写入的字符编码为字节
它使用的字符集可以由名称指定,也可以被明确指定,或者可以接受平台的默认字符集
构造方法:
InputStreamReader(InputStream in)使用默认字符编码创建InputStreamReader对象
InputStreamReader(InputStream in,String chatset)使用指定的字符编码创建InputStreamReader对象 OutputStreamWriter(OutputStream out)使用默认字符编码创建OutputStreamWriter对象
OutputStreamWriter(OutputStream out,String charset)使用指定的字符编码创建OutputStreamWriter对象
//方法一
//BufferedReader br=new BufferedReader(new FileReader("d:\\javatest\\a.txt"));
//BufferedWriter bw=new BufferedWriter(new FileWriter("d:\\\\javatest\\\\f.txt"));
//方法二
// BufferedReader br=new BufferedReader(new InputStreamReader(new FileInputStream("d:\\\\javatest\\\\a.txt")));
//BufferedWriter bw=new BufferedWriter(new OutputStreamWriter(new FileOutputStream("d:\\\\javatest\\\\f.txt")))
//方法三
Scanner sc=new Scanner(new FileInputStream("d:\\\\javatest\\\\a.txt") );
BufferedWriter bw=new BufferedWriter(new PrintWriter("d:\\\\javatest\\\\f.txt"));
while(sc.hasNextLine()){
String s=sc.nextLine();
bw.write(s);
bw.flush();
bw.newLine();
}
sc.close();
bw.close();
对象操作流
ObjectOutputStream序列化对象
- 对象序列化:就是将对象保存到磁盘中,或者在网络中传输对象
- 这种机制就是使用一个字节序列表示一个对象,该字节序列包含:对象的类型、对象的数据和对象中存储的属性等信息
- 字节序列写到文件之后,相当于文件中持久保存了一个对象的信息
- 反之,该字节序列还可以从文件中读取回来,重构对象,对它进行反序列化
简单来说就是把内存中的对象写入到文件中叫序列化,把文件对象读入内存叫做反序列化。
将Java对象的原始数据类型和图形写入OutputStream。 可以使用ObjectInputStream读取(重构)对象。 可以通过使用流的文件来实现对象的持久存储。 如果流是网络套接字流,则可以在另一个主机上或另一个进程中重构对象
构造方法:
ObjectOutputStream(OutputStream out) 创建一个写入指定的OutputStream的ObjectOutputStream
常用方法:
write(想要序列化什么类型就后面就加什么类型) 将指定的对象写入ObjectOutputStream
想要序列化一个自定义对象,必须实现Serializable接口。
Serializable是一个标记接口,实现该接口,不需要重写任何方法
public class Student implements Serializable {
//对象输出流,需要依赖基础的字节输出流
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("d:\\javatest\\a.txt"));
Student st = new Student("zangsan", "123456", 12);
//写入一个字节
oos.writeByte(10);
//写入一个字符,占两个字节
oos.writeChar('a');
//写入一个整形 4位
oos.writeInt(20);
//写入一个float类型 4位
oos.writeFloat(3.14f);
//写入一个double类型 8位
oos.writeDouble(3.14);
//写入一个字符串类型
oos.writeUTF("abcde");
//写入一个集合
ArrayList<Student> list = new ArrayList<>();
list.add(new Student("lisi", "123456", 22));
list.add(new Student("wngwu ", "12345617", 33));
list.add(new Student("zhaoliu", "1234516", 12));
oos.writeObject(list);
//写入一个对象,必须是先Serializable接口
oos.writeObject(st);
oos.close();
ObjectInputStream序列化对象
ObjectInputStream反序列化先前使用ObjectOutputStream编写的原始数据和对象
构造方法:
ObjectInputStream(InputStream in) 创建从指定的InputStream读取的ObjectInputStream
常用方法:
Object read(跟上面一样,反序列化什么类型就接什么类型)() 从ObjectInputStream读取一个对象
反序列化要跟序列化的顺序一致
void skipBytes(int 字节个数) 跳过指定字节个数反序列化,记住值字节个数。
//对象输入流,需要依赖基础的字节输入流
ObjectInputStream ois=new ObjectInputStream(new FileInputStream("d:\\javatest\\a.txt"));
//读取一个字节
/* System.out.println(ois.readByte());
//读取一个字符,占两个字节
System.out.println(ois.readChar());
//读取一个整形 4位
System.out.println(ois.readInt());*/
//跳过7个字节,文件指针往后移7位
ois.skipBytes(7);
//读取一个float类型 4位
System.out.println(ois.readFloat());
//读取一个double类型 8位
System.out.println(ois.readDouble());
//读取一个字符串类型
System.out.println(ois.readUTF());
//读取一个集合
((List)ois.readObject()).stream().forEach(s-> System.out.println(s));
//读取一个对象
System.out.println(ois.readObject());
ois.close();
序列化与反序列化的两个关键字:
-
serialVersionUID
- 用对象序列化流序列化了一个对象后,假如我们修改了对象所属的类文件,这时候我们使用反序列化,会抛出InvalidClassException异常!所以我们要给对象所属的类加一个serialVersionUID(可以看做是一个标记序列化的唯一标识)。
private static final long serialVersionUID = 100;
这个太长了我们可以通过idea自动生成:
点击file—>setting->editor->inspections->搜索Serializable->找到Serializable class without “serialVersionUID”,然后勾选,
回到类中将数遍指向类名自动生成就行了。
-
transient
- 如果一个对象中的某个成员变量的值不想被序列化,可以给该成员变量加transient关键字修饰,该关键字标记的成员变量不参与序列化过程
- RandomAccessFil类
构造方法:
RandomAccessFile(File file, String mode) (第二个参数是模式,设置是读文件还是写文件,参数如下:)
创建从中读取和向其中写入(可选)的随机访问文件流,该文件由 File 参数指定。
RandomAccessFile(String name, String mode)
创建从中读取和向其中写入(可选)的随机访问文件流,该文件具有指定名称。
参数类型:
"r" 以只读方式打开。调用结果对象的任何 write 方法都将导致抛出 IOException。
"rw" 打开以便读取和写入。如果该文件尚不存在,则尝试创建该文件。
"rws" 打开以便读取和写入,对于 "rw",还要求对文件的内容或元数据的每个更新都同步写入到底层存储设备。
"rwd" 打开以便读取和写入,对于 "rw",还要求对文件内容的每个更新都同步写入到底层存储设备。
常用方法:
long getFilePointer()
获取文件当前指针位置
long length()
获取此文件的长度。
void setLength(long newLength)
设置此文件的长度。
void seek(long pos)
设置到此文件开头测量到的文件指针偏移量,在该位置发生下一个读取或写入操作。
int skipBytes(int n)
尝试跳过输入的 n 个字节以丢弃跳过的字节。
void write+(数据类型)
写入指定类型数据
read+(指定类型数据)
获取指定类型数据
注意:获取顺序要写入顺序一致
注意:String类型数据是UTF
//创建RandomAccessFile对象
RandomAccessFile raf=new RandomAccessFile("d:\\javatest\\a.txt","rw");
//获取当前文件指针
System.out.println("当前文件指针位置"+raf.getFilePointer());
//写入文件数据
raf.writeByte(10);
raf.writeShort(20);
raf.writeInt(30);
raf.writeLong(40);
raf.writeChar('a');
raf.writeBoolean(true);
raf.writeUTF("你们好");
System.out.println("当前文件指针位置"+raf.getFilePointer());
//使用seek方法把文件指针移到开始位置
raf.seek(0);
//根据写入顺序读取数据
System.out.println(raf.readByte());
System.out.println(raf.readShort());
System.out.println(raf.readInt());
System.out.println(raf.readLong());
System.out.println(raf.readChar());
System.out.println(raf.readBoolean());
System.out.println(raf.readUTF());
raf.close();
Properties类
-
是一个Map体系的集合类
-
Properties可以保存到流中或从流中加载
-
属性列表中的每个键及其对应的值都是一个字符串
-
构造方法:
-
Properties()
创建一个无默认值的空属性列表。
Properties(Properties defaults)
创建一个带有指定默认值的空属性列表。
-
基本方法:
-
Object setProperty(String key, String value)
设置集合的键和值,都是String类型,底层调用 Hashtable方法 put
-
String getProperty(String key)
使用此属性列表中指定的键搜索属性
-
Set stringPropertyNames()
从该属性列表中返回一个不可修改的键集,其中键及其对应的值是字符串
-
void loadFromXML(InputStream in)
将指定输入流中由 XML 文档所表示的所有属性加载到此属性表中。
-
void load(Reader reader)
从输入字符流读取属性列表(键和元素对)
-
void store(Writer writer, String comments)
将此属性列表(键和元素对)写入此 Properties表中,以适合使用 load(Reader)方法的格式写入输出字符流 ==第二个参数其实就是一个文件的注释,使用utf-8编码格式== ==小总结:由于properties实现了map接口所以map的方法properties集合也能用==
//创建properties对象
Properties pro=new Properties();
try {
//先写入数据到集合中
pro.setProperty("d","4");
pro.setProperty("e","5");
pro.setProperty("f","6");
//调用store方法将集合中的数据存储到指定properties文件
pro.store(new FileOutputStream("D:\\javatest\\b.properties",true),"balabala");
//调用storeToXML方法将集合中的数据存储到xml文件中
pro.storeToXML(new FileOutputStream("D:\\javatest\\c.xml",true),"balabala");
//创建properties对象,参数文件名后缀是.properties;
pro.load(new FileInputStream("D:\\javatest\\b.properties"));
//根据键获取值
String a = pro.getProperty("a");
String b =pro.getProperty("b");
String c =pro.getProperty("c");
System.out.println("a="+a+"b="+b+"c="+c);
} catch (IOException e) {
e.printStackTrace();
}
}
总结
**
-
文件/文件夹属性操作:
File
文件内容操作类及接口
-
接口:
DateInput、DateOutput
-
抽象类:
InputStream、OutputStream、Reader、Writer
实现类:
*文件流:
FileInputStream、FileOutputStream,FileReader、FileWriter
*缓冲流:
BufferedInputStream、BufferedOutputStream、BufferedReader、BufferedWriter
-
基本数据类型输入输出流:
DateInputStream、DateOutputStream、ObjectInputStream、ObjectInputStream、RandomAccessFile
-
转化流:
InputStreamReader、OutputStreamWriter
-
打印输出流:
PrintStream、PrintWriter
-
配置文件读取流:
properties
-
I/o流常用流总结:
2接口4抽象18实现
*/