在一些对数据实时性要求比较高的场合,如随时可能断电的场合下,同时需要将数据写入文件中,我们不能让数据在内存中呆太久,最好能够做到同步,这是我们的需求。
1 package com.android.utils;
2
3 import java.io.File;
4 import java.io.IOException;
5 import java.io.RandomAccessFile;
6 import java.util.Arrays;
7
8 import android.app.Activity;
9 import android.util.Log;
10
11
12 /**
13 * 在一些对数据实时性要求比较高的场合,如随时可能断电的场合下,同时需要将数据写入文件中,
14 * 这个时候,我们不希望数据在内存中呆太久,最好能够做到同步,这是我们的需求。<br>
15 * 第一种方案:<br>
16 * 1. RandomAccessFile<br>
17 * 2. public RandomAccessFile(File file, String mode) throws FileNotFoundException<br>
18 * Constructs a new RandomAccessFile based on file and opens it according to the access string in mode. <br>
19 * 3. mode may have one of following values: <br>
20 * 1. "r" The file is opened in read-only mode. An IOException is thrown if any of the write methods is called. <br>
21 * 2. "rw" The file is opened for reading and writing. If the file does not exist, it will be created. <br>
22 * 3. "rws" The file is opened for reading and writing. Every change of the file's content or metadata must be written synchronously to the target device. <br>
23 * 4. "rwd" The file is opened for reading and writing. Every change of the file's content must be written synchronously to the target device. <br>
24 * 4. 由于我们需要其中的数据同步功能,所以我们选择使用包装RandomAccessFile类,实现要求。<br>
25 * 第二种方案:<br>
26 * 1. FileDescriptor中有sync()方法<br>
27 Ensures that data which is buffered within the underlying implementation is written out to the appropriate device before returning.<br>
28 * 2. FileOutputStream中的 getFD()方法<br>
29 Returns a FileDescriptor which represents the lowest level representation of an operating system stream resource. <br>
30 * 3. 使用起来感觉没有RandomAccessFile方便,放弃时使用<br>
31 */
32
33 public class ZengjfRandomAccessFile {
34 /**
35 * 将整形数组写入文件
36 *
37 * @param filePath 文件路径
38 * @param data 整形数组
39 * @throws IOException
40 */
41 static public void writeIntArray(String filePath, int[] data) throws IOException {
42 if (null == filePath || null == data)
43 return ;
44
45 if (filePath.trim().equals(""))
46 return ;
47
48 File file = new File(filePath);
49 if (!file.exists())
50 file.createNewFile();
51
52 if (!file.canWrite())
53 throw new RuntimeException("Zengjf Utils writeIntArray(): no permission for file -- " + filePath + ".");
54
55 // write data
56 RandomAccessFile raf = new RandomAccessFile(file, "rws");
57 for (int i = 0; i < data.length; i++)
58 raf.writeInt(data[i]);
59
60 raf.close();
61 }
62
63 /**
64 * 将整形数组写入文件,文件目录被指定,作为使用者可以不用关心
65 *
66 * @param activity 调用这个函数的Activity
67 * @param data 要保存的的整形数组
68 * @throws IOException
69 */
70 static public void writeIntArray(Activity activity, int[] data) throws IOException {
71 if (null == activity || null == data)
72 return ;
73
74 String filePath = activity.getApplicationContext().getFilesDir().getAbsoluteFile() + "/zengjfData.txt";
75 writeIntArray(filePath, data);
76 }
77
78 /**
79 * 从文件中读出长度为length的整形数组
80 *
81 * @param filePath 文件路径
82 * @param length 数组长度
83 * @return 返回数组,如果出错,返回null
84 * @throws IOException
85 */
86 static public int[] readIntArray(String filePath, int length) throws IOException {
87
88 if (null == filePath || length <= 0)
89 return null;
90
91 if (filePath.trim().equals(""))
92 return null;
93
94 File file = new File(filePath);
95 if (!file.canRead())
96 throw new RuntimeException("Zengjf Utils writeIntArray(): no permission for file -- " + filePath + ".");
97
98 int[] data = new int[length]; // for return data
99
100 // if file not exist in first time and file length less than data size,
101 // just create file and make data for it
102 if (!file.exists() || (file.length() < (4 * length))) {
103 for (int i = 0; i < data.length; i++)
104 data[i] = 0;
105
106 writeIntArray(filePath, data);
107 return data;
108 }
109
110 //get data
111 RandomAccessFile raf = new RandomAccessFile(file, "r");
112 for (int i = 0; i < length; i++)
113 data[i] = raf.readInt();
114
115 raf.close();
116
117 return data;
118 }
119
120 /**
121 * 从文件中读取整形数组,文件位置、名已经被指定,作为使用者可以不关心
122 *
123 * @param activity 调用这个函数的Activity
124 * @param length 数组的长度
125 * @return 返回数组,如果出错,返回null
126 * @throws IOException
127 */
128 static public int[] readIntArray(Activity activity, int length) throws IOException {
129 if (null == activity || 0 == length)
130 return null;
131
132 String filePath = activity.getApplicationContext().getFilesDir().getAbsoluteFile() + "/zengjfData.txt";
133 return readIntArray(filePath, length);
134 }
135
136 /**
137 * 往文件中写入原始整形数组,其实就是填充整形0
138 *
139 * @param filePath 文件路径
140 * @param length 数组大小
141 * @throws IOException
142 */
143 static public void writeRawIntArray(String filePath, int length) throws IOException {
144
145 if (null == filePath || length <= 0)
146 return ;
147
148 if (filePath.trim().equals(""))
149 return ;
150
151 File file = new File(filePath);
152 int[] data = new int[length]; // for return data
153
154 // if file not exist in first time, just create file and make data for it
155 if (file.exists()) {
156 for (int i = 0; i < data.length; i++)
157 data[i] = 0;
158
159 writeIntArray(filePath, data);
160 }
161 }
162
163 /**
164 *
165 * 往文件中写入值为0的整形数组,文件位置、名已经被指定,作为使用者可以不关心
166 *
167 * @param activity 调用这个函数的Activity
168 * @param length 写入数组的长度
169 * @throws IOException
170 */
171 static public void writeRawIntArray(Activity activity, int length) throws IOException{
172 if (null == activity || 0 == length)
173 return ;
174
175 String filePath = activity.getApplicationContext().getFilesDir().getAbsoluteFile() + "/zengjfData.txt";
176 writeRawIntArray(filePath, length);
177 }
178
179 /**
180 * 测试用的的Demo
181 * @param activity 调用这个函数的Activity
182 */
183 static public void testDemo(Activity activity) {
184 int[] data = {1, 2, 3, 4, 5, 6};
185 try {
186 writeIntArray(activity, data);
187 int[] redata = readIntArray(activity, 6);
188 Log.e("zengjf utils", Arrays.toString(redata));
189 } catch (IOException e) {
190 // TODO Auto-generated catch block
191 e.printStackTrace();
192 }
193 }
194 }