看了下很多文章,本地檔案儲存都只有儲存txt檔案,我們探索下儲存二進位制檔案吧。
儲存二進位制檔案到裝置硬碟上。
我們儲存一個圖片到手機本地上,並讀取展示圖片到app上。
以百度logo圖為例子
寫入圖片
邏輯如下: 獲取本地路徑 -> 根據圖片url開始下載獲取到二進位制檔案 -> 圖片檔案寫入到本地路徑
寫入本地檔案
寫入檔案有幾種方式點我檢視file文件 分別是字串和二進位制,而寫入的時候分同步和非同步,所以寫入的有4種。\
看writeAsBytes
這個函式名字,這廝需要bytes
程式碼
writeFile(String filePath, String imgUrl){
File file = new File(filePath);
if(!file.existsSync()) {
file.createSync();
}
getRemoteFileStream(imgUrl, (fileInfo){
if(fileInfo["ok"]){
file.writeAsBytes(fileInfo["bytes"]);
}else{
debugPrint("異常");
}
});
}
複製程式碼
獲取遠端檔案流
新建一個http連線,使用dartimport 'dart:io';
自帶的哦。
使用Uri.parse解析完整的url
request.close()
開始傳送請求(小聲bb:這個命名一言難盡)
獲取到資料後,response
是一個HttpClientResponse
型別,而HttpClientResponse
型別Stream
的實現
abstract class HttpClientResponse implements Stream<List<int>>
複製程式碼
關於Stream
說起來比較複雜,推薦一個文章傳送門
Stream最後會吐出List<int>
,也就是我們需要的Bytes
程式碼
// get檔案流
getRemoteFileStream(String url, cb) async{
return new Future(() async{
HttpClient httpClient = new HttpClient();
HttpClientRequest request = await httpClient.getUrl(Uri.parse(url));
HttpClientResponse response = await request.close();
if (response.statusCode == HttpStatus.ok) {
List<int> buffer = [];
response.listen((data){
data.forEach((e){
buffer.add(e);
});
},
onDone: (){
cb({
"ok": true,
"bytes": buffer
});
},
onError: (e){
print(e);
}
);
}else{
debugPrint('HTTP request failed');
}
});
}
複製程式碼
寫好了上面兩個函式,我們現在可以獲取本地檔案路徑來寫入圖片了
最後一步,執行寫入
獲取本地路徑分為臨時檔案
和文件路徑
我們使用path_provider
來獲取本地路徑
path_provider: ^1.4.0
import 'package:path_provider/path_provider.dart';
複製程式碼
獲取本地路徑,執行讀寫本地檔案
程式碼
getLocalhostBooks() async{
String imgUrl = 'https://user-gold-cdn.xitu.io/2019/11/1/16e24dc995c95343?w=540&h=258&f=png&s=7877';
Directory tempDir = await getTemporaryDirectory();
Directory appDocDir = await getApplicationDocumentsDirectory();
debugPrint('本地路徑');
debugPrint(tempDir.path);
debugPrint(appDocDir.path);
String testPath = '${appDocDir.path}/test.png';
// // 寫入圖片
// writeFile(testPath, imgUrl);
// 讀取圖片
readFile(testPath, imgUrl);
}
複製程式碼
讀取
讀取本地檔案
readFile(String filePath, String imgUrl) async{
File file = new File(filePath);
Uint8List fileBytes = await file.readAsBytes();
setState(() {
imgBytes = fileBytes;
print(imgBytes);
});
}
複製程式碼
讀取比較簡單一點,獲取bytes,然後渲染就是了。
setState(() {
imgBytes = fileBytes;
print(imgBytes);
});
複製程式碼
Container(
child: Image.memory(imgBytes, gaplessPlayback: true,),
)
複製程式碼
效果
其他
嘻嘻,利用上面的知識,就可以手寫一個圖片快取器了。
看懂了請點贊~~ 喵喵
下一篇,集合sqlite3實現本地書籍加入書架