app一些重要步驟 比如支付 需要把用戶每一步日志寫入到本地,如果有異常,可以服務(wù)端下發(fā)一個(gè)字段,讓設(shè)備自動(dòng)上傳日志, 或者用戶某個(gè)操作主動(dòng)觸發(fā)上傳本地日志.
我寫了一個(gè)可以寫入文件的類,自動(dòng)刪除超過7天的文件
每天生成一個(gè)文件 ,每次啟動(dòng)有標(biāo)識(shí)
每個(gè)log都有時(shí)間
上傳時(shí)候調(diào)用showFileList()打印出來所有文件列表
調(diào)用接口上傳文件就行
尤其對(duì)ios內(nèi)購很必要,內(nèi)購邏輯都在客戶端,如果你的邏輯不完善 再?zèng)]有日志,出現(xiàn)丟單的話 就沒法排查了.有了日志 出現(xiàn)問題你能找到問題原因 解決問題
使用時(shí)候要提前一個(gè)地方 調(diào)用下FileWriteLog.instance提前生成目錄
打印時(shí)候 FileWriteLog.log('xxxx');
每天第一次打印時(shí)候 會(huì)生成一個(gè)文件 文件名字是當(dāng)天日期
class FileWriteLog {
FileWriteLog._() {
createDirectory();
}
static FileWriteLog? _instance;
static FileWriteLog get instance => _getOrCreateInstance();
static FileWriteLog _getOrCreateInstance() {
if (_instance != null) {
return _instance!;
} else {
_instance = FileWriteLog._();
return _instance!;
}
}
File? currentFile;
static bool isFirst = true;
static log(String content) {
if (isFirst) {
isFirst = false;
FileWriteLog.instance
.writeFile('-----------------app啟動(dòng) 日志開始-----------------------\n '
'UserId--->${LoginTool.getUserId}\n $content');
} else {
FileWriteLog.instance.writeFile(content);
}
}
// 寫入一次 文件才會(huì)生成
writeFile(String content) async {
if (fileName.isNotEmpty) {
try {
jdLog('寫入文件內(nèi)容---->$content');
IOSink sink = currentFile!.openWrite(mode: FileMode.append);
sink.writeln(
'$content ---- 時(shí)間 ${TimeTool.formatFullInfo(DateTime.now())}');
await sink.flush();
await sink.close();
} catch (e) {
jdLog('寫入異常----> $e');
}
}
}
String fileType = '.txt';
Future<String> readFile() async {
try {
bool exist = await FileTool.fileExists(fileName);
if (!exist) {
jdLog('文件不存在');
return '';
}
File file = File(fileName);
String contents = await file.readAsString();
jdLog('read 內(nèi)容----> $contents');
return contents;
} catch (e) {
return '';
}
}
String fileName = '';
createFileName() {
if (fileName.isNotEmptyNullAble) {
return fileName;
}
var time = DateTime.now();
// 一天創(chuàng)建一個(gè)日志文件 半個(gè)月前的日志文件刪除
String name =formatDateTime(time);
fileName = '$currentDirectory/$name$fileType';
currentFile = File(fileName);
return fileName;
}
String formatDateTime(DateTime dateTime,
[String format = 'yyyy-MM-dd']) {
return DateFormat(format).format(dateTime);
}
String currentDirectory = '';
void createDirectory() async {
// 創(chuàng)建Directory對(duì)象
Directory documentPath = await getApplicationDocumentsDirectory();
currentDirectory = '${documentPath.path}/jdLog';
Directory directory = Directory(currentDirectory);
// 檢查目錄是否存在,如果不存在,則創(chuàng)建目錄
if (!await directory.exists()) {
// 設(shè)置recursive為true以確保創(chuàng)建任何必要的父目錄
await directory.create(recursive: true);
jdLog('Directory created successfully!');
} else {
jdLog('Directory already exists.');
}
createFileName();
deleteOldFiles();
}
showFileList() {
FileTool.listFilesInDirectory(currentDirectory).then((List<String> value) {
jdLog('當(dāng)前文件列表----$value');
});
}
deleteAllFiles() {
FileTool.listFilesInDirectory(currentDirectory).then((List<String> value) {
value.mapIndex((index, element) {
FileTool.deleteFile(element);
});
});
}
deleteOldFiles() {
FileTool.listFilesInDirectory(currentDirectory).then((List<String> value) {
var nowTime = DateTime.now();
value.mapIndex((index, element) {
try {
List<String> parts = element.split('/'); // 使用 '/' 分割路徑
// 獲取最后一段路徑
String lastSegment = parts.isNotEmpty ? parts.last : '';
if (lastSegment.endsWith(fileType)) {
lastSegment = lastSegment.substring(0, lastSegment.length - 4);
}
// jdLog('獲取的文件名字22------$lastSegment');
DateTime? time = TimeTool.parse(lastSegment);
if (time is DateTime) {
Duration difference = time.difference(nowTime);
int days = difference.inDays;
if (days > 7) {
// 刪除超過7天的文件
jdLog('離現(xiàn)在差距$days天 刪除了-------->');
FileTool.deleteFile(element);
}
}
} catch (onError) {
jdLog('轉(zhuǎn)換后的onError--------> $onError');
}
});
});
}
}
具體的封裝實(shí)現(xiàn)在https://gitee.com/kuaipai/my_app.git