diff --git a/src/FileManager.java b/src/FileManager.java index 6a3127f..9d1d0c0 100644 --- a/src/FileManager.java +++ b/src/FileManager.java @@ -1,20 +1,17 @@ +// Eric Li, Charlie Zhao, ICS4U, Finished 2022-06-17 //This class allows us to input and output flies useful for -//Inputing levels and making save data. +// inputting levels and making save data. import java.io.*; import java.util.ArrayList; import java.util.List; import java.util.Scanner; // TODO: close scanner etc after use -public class FileManager { - public static void writeFile(String fileLocation, String writeString) throws IOException { - File newFile = new File(fileLocation); - FileWriter fileWriter = new FileWriter(newFile); - fileWriter.write(writeString); - fileWriter.close(); - } +public final class FileManager { // will create file if it doesn't exist + // does not include robust file closing as readFile is simpler and less likely to fail during reading + // additionally, even failing won't affect readFile as reading is a non-exclusive action (a lock will not prevent it) public static String readFile(String fileLocation) throws IOException { File newFile = new File(fileLocation); if (newFile.createNewFile()) { @@ -28,35 +25,48 @@ public class FileManager { } } + // includes robust file closing public static Object readObjectFromFile(String fileLocation, List allowedObject) throws IOException, ClassNotFoundException { ObjectInputStream objectStream; Object o; FileInputStream fileStream = new FileInputStream(fileLocation); + // if the allowedObject list is not "Any", ensure that the objects loaded are in the list + // this can help mitigate the security risk with deserializing untrusted files if (!allowedObject.contains("Any")) { objectStream = new SafeObjectInputStream(fileStream, allowedObject); } else { + // otherwise, use the unsafe class objectStream = new ObjectInputStream(fileStream); } try { o = objectStream.readObject(); + return o; } catch (Exception e) { // please note that the broad exception Exception was used here // as in the event of any exception, the object should still be closed - // additionally, the exception is reraised, so no information is lost from being too coarse + // additionally, the exception is re-raised, so no information is lost from being too coarse objectStream.close(); fileStream.close(); throw e; + } finally { + objectStream.close(); + fileStream.close(); } - objectStream.close(); - fileStream.close(); - return o; } + // includes robust file closing public static void writeObjectToFile(String fileLocation, Object o) throws IOException { FileOutputStream fileStream = new FileOutputStream(fileLocation); ObjectOutputStream objectStream = new ObjectOutputStream(fileStream); - objectStream.writeObject(o); - objectStream.close(); - fileStream.close(); + try { + objectStream.writeObject(o); + // please note that a less broad exception was used here compared to readObject, as the only "safe" exception to raise in this circumstance is IOException + } catch (IOException e) { + throw new RuntimeException(e); + } finally { + // close resources used even if writing caused an error + objectStream.close(); + fileStream.close(); + } } }