IO流
File 类的方法
package IOpackage;
import org.junit.jupiter.api.Test;
import java.io.File;
/**
* File 类的使用
* 1 File类的一个对象,代表一个文件或者一个文件目录
* 2 File类声明在java.io包下
*
*/
public class FileTest {
/**
* 1 创建File类的实例
* File(String filePath)
* File(parent,child)
* File(file,"childPath")
* 2
* 相对路径:相较于某一个路径下,指明的路径
* 绝对路径:确定的某一个路径,包含具体的盘 什么的
*/
@Test
public void test1(){
// 构造器一
File fil1 = new File("hello.txt"); // 相对路径: 相对于当前工程的Module
File file2 = new File("Mac:\\user\\..."); // 绝对路径:指的是确定的在哪一个文件夹下的目录
// 构造器二
File file3 = new File("Mac\\user", "files");
// 构造器三
File file4 = new File(file3, "childFile");
}
/*
File 方法的使用
*/
/**
* File类的获取功能
*
* public String getAbsolutePath():获取绝对路径
* public String getPath() :获取路径
* public String getName() :获取名称
* public String getParent():获取上层文件目录路径。若无,返回null
* public long length() :获取文件长度(即:字节数)。不能获取目录的长度。
* public long lastModified() :获取最后一次的修改时间,毫秒值
* public String[] list() :获取指定目录下的所有文件或者文件目录的名称数组
* public File[] listFiles() :获取指定目录下的所有文件或者文件目录的File数组
*
* 适用于文件目录
* public String[] list() :获取指定目录下的所有文件或者文件目录的名称数组
* public File[] listFiles() :获取指定目录下的所有文件或者文件目录的File数组
*
*/
@Test
public void test2(){
File file1 = new File("hello.txt");
System.out.println(file1.getAbsoluteFile());
System.out.println(file1.getPath());
System.out.println(file1.getName());
System.out.println(file1.getParent());
System.out.println(file1.length());
System.out.println(file1.lastModified()); // 返回的是个毫秒的值
File file2 = new File("/Users/jakob/IDEA_Java程序/JavaSenior");
// public String[] list()
String[] list = file2.list();
for(String s: list){
System.out.println(s);
}
System.out.println("*************");
File[] files = file2.listFiles();
for(File f: files){
System.out.println(f);
}
}
}
FileRead 和 FileWriter 的使用:
package IOpackage;
import org.junit.jupiter.api.Test;
import java.io.*;
public class FileReaderWriterTest {
@Test
public void test1() throws IOException {
// 1 实例化File类的对象,指明要操作的文件
File file = new File("hello.txt"); // 这个相当于当前的Module
// 2 提供哦那个具体的流
FileReader reader = new FileReader(file);
// 3 读取数据
// read(): 返回读入的一个字符。如果达到文件末尾,返回-1
// 每次读取一个
int data = reader.read();
while (data != -1){
System.out.print((char)data);
data = reader.read();
}
// 4 流的关闭操作
reader.close();
}
// 对于文件的读取 首先要确保文件中 要存在该文件 不然保存
@Test
public void test2(){
FileReader fileReader = null;
try {
// 1 File 的实例化
File file = new File("hello.txt");
// 2 流的实例化
fileReader = new FileReader(file);
char[] cfr = new char[5];
int len;
// read(char[] cbuf) : 返回每次读入cbuf数组的字符个数,如果达到末尾 则输出-1
while((len = fileReader.read(cfr)) != -1){
// 因为每次读取的是5个char型数组,要考虑最后一次读取
// len 在最后一次就是表明的是最后一次读了多少个数据
// 正确的写法一
// for (int i = 0; i <len ; i++) {
// System.out.print(cfr[i]);
// }
// 写法二
String str = new String(cfr,0,len);
System.out.print(str);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (fileReader == null)
fileReader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
/**
* 从内存中写出数据到硬盘
* 说明:
* 1 数据写出的时候如果文件不存在 能自动创造 该文件
* 2 如果存在,则是对原有文件的覆盖
* 这里涉及到file构造器
* 如果流使用的构造器是:FileWriter(file,false(这里定义为false)) 或者 FileWriter(file)
* 则是覆盖原有的文件
* 如果流使用的构造器是:FileWriter(file,true) 则指的是不对原有文件进行覆盖,而是继续 添加内容
*
*
*/
@Test
public void testFileWriter() throws IOException {
// 1 提供File类的对象,指明写出到的文件
File file = new File("hello1.txt");
// 2 提供FileWriter的对象,用于数据的写出
FileWriter fileWriter = new FileWriter(file,true);
// 3 写出的操作
fileWriter.write("I have a dream!");
fileWriter.write("something for test");
fileWriter.close();
}
// 文件的复制操作
@Test
public void testCopyFile(){
FileReader fr = null;
FileWriter fw = null;
try {
File file1 = new File("hello.txt");
File file2 = new File("helloCopy.txt");
fr = new FileReader(file1);
fw = new FileWriter(file2);
char[] ch =new char[5];
int len;
while((len = fr.read(ch)) != -1){
fw.write(ch,0,len);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if(fr != null){
try {
fr.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (fw != null) {
try {
fw.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
缓冲流的使用
package IOpackage;
import org.junit.jupiter.api.Test;
import java.io.*;
/**
* 处理流一: 缓冲流的使用
*
* 1 缓冲流:
* BufferedInputStream
* BufferedOutputStream
* BufferedReader
* BufferedWriter
* 2 作用:提供流的读取、写入的速度
* 提高读写速度的原因: 内部提供了一个缓冲区
* 不带缓冲的流的工作原理:它读取到一个字节/字符,就向用户指定的路径写出去 读一个写一个 所以就慢了
* 带缓冲的流的工作原理:读取到一个字节/字符,先不输出,等凑足了缓冲的最大容量后一次性写出去,从而提高了工作效率
*
* 3 处理流 嵌套在 已有流的上面
*/
public class BufferedTest {
// 实现非文本文件的复制
// 缓冲流实现是处理流,缓冲流是作用在节点流上面的
@Test
public void test1() throws IOException {
FileInputStream fis = null;
FileOutputStream fos = null;
BufferedInputStream bis = null;
BufferedOutputStream bos = null;
try {
// 1 造文件
File file = new File("证件照.jpg");
File fileCopy = new File("证件照copy.jpg");
// 2 造流
// 2.1 造节点流
fis = new FileInputStream(file);
fos = new FileOutputStream(fileCopy);
// 2.2 造缓冲流
bis = new BufferedInputStream(fis);
bos = new BufferedOutputStream(fos);
// 3 复制的 写入 写出
byte[] buffer = new byte[10];
int len;
while ((len = bis.read(buffer)) !=-1){
bos.write(buffer,0,len);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
// 4 资源关闭: 先关闭外面的 后关里面的
bos.close();
bis.close();
// 说明: 关闭外层流的同时,内层会自动关闭
fos.close();
fis.close();
}
}
}
对象流 以及 对象序列化机制的知识点
对象的序列化机制 包含 对象的序列化 和 反序列化 这两个点:
对象序列化:允许把内存中的Java对象转换成平台无关的二进制流,从 而允许把这种二进制流持久地保存在磁盘上,或通过网络将这种二进制流传 输到另一个网络节点。
反序列化:当其它程序获取了这种二进制流,就可以恢复成原 来的Java对象
package IOpackage;
import org.junit.jupiter.api.Test;
import java.io.*;
public class SerializableTest {
// 序列化
@Test
public void test1() throws IOException {
// 序列化
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("data.dat"));
String str = "this is a Serializable test file";
oos.writeObject(str);
oos.flush();
}
// 反序列化
@Test
public void test2() throws IOException, ClassNotFoundException {
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("data.dat"));
Object ois1 = ois.readObject();
String str = (String)ois1;
System.out.println(str);
}
// 序列化 对象的方法
/**
* 序列化对象的过程及条件
* 1 需要该类实现接口 :serializable
* 2 当前类提供一个全局常量: serializableUID;就是一个序列号或者说是标识符,一个不一样的数字而已
* 3 出了当前person类需要实现Serializable接口之外,还必须保证其内部所以属性也必须是可序列化的
* (基本数据类型 默认的是可序列化的)
* 比如说 person 里面有个account的属性,也需要保证该属性也是课序列化的 就是说 该类 也需要实现序列化接口
*/
@Test
public void test3() throws IOException {
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("person.dat"));
oos.writeObject(new Person("Jerry",12));
oos.flush();
oos.close();
}
@Test
public void test4() throws IOException, ClassNotFoundException {
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("person.dat"));
Object person = ois.readObject();
ois.close();
System.out.println(person.toString());
}
}
class Person implements Serializable{
public static final long serialVersionUID = 3123423432432434L;
private String name;
private int age;
public Person() {
}
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}