Flutter - 파일에 데이터 저장하기(1)

유의선·2024년 3월 25일
0

파일을 이용한 데이터 저장은 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() 함수를 다음처럼 작성해 화면을 설계했다.

  
  Widget 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),
      ),
    );
  }

텍스트 위젯에 _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을 누르면 화면의 값이 증가한다.
그리고 앱을 종료하고 다시 실행해도 화면의 값이 초기화되지 않고 누적된다.

0개의 댓글