21-CS61B-lab6:java文件操作以及持久化一见
文件操作
这里的文件操作主要通过File类,Serializable的派生类等实现
拥有路径path(相对路径/绝对路径),创建File对象
File newFile = new File(path);
获得当前工作目录File
File CWD = new File(System.getProperty("user.dir"));
通过System.getProperty("user.dir")得到的是CWD的绝对路径
注:工作目录为运行Main.class的目录,并非储存Main.class的目录
例如Main.class放在Main目录,我在lab6使用命令行java Main.Main,那么CWD得到的是lab6
获得File对象的路径的String形式
String path = CWD.getPath();
拥有路径中的多个目录名,想转换为File对象
File newFile = Paths.get(CWD.getPath(), dir1, dir2, dir3).toFile();
检查File对象所指向的文件/目录是否已创建
newFile.exists();
检查File对象所指向的是否为文件
newFile.isFile();
检查File对象指向的是否为目录
newFile.isDirectory();
将File指向的文件创建
try {newFile.createNewFile();
} catch (IOException e) {throw new RuntimeException(e);
}
将File指向的目录创建
newFile.mkdir();
将byte[]类写入文件
/*** @param newFile 要写入的文件* @param contents 要写入的内容对象,这里默认implements byte[]*/
static void writeContents(File newFile, Object... contents) {BufferedOutputStream str = new BufferedOutputStream(Files.newOutputStream(newFile.toPath()));for (Object obj : contents) {str.write((byte[]) obj);{str.close();
}
将String类转换为byte[]类
((String) obj).getBytes(StandardCharsets.UTF_8)
读取二进制文件
byte[] byteResult = Files.readAllBytes(newFile.toPath());
将byte[]类转换为String类
String StringResult = new String(byteResult, StandardCharsets.UTF_8);
对象的序列化
序列化对象指的是将对象转换成byte[]数组保存其信息
obj一定要implements Serializable
static byte[] serialize(Serializable obj) {ByteArrayOutputStream stream = new ByteArrayOutputStream(); ObjectOutputStream objectStream = new ObjectOutputStream(stream);objectStream.writeObject(obj); //写入,被stream接收objectStream.close(); //关闭Object流return stream.toByteArray(); //转换为byte[]
}
将对象写入文件
即序列化后写入文件
writeContents(newFile, serialize(obj));
从序列化文件中读取对象
/***@Param file 待读的文件*@Param expectedClass 期望返回的对象类型*/
static <T extends Serializable> T readObject(File file, Class<T> expectedClass) {ObjectInputStream in =new ObjectInputStream(new FileInputStream(file)); //使用in读取ObjectT result = expectedClass.cast(in.readObject()); //cast到期望的类上in.close();return result;
}
持久化
持久化的目的是使我们的程序有记忆,在下次运行的时候,能够继承上次运行的状态继续运行
实现的方式很简单,即将我们需要保存的对象状态作为文件记录在磁盘当中,下次运行时读取该文件恢复对象状态。
CapersRepository.java的若干方法实现
void CapersRepository.setupPersistence();
public static void setupPersistence() {if (!CAPERS_FOLDER.exists()) {CAPERS_FOLDER.mkdir();}File STORY = join(CAPERS_FOLDER, "story");if (!STORY.exists()) {try {STORY.createNewFile();} catch (IOException e) {throw new RuntimeException(e);}}File DOGS = join(CAPERS_FOLDER, "dogs");if (!DOGS.exists()) {DOGS.mkdir();}
}
void CapersRepository.writeStory(String);
public static void writeStory(String text) {File STORY = join(CAPERS_FOLDER, "story");String writeString = readContentsAsString(STORY);if (writeString.isEmpty()) {writeString = text;} else {writeString = writeString + "\n" + text;}writeContents(STORY, writeString);System.out.println(writeString);
}
void CapersRepository.makeDog(String, String, int);
public static void makeDog(String name, String breed, int age) {Dog dogObj = new Dog(name, breed, age);dogObj.saveDog();System.out.println(dogObj);
}
void CapersRepository.celebrateBirthday(String);
public static void celebrateBirthday(String name) {Dog dogObj = Dog.fromFile(name);if (dogObj != null) {dogObj.haveBirthday();dogObj.saveDog();}
}
Dog.java的若干方法实现
Dog Dog.FromFile(String);
public static Dog fromFile(String name) {File dogObj = join(DOG_FOLDER, name);if (!dogObj.exists()) {return null;}return readObject(dogObj, Dog.class);
}
void saveDog();
public void saveDog() {File dog = join(DOG_FOLDER, name);if (!dog.exists()) {try {dog.createNewFile();} catch (IOException e) {throw new RuntimeException(e);}}writeObject(dog, this);
}