文章目录
1.File类的使用
1.1 File类的实例化
1.java.io.File类:File类的一个对象,代表一个文件或一个文件目录(俗称:文件夹)
2.构造:
public File(String pathname),以pathname为路径,可以是 相对路径(相时路径即为当前的Project下。)或者是绝对路径(包含盘符:D:\\workspace\\…\\hello.text)
public class Main{
public static void main(String[] args){
File file1 = new File("hello.text"); // 文件(相对路径)
File file2 = new File("D:\\workspace\\hello.text"); // 文件(绝对路径)
File file3 = new File("D:\\wordspace","test_File"); // 文件夹
File file4 = new File(file3,"hi.text"); // 文件夹file3下面的一个文件
System.out.println(file1);
System.out.println(file2); // 内存中的对象,toString()方法输出文件路径
Ststem.out.println(file3);
System.out.println(file4);
/* hello.text
D:\workspace\hello.text
D:\wordspace\test_File
D:\wordspace\test_File\hi.text */
}
}
// 构造器
public File(String pathname) {
if (pathname == null) {
throw new NullPointerException();
}
this.path = fs.normalize(pathname);
this.prefixLength = fs.prefixLength(this.path);
}
// toString()方法
public String toString() {
return getPath();
}
1.2 File类的常用方法
File类中涉及到关于文件或文件目录的创建、删除、重命名、修改时间、文件大小等方法。
并未涉及到写入或读取文件内容的操作。如果需要读取或写入文件内容,必须使用IO流来完成。
FIle类的对象常会作为参数传递到流的构造器中,指明读取或写入的“终点”
a.File类的获取方法:
public String getAbsolutePath(): 获取绝对路径
public String getPath(): 获取路径
public String getName():获取名称
public String getParent(): 获取上层文件目录路径。若无,返回null
public long length(): 获取文件长度(即:字节数)。不能获取目录的长度。
public long lastModified(): 获取最后一次的修改时间,毫秒值
public String[] Iist():获取指定目录下的所有文件或者文件目录的名称数组
public File[] listFiles():获取指定目录下的所有文件或者文件目录的File数组
b.File类的重命名方法:
public boolean renameTo(File dest): 把文件重命名为指定的文件路径
c.File类的判断功能:
public boolean isDirectory(): 判断是否是文件目录
public boolean isFile(): 判断是否是文件
public boolean exists(): 判断是否存在
public boolean canRead(): 判断是否可读
public boolean canWrite(): 判断是否可写
public boolean isHidden(): 判断是否隐藏
d.File类的创建方法:
public boolean createNewFile(): 创建文件。若文件存在,则不创建,返回false
public boolean mkdir():创建文件目录。如果此文件目录存在,就不创建。如果此文件目录的上层目录不存在,也不创建。
public boolean mkdirs(): 创建文件目录。如果上层文件目录不存在,一并创建
(若没有写盘符路径,则默认在该项目路径下)
e.File类的删除方法:
public boolean delete(): 删除文件或者文件夹
2.IO流原理及流的分类
概述:
I/O是Input/Output的缩写,I/O技术是非常实用的技术,用于 处理设备之间的数据传输。如读/写文件,网络通讯等
Java程序中,对于数据的输入/输出操作以 “流(seam)” 的方式进行
java.io包下提供了各种“流”类和接口,用以获取不同种类的数据,并通过 标准的方法 输入或输出数据
站在 / 程度内存的角度上看:
● 输入input: 读取外部数据(磁盘、光盘等存储设备的数据)到程序(内存)中。
● 输出output: 将程序(内存)数据输出到磁盘、光盘等存储设备中。
流的分类:
● 按操作数据单位不同分为:字节流(8bt),字符流(16bit)
● 按数据流的流向不同分为:输入流,输出流
● 按流的角色的不同分为:节点流,处理流
流的体系结构:
抽象基类: InputStream、OutputStream、Reader、Writer
字节流: InputStream、OutputStream
字符流: Reader、Wrider
输入流: InputStream、Reader
输出流: OutputStream、Writer
节点流(文件流): FileInputStream、FileOutputStream、FileReader、FileWriter
缓冲流(处理流的一种): BufferedInputStream、BufferedOutputStream、BuffereadReader、BuffereadWriter
3.节点流(或文件流)
FileInputstream、FileOutputstream、FileReader、FileWriter
文件流中的字节流和字符流的使用:
对于文本文件(.text,.java,.c,.cpp),使用字符流处理
对于非文本文件(.jpg,.mp3,.mp4,.avi,.doc,.ppt,…),使用字节流处理
使用字节流处理文本文件可能会出现乱码
3.1 read()读入数据方法
1.read: 返回读入的一个字符,达到末尾返回-1
2.数据读入的文件一定要存在,否则就会报FiLeNotFoundException异常
public class Main{
public static void main(String[] args) {
// 1.实例化File对象,指明要操作的对象
File file1 = new File("tc.text");
FileReader f = null;
try {
System.out.println(file1.createNewFile());
// 2.提供具体的流
f = new FileReader(file1);
// 3.数据的读入
// 方式一
// int read = f.read();
// while(read != -1){
// System.out.print((char)read);
// read = f.read();
// }
// 方式二
int date;
while((date = f.read()) != -1){
System.out.print((char)date);
}
} catch (IOException e) {
throw new RuntimeException(e);
}finally {
// 4.流的关闭
try {
if(f != null){
f.close();
}
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
}
对read()的方法升级,使用read的重载方法: read(char[] arr)
public class Main{
public static void main(String[] args) {
// 1.File实例化
File file = new File("tc.text");
// 2.流的实例化
FileReader f = null;
try {
f = new FileReader(file);
// 3.读入的操作
// read(char[] arr): 返回每次读入数组中字符的个数,达到末尾返回-1
char[] arr = new char[5];
int len;
while((len = f.read(arr)) != -1){ // 每次读入数组数据,将原有的数据替换掉
for(int i=0;i<len;i++){ // 按照读入的字符个数来遍历输出
System.out.print(arr[i]);
}
}
} catch (IOException e) {
throw new RuntimeException(e);
}finally {
// 4.流的关闭
try {
f.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
}
3.2 writer()写出数据方法
1.将指定参数中的数据写出到指定文件中
2.若文件不存在,在写出中自动创建此文件;若文件存在,默认不追加数据,即删除原有数据,再读入新的的数据(FileWriter f = new FileWriter(file,false))
public class Main{
public static void main(String[] args) throws IOException {
// 1.File的实例化
File file = new File("tc01.text");
// 2.流的实例化
FileWriter f = new FileWriter(file,false); // 默认,FileWriter f = new FileWriter(file);
// 3.写出的操作
String str = "abc123\n";
f.write(str);
f.write("uio");
// 4.关闭资源
f.close();
}
}
3.3 使用read()和write()实现文件的复制
public class Main {
public static void main(String[] args) {
// 1.创建读入的File对象和写出的File对象
File file1 = new File("tc.text");
File file2 = new File("tc02.text");
// 2.创建输入流和输出流的对象
FileReader f1 = null;
FileWriter f2 = null;
try {
f1 = new FileReader(file1);
f2 = new FileWriter(file2);
// 3.操作
char[] arr = new char[5];
int len;
while((len = f1.read(arr)) != -1){
// 每次读出len个,并写出到file2中
f2.write(arr,0,len);
}
} catch (IOException e) {
throw new RuntimeException(e);
}
// 4.关闭资源
try {
f1.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
try {
f2.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
3.4 图片的复制
使用字节流来完成复制图片, 字符流不能处理图片
public class Main{
public static void main(String[] args) {
// 1.创建读入的File对象和写出的File对象
File file1 = new File("01.jpg");
File file2 = new File("02.jpg");
// 2.创建输入流和输出流的对象
FileInputStream f1 = null;
FileOutputStream f2 = null;
try {
f1 = new FileInputStream(file1);
f2 = new FileOutputStream(file2);
// 3.操作
byte[] arr = new byte[5];
int len;
while((len = f1.read(arr)) != -1){
// 每次读出len个,并写出到file2中
f2.write(arr,0,len);
}
} catch (IOException e) {
throw new RuntimeException(e);
}
// 4.关闭资源
try {
f1.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
try {
f2.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
4.缓冲流
1.缓冲流,处理流的一种:BufferedInputStream、BufferedOutputStream、BufferReader、BufferWriter
2.作用:提供流的读取、写入的速度。
(使用缓冲流关闭是资源时先关闭外层的流,但在关闭外层时会自动关闭内层流,所以只需要关闭内层的流即可,内层的流关闭操作不用写)
复制图片:
public class test_09 {
public static void main(String[] args) {
// 1.File对象
File file1 = new File("01.jpg");
File file2 = new File("02.jpg");
// 2.流
// 文件流、处理流
FileInputStream f1 = null;
FileOutputStream f2 = null;
BufferedInputStream b1 = null;
BufferedOutputStream b2 = null;
try {
f1 = new FileInputStream(file1);
f2 = new FileOutputStream(file2);
// 缓冲流
b1 = new BufferedInputStream(f1);
b2 = new BufferedOutputStream(f2);
// 3.操作
byte[] arr = new byte[10];
int len;
while((len = b1.read(arr)) != -1){
b2.write(arr,0,len);
}
} catch (IOException e) {
throw new RuntimeException(e);
} finally {
try {
if(b1 != null){
b1.close();
}
} catch (IOException e) {
throw new RuntimeException(e);
}
try {
if(b2 != null){
b2.close();
}
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
}
复制文本:
public class Main{
public static void main(String[] args){
copyFile1("tc.text","tc1.text");
}
public static void copyFile1(String srcPath,String destPath){
BufferedReader b1 = null;
BufferedWriter b2 = null;
try {
b1 = new BufferedReader(new FileReader(new File(srcPath)));
b2 = new BufferedWriter(new FileWriter(new File(destPath)));
String date;
while((date = b1.readLine()) != null){
b2.write(date + "\n"); // date中不包括换行符
// 或者 b2.newLine();
}
} catch (IOException e) {
throw new RuntimeException(e);
} finally {
try {
if(b1 != null){
b1.close();
}
} catch (IOException e) {
throw new RuntimeException(e);
}
try {
if(b2 != null){
b2.close();
}
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
}
5.转换流
转换流,字符流子类,转换流本质是字符流,只能操作纯文本文件,他可以对字符流的编码集进行指定转换。
1.转换流是处理流的一种: InputStreamReader、OutputStreamWriter(属于字符流)
2.作用:转换流提供了在字节流与字符流之间的转换
InputStreamReader: 将一个字节的输入流转换为字符的输入流
OutputStreamWriter: 将一个字符的输出流转换为字节的输出流
3.解码: 字节、字节数组 -->字符、字符数组
编码:字符、字符数组 -->字节、字节数组
输入:
public class Main{
public static void main(String[] args){
InputStreamReader isr = null; // 参数为文件保存时的字符集
try {
FileInputStream f = new FileInputStream("tc.text");
isr = new InputStreamReader(f,"UTF-8");
char[] arr = new char[20];
int len;
while((len = isr.read(arr)) != -1){
String str = new String(arr,0,len);
System.out.println(str);
}
} catch (IOException e) {
throw new RuntimeException(e);
} finally {
if(isr != null){
try {
isr.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
}
}
输出:
public class Main{
public static void main(String[] args){
InputStreamReader in1 = null;
OutputStreamWriter ou1 = null;
try {
FileInputStream f1 = new FileInputStream("tc.text");
FileOutputStream f2 = new FileOutputStream("tc01.text");
// 1.InputStreamReader[字节-->字符,解码]:
// 使用字节输入流读取字节, 根据转换流的编码集进行解码成字符,再使用输入转换流把解码后的字符读到内存中
// 2.OutputStreamWriter[字符-->字节,编码]:
// 使用输出转换流读取字符,根据转换流的编码集进行编码成字符,再使用字节输出流把编码后的字节写出到文件中
in1 = new InputStreamReader(f1,"utf-8");
ou1 = new OutputStreamWriter(f2, "gbk");
char[] arr = new char[20];
int len;
while((len = in1.read(arr)) != -1){
ou1.write(arr,0,len);
}
} catch (IOException e) {
throw new RuntimeException(e);
} finally {
try {
if(in1 != null){
in1.close();
}
} catch (IOException e) {
throw new RuntimeException(e);
}
try {
if(ou1 != null){
ou1.close();
}
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
}
6.对象流
处理流的一种:ObjectInputstream、OjbectOutputSteam
用于存储和读取 基本数据类型数据 或 对象 的处理流。它的强大之处就是可以把Java中的对象写入到数据源中,也能把对象从数据源中还原回来。
序列化:用ObjectOutputStream类保存基木类型数据或对象的机制
反序列化:用ObjectInputStream类读取基木类型数据或对象的机制
ObjectOutputStream和lObjectlnputStream不能序列化 static 和 transient 修饰的成员变量
对象序列化机制允许把内存中的Java对象转换成平台无关的二进制流,从而允许把这种二进制流持久地保存在磁盘上,或通过网络将这种二进制流传输到另一个网络节点。当其它程序获取了这种二进制流,就可以恢复成原来的Java对象
序列化的好处在于可将任何实现了 Serializable接口的对象转化为字节数据,使其在保存和传输时可被还原
序列化是RMl(Remote Method Invoke-远程方法调用)过程的参数和返回值都必须实现的机制,而RMl是JavaEE的基础。因此序列化机制是 JavaEE平台的基础
如果需要让某个对象支持序列化机制,则必须让对象所属的类及其属性是可序列化的,为了让某个类是可序列化的,该类必须实现如下两个接口之一。否则,会抛出NotSerializableException.异常
Serializable
Externalizable
6.1 对象序列化(ObjectOutputStream)
将java中的对象保存到磁盘中或通过网络传输出去
public class Main{
public static void main(String[] args){
ObjectOutputStream oos = null;
try {
oos = new ObjectOutputStream(new FileOutputStream("Object.dat"));
oos.writeObject(new String("我爱北京天字门!"));
oos.flush(); // 清空缓冲区
} catch (IOException e) {
throw new RuntimeException(e);
} finally {
try {
if(oos != null){
oos.close();
}
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
}
6.2 对象反序列化(ObjectInputStream)
还原为内存中的对象
public class Main{
public static void main(String[] args) {
ObjectInputStream ois = null;
String str = null;
try {
ois = new ObjectInputStream(new FileInputStream("Object.dat"));
str = (String)ois.readObject();
} catch (IOException e) {
throw new RuntimeException(e);
} catch (ClassNotFoundException e) {
throw new RuntimeException(e);
} finally {
try {
if(ois != null){
ois.close();
}
} catch (IOException e) {
throw new RuntimeException(e);
}
}
System.out.println(str);
}
}
6.3 自定义类的序列化与反序列化
使用序列化机制的前提
1.实现Serializable接口(标识用的接口)
2.提供一个全局常量serialVersionUID,会默认提供,但一般显示提供(识别类的版本)
3.除了当前自定义类需要实现Serializable接口,还必须保证其内部所有属性也必须是可序列化的。(默认情况下,基本数据类型可序列化)
凡是实现Serializable接口的类都有一个表示序列化版木标识符的静态变量:
private static final long serialVersionUlD;
serialVersionUlD用来表明类的不同版本间的兼容链简言之,其目的是以序列化对象进行版本控制,有关各版本反序列化时是否兼容。
如果类没有显示定义这个静态变量,它的值是Java运行时环境根据类的内部细节自动生的。若类的实例变量做了修改,serialVersionUlD可能发生变化。故建议,显式声明。
简单来说,Java的序列化机制是通过在运行时判断类的serialVersionUID来验证版木一致性的。在进行反序列化时,JM会把传来的字节流中的serialVersionUlD与木地相应实体类的serialVersionUID进行比较,如果相同就认为是一致的,可以进行反序列化,否则就会出现序列化版木不一致的异常。(InvalidCastException)
public class Main {
public static void main(String[] args) {
// 序列化
ObjectOutputStream oos = null;
try {
oos = new ObjectOutputStream(new FileOutputStream("Object.dat"));
oos.writeObject(new person("张三",19));
oos.flush(); // 清空缓冲区
} catch (IOException e) {
throw new RuntimeException(e);
} finally {
try {
if(oos != null){
oos.close();
}
} catch (IOException e) {
throw new RuntimeException(e);
}
}
// 反序列化
ObjectInputStream ois = null;
person p = null;
try {
ois = new ObjectInputStream(new FileInputStream("Object.dat"));
p = (person)ois.readObject();
} catch (IOException e) {
throw new RuntimeException(e);
} catch (ClassNotFoundException e) {
throw new RuntimeException(e);
} finally {
try {
if(ois != null){
ois.close();
}
} catch (IOException e) {
throw new RuntimeException(e);
}
}
System.out.println(p);
}
}
class person implements Serializable {
private static final long serialVersionUID = 8493754667710L;
private String name;
private int age;
public person(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "person{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}