依赖包 top.fols.box;
依赖工具类top.fols.box.io.XFile
如果你想用自定义文件而不是preference
在保存模块配置时使用
XFile.createNewFile(new File("/data/data/packageName/config/1"), false);
FileOutputStream out = new FileOutputStream(XFile.openFile(new File("/data/data/packageName/config/1"), false));
原理是修改文件权限为rwxrwxrwx
如果文件被莫名其妙更改了权限 可使用 XFile.openFile(new File("/data/data/packageName/config/1"), false); 尝试恢复权限
在宿主读写数据只需要直接
使用FileInputStream, FileOutputStream就可以读写
如果你想使用 PreferenceFragment 以及 XSharedPreferences
只需要在PreferenceFragment 继承的
onCreate方法
this.getPreferenceManager().setSharedPreferencesName("1");//设置preference文件名
onSaveInstanceState方法
XFile.openFile(new File("/data/data/packageName/shared_prefs/1.xml"), false); //修改权限
在宿主使用XSharedPreferences直接 new XSharedPreferences(new File("/data/data/packageName/shared_prefs/1.xml")); 即可
工具类代码:
public class XFile {
public static class XDoubleLinkedList implements Serializable {
private static final long serialVersionUID = 1L;
public static class VarLinkedList extends XDoubleLinkedList implements Serializable {
private static final long serialVersionUID = 1L;
private T content;
public VarLinkedList(T content) {
this.content = content;
}
@Override
public String toString() {
// TODO: Implement this method
return null == this.content ? null : this.content.toString();
}
public T content() {
return this.content;
}
@Override
public int hashCode() {
// TODO: Implement this method
return null == this.content ? 0 : this.content.hashCode();
}
@Override
public boolean equals(Object obj) {
// TODO: Implement this method
if (obj instanceof VarLinkedList) {
return null == this.content ? null == ((VarLinkedList) obj).content
: this.content.equals(((VarLinkedList) obj).content);
} else {
return null == this.content ? null == obj : this.content.equals(obj);
}
}
public static boolean equals(Object obj1, Object obj2) {
// TODO: Implement this method
Object val1 = obj1 instanceof VarLinkedList ? (((VarLinkedList) obj1).content) : obj1;
Object val2 = obj2 instanceof VarLinkedList ? (((VarLinkedList) obj2).content) : obj2;
return val1 == val2 || val1.equals(val2);
}
}
private XDoubleLinkedList last = null, next = null;
public XDoubleLinkedList() {
}
// 获取上一个item
public XDoubleLinkedList getLast() {
return this.last;
}
// 获取下一个item
public XDoubleLinkedList getNext() {
return this.next;
}
public boolean hasLast() {
return null != this.last;
}
public boolean hasNext() {
return null != this.next;
}
/*
* bottom >> elements >> top
*/
// 添加下一个item
public void addNext(XDoubleLinkedList item) {
this.addNext(this, item);
}
public static void addNext(XDoubleLinkedList index, XDoubleLinkedList addelement) {
if (null == index) {
throw new NullPointerException("item for null");
}
if (null == addelement) {
throw new NullPointerException("need add item for null");
}
/*
* [index, ...] 原index下个元素引索
*/
XDoubleLinkedList itemnext = index.next;
/*
* 如果index 的下一个元素就是addelement那么直接退出 (在位置重复添加元素了)
*/
if (itemnext == addelement) {
return;
}
/*
* 将index的下一个元素设置成 addelement
*/
index.next = addelement;
/*
* 将index 的 下一个元素 的上一个元素引索设置为 addelement
*/
if (null != itemnext) {
itemnext.last = addelement;
}
if (null != addelement.last) {
/*
* [a, addelement, index, ...] ==> [a, index, addelement, ...]
*
* 将 原来addelement所在的位置的上一个元素 的下一个元素引索 设置为 addelement的下一个元素引索
*/
addelement.last.next = addelement.next;
}
if (null != addelement.next) {
addelement.next.last = addelement.last;
}
/*
* 将addelement 的上一个元素引索设置为index
*/
addelement.last = index;
/*
* 将addelement的下个元素引索改为原index的下个元素引索
*/
addelement.next = itemnext;
}
public void remove(XDoubleLinkedList item) {
if (null == item) {
return;
}
XDoubleLinkedList itemlast = item.last;
if (null != item.next) {
item.next.last = itemlast;
}
if (null != itemlast) {
itemlast.next = item.next;
} else {
/*
* 这是栈底
*/
item.next = null;
}
}
// 获取第一个元素
public XDoubleLinkedList getBottom() {
return XDoubleLinkedList.getBottom(this);
}
// 获取最后一个元素
public XDoubleLinkedList getTop() {
return XDoubleLinkedList.getTop(this);
}
// 获取第一个元素
public static XDoubleLinkedList getBottom(XDoubleLinkedList item) {
if (null == item) {
throw new NullPointerException("item for null");
}
XDoubleLinkedList tmp = item;
XDoubleLinkedList bottom = null;
while (null != (tmp = tmp.last)) {
bottom = tmp;
}
if (null == bottom) {
return item;
}
return bottom;
}
// 获取最后一个元素
public static XDoubleLinkedList getTop(XDoubleLinkedList item) {
if (null == item) {
throw new NullPointerException("item for null");
}
XDoubleLinkedList tmp = item;
XDoubleLinkedList next = null;
while (null != (tmp = tmp.next)) {
next = tmp;
}
if (null == next) {
return item;
}
return next;
}
public static String toStringFromTopStart(XDoubleLinkedList item) {
if (null == item) {
return "{}";
}
StringJoiner sj = new StringJoiner(",", "{", "}");
XDoubleLinkedList top = getTop(item);
if (null != top) {
do {
sj.add(top.toString());
} while (top.hasLast() && null != (top = top.getLast()));
}
return sj.toString();
}
public static String toStringFromBottomStart(XDoubleLinkedList item) {
if (null == item) {
return "{}";
}
StringJoiner sj = new StringJoiner(",", "{", "}");
XDoubleLinkedList top = getBottom(item);
if (null != top) {
do {
sj.add(top.toString());
} while (top.hasNext() && null != (top = top.getNext()));
}
return sj.toString();
}
/*
* 是否为栈底
*/
public boolean isBottom() {
return null == this.last;
}
/*
* 是否为栈顶
*/
public boolean isTop() {
return null == this.last;
}
/*
* 添加到栈底
*/
public XDoubleLinkedList addToBottom(XDoubleLinkedList bottom) {
if (!isBottom()) {
throw new RuntimeException("only may be added from the bottom");
}
if (null == bottom) {
throw new NullPointerException("item for null");
}
this.addNext(bottom);
bottom.addNext(this);
return bottom;
}
/*
* 不在栈里 独立item 孤儿
*/
public boolean isOrphan() {
return null == this.last && null == this.next;
}
}
public static File setFilePermission(File file, Boolean readable, Boolean writeable, Boolean executeable,
Boolean ownerOnly) {
if (null == ownerOnly) {
if (null != readable) {
file.setReadable(readable);
}
if (null != writeable) {
file.setWritable(writeable);
}
if (null != executeable) {
file.setExecutable(executeable);
}
} else {
if (null != readable) {
file.setReadable(readable, ownerOnly);
}
if (null != writeable) {
file.setWritable(writeable, ownerOnly);
}
if (null != executeable) {
file.setExecutable(executeable, ownerOnly);
}
}
return file;
}
@SuppressWarnings("unchecked")
public static File setFilePermissions(File file, Boolean readable, Boolean writeable, Boolean executeable,
Boolean ownerOnly) {
file = file.getAbsoluteFile();
XDoubleLinkedList.VarLinkedList files = new XDoubleLinkedList.VarLinkedList<>(null);
File pn = file;
while ((pn = pn.getParentFile()) != null) {
files.addNext(new XDoubleLinkedList.VarLinkedList<>(pn));
}
XDoubleLinkedList.VarLinkedList now = files;
while (now != null && (now = (XDoubleLinkedList.VarLinkedList) now.getNext()) != null) {
File f = now.content();
setFilePermission(f, readable, writeable, executeable, ownerOnly);
}
setFilePermission(file, readable, writeable, executeable, ownerOnly);
return file;
}
public static boolean mkdirs(File file) {
return XFile.mkdirs(file, true);
}
@SuppressWarnings("unchecked")
public static boolean mkdirs(File file, Boolean ownerOnly) {
file = file.getAbsoluteFile();
if (file.exists()) {
XFile.setFilePermissions(file, true, true, true, ownerOnly);
return true;
} else {
boolean b = false;
XDoubleLinkedList.VarLinkedList files = new XDoubleLinkedList.VarLinkedList<>(null);
files.addNext(new XDoubleLinkedList.VarLinkedList<>(file));
File pn = file;
while ((pn = pn.getParentFile()) != null) {
files.addNext(new XDoubleLinkedList.VarLinkedList<>(pn));
}
XDoubleLinkedList.VarLinkedList now = files;
while (now != null && (now = (XDoubleLinkedList.VarLinkedList) now.getNext()) != null) {
File dir = now.content();
if (!dir.exists()) {
boolean result = dir.mkdir();
b = b & result;
}
XFile.setFilePermission(dir, true, true, true, ownerOnly);
}
return b;
}
}
public static File openFile(File file) {
return XFile.openFile(file, true);
}
public static File openFile(File file, Boolean ownerOnly) {
return XFile.setFilePermissions(file, true, true, true, ownerOnly);
}
public static boolean createNewFile(File file) throws IOException {
return XFile.createNewFile(file, true);
}
public static boolean createNewFile(File file, Boolean ownerOnly) throws IOException {
file = file.getAbsoluteFile();
try {
boolean b0 = false;
try {
b0 = file.createNewFile();
} catch (IOException e) {
b0 = false;
}
if (b0) {
return true;
} else {
File parent = file.getParentFile();
if (null != parent) {
XFile.mkdirs(parent, ownerOnly);
return new File(parent, file.getName()).createNewFile();
} else {
return file.createNewFile();
}
}
} finally {
XFile.setFilePermission(file, true, true, true, ownerOnly);
}
}
public static boolean delete(File file) {
return XFile.delete(file, true);
}
public static boolean delete(File file, Boolean ownerOnly) {
boolean b0 = file.delete();
if (b0) {
return true;
} else {
XFile.setFilePermissions(file, true, true, true, ownerOnly);
if (!file.exists()) {
return false;
} else {
if (file.isFile()) {
boolean result = file.delete();
return result;
} else {
boolean b1 = file.delete();
if (b1) {
return true;
}
boolean b = delete0(file, ownerOnly) & file.delete();
return b;
}
}
}
}
private static boolean delete0(File file, Boolean ownerOnly) {
boolean b = true;
File[] files = file.listFiles();
if (null != files) {
for (File f : files) {
XFile.setFilePermission(f, true, true, true, ownerOnly);
if (f.isFile()) {
b = b & f.delete();
} else if (f.isDirectory()) {
b = b & delete0(f, ownerOnly) & f.delete();
} else {
b = false;
}
}
}
return b;
}
}