파일을 이용한 데이터 저장은 SharedPreferences보다 더 복잡하고 다양한 데이터를 다룰 수 있다.
JPG나 비트맵같은 이미지, MP3, MP4 같은 음성, 동영상, 긴 텍스트를 저장하고 불러올 수 있다.
파일 입출력을 연습해보기 위해 플러터 프로젝트를 만들었다.
먼저 pubspec.yaml
파일에 파일 입출력을 돕는 path_provider
패키지를 등록했다.
dependencies:
flutter:
sdk: flutter
# The following adds the Cupertino Icons font to your application.
# Use with the CupertinoIcons class for iOS style icons.
cupertino_icons: ^1.0.2
path_provider: ^2.0.2
fileApp.dart
라는 새 다트 파일을 만들고 StatefulWidget
을 상속받는 FileApp
클래스를 작성했다.
import 'package:flutter/material.dart';
class FileApp extends StatefulWidget {
State<StatefulWidget> createState() {
return _FileApp();
}
}
class _FileApp extends State<FileApp>{
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('File Example'),
),
body: Container(),
);
}
}
_FileApp
클래스에 파일을 읽고 쓸 수 있는 함수를 만들었다.
import 'package:flutter/material.dart';
import 'dart:io';
import 'package:path_provider/path_provider.dart';
class FileApp extends StatefulWidget { ... }
class _FileApp extends State<FileApp>{
int _count = 0;
void initState(){
super.initState();
readCountFile();
}
Widget build(BuildContext context) { ... }
void writeCountFile(int count) async {
var dir = await getApplicationDocumentsDirectory();
File(dir.path + '/count.txt').writeAsStringSync(count.toString());
}
void readCountFile() async {
try{
var dir = await getApplicationDocumentsDirectory();
var file = await File(dir.path + '/count.txt').readAsString();
print(file);
setState(() {
_count = int.parse(file);
});
}catch(e){
print(e.toString());
}
}
}
파일 입출력은 환경에 따라 작업이 언제 끝날지 알 수 없으므로 비동기 함수로 만들었다.
path_provider
패키지에 들어 있는 getApplicationDocumentsDirectory()
메소드를 이용해 냐부 저장소의 경로를 가져와서 그곳에 파일을 읽거나 쓸 수 있다.
writeCountFile()
메소드는 매개변수로 전달받은 count
값을 count.txt
라는 이름의 파일로 만들어 문자열 형태로 저장하고,
readCountFile()
메소드는 이 파일을 읽어 다시 정수형으로 변환한 후 _count
변수에 저장한다.
앱이 실행될 때 파일에서 가져온 데이터를 표시하기 위해 initState()
메소드에 readCountFile()
메소드를 호출한다.
build()
함수를 다음처럼 작성해 화면을 설계했다.
build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('File Example'),
),
body: Container(
child: Center(
child: Text('$_count', style: TextStyle(fontSize: 40),),
),
),
floatingActionButton: FloatingActionButton(
onPressed: () {
setState(() {
_count++;
});
writeCountFile(_count);
},
child: Icon(Icons.add),
),
);
}
Widget
텍스트 위젯에 _count
값을 넣고 Floating Button을 누를 때마다 값을 증가시킨다.
증가한 _count
값을 파일에 저장하도록 Floating Button의 onPressed()
이벤트 안에서 writeCountFile()
메소드를 호출한다.
main.dart
파일에 작성한 fileApp.dart
파일을 추가하고
MyApp
클래스의 home
값을 FileApp
클래스로 수정한다.
import 'package:flutter/material.dart';
import 'fileApp.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
// This widget is the root of your application.
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
useMaterial3: true,
),
home: FileApp()
);
}
}
앱을 실행하고 Floating Button을 누르면 화면의 값이 증가한다.
그리고 앱을 종료하고 다시 실행해도 화면의 값이 초기화되지 않고 누적된다.