1 /* 2 * Copyright (C) 2009 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.internal.util; 18 19 import java.io.File; 20 import java.io.IOException; 21 22 /** 23 * @Deprecated Use {@link com.android.internal.os.AtomicFile} instead. It would 24 * be nice to update all existing uses of this to switch to AtomicFile, but since 25 * their on-file semantics are slightly different that would run the risk of losing 26 * data if at the point of the platform upgrade to the new code it would need to 27 * roll back to the backup file. This can be solved... but is it worth it and 28 * all of the testing needed to make sure it is correct? 29 */ 30 @Deprecated 31 public class JournaledFile { 32 File mReal; 33 File mTemp; 34 boolean mWriting; 35 36 public JournaledFile(File real, File temp) { 37 mReal = real; 38 mTemp = temp; 39 } 40 41 /** Returns the file for you to read. 42 * @more 43 * Prefers the real file. If it doesn't exist, uses the temp one, and then copies 44 * it to the real one. If there is both a real file and a temp one, assumes that the 45 * temp one isn't fully written and deletes it. 46 */ 47 public File chooseForRead() { 48 File result; 49 if (mReal.exists()) { 50 result = mReal; 51 if (mTemp.exists()) { 52 mTemp.delete(); 53 } 54 } else if (mTemp.exists()) { 55 result = mTemp; 56 mTemp.renameTo(mReal); 57 } else { 58 return mReal; 59 } 60 return result; 61 } 62 63 /** 64 * Returns a file for you to write. 65 * @more 66 * If a write is already happening, throws. In other words, you must provide your 67 * own locking. 68 * <p> 69 * Call {@link #commit} to commit the changes, or {@link #rollback} to forget the changes. 70 */ 71 public File chooseForWrite() { 72 if (mWriting) { 73 throw new IllegalStateException("uncommitted write already in progress"); 74 } 75 if (!mReal.exists()) { 76 // If the real one doesn't exist, it's either because this is the first time 77 // or because something went wrong while copying them. In this case, we can't 78 // trust anything that's in temp. In order to have the chooseForRead code not 79 // use the temporary one until it's fully written, create an empty file 80 // for real, which will we'll shortly delete. 81 try { 82 mReal.createNewFile(); 83 } catch (IOException e) { 84 // Ignore 85 } 86 } 87 88 if (mTemp.exists()) { 89 mTemp.delete(); 90 } 91 mWriting = true; 92 return mTemp; 93 } 94 95 /** 96 * Commit changes. 97 */ 98 public void commit() { 99 if (!mWriting) { 100 throw new IllegalStateException("no file to commit"); 101 } 102 mWriting = false; 103 mTemp.renameTo(mReal); 104 } 105 106 /** 107 * Roll back changes. 108 */ 109 public void rollback() { 110 if (!mWriting) { 111 throw new IllegalStateException("no file to roll back"); 112 } 113 mWriting = false; 114 mTemp.delete(); 115 } 116 } 117