Flutter Dosya Erişim Problemi - OS Error: No such file or directory

Merhaba arkadaşlar, bu sıralar fırsat buldukça Flutter ile uğraşıyorum ve henüz çok yeniyim. Basit projelerle kendimi geliştirmeye çalışıyorum. Excel dosyası okuyan bir proje yapmaya çalışıyorum ve başlıktaki hatayı alıyorum.

Linux/Debian tabanlı Pardus 23 XFCE işletim sistemini kullanıyorum.

Faydalandığım kaynak:

Dökümantasyonda olay açık ve net anlatılmış. Aşağıdaki görselde proje klasör hiyerarşim görülmekte.

proje_agaci

  • Turuncu renkli ok, main.dart dosyamı gösteriyor. Uygulama buradan çalışmaya başlıyor.
  • Kırmızı renkli ok, api klasörü içerisindeki file_connect.dart dosyamı, bu dosyamın kullanacağı plan_6.xlsx Excel dosyasını gösteriyor.
  • Yeşil renkli ok, Excel dosyası, metin belgesi gibi çeşitli dosyaları içerisinde barındıran assets klasörünü gösteriyor.

pubspec.yaml dosyamın içeriği aşağıdaki gibi

name: plan_okuyucu
description: A new Flutter project.
publish_to: 'none' # Remove this line if you wish to publish to pub.dev
version: 1.0.0+1

environment:
  sdk: '>=3.1.3 <4.0.0'

dependencies:
  flutter:
    sdk: flutter

  cupertino_icons: ^1.0.2

  path_provider: ^2.1.1
  excel: ^4.0.2

dev_dependencies:
  flutter_test:
    sdk: flutter

  flutter_lints: ^2.0.0


flutter:
  uses-material-design: true

  # To add assets to your application, add an assets section, like this:
  assets:
    - assets/plan_6.xlsx
    - assets/sample.txt

Amacım şimdilik sadece Excel dosyası içindeki verileri terminalde görüntülemek, bunu yaptıktan sonra widget’leri yerleştirmeye başlayacam.

api/file_connect.dart dosyası içeriği

import 'dart:io';
import 'package:excel/excel.dart';

class FileConnect{
  String fileName;

  FileConnect(this.fileName);

  Excel getExcel() {
  var bytes = File("/assets/$fileName").readAsBytesSync();
  var excel = Excel.decodeBytes(bytes);
  return excel;
  }

  void printExcelFile(Excel excel) {
    for (var table in excel.tables.keys) {
      print(table); //sheet Name
      print(excel.tables[table]?.maxColumns);
      print(excel.tables[table]?.maxRows);
      for (var row in excel.tables[table]!.rows) {
        for (var cell in row) {
          print('cell ${cell?.rowIndex}/${cell?.columnIndex}');
          final value = cell?.value;
          final numFormat = cell?.cellStyle?.numberFormat ?? NumFormat.standard_0;
          switch(value){
            case null:
              print('  empty cell');
              print('  format: ${numFormat}');
            case TextCellValue():
              print('  text: ${value.value}');
            case FormulaCellValue():
              print('  formula: ${value.formula}');
              print('  format: ${numFormat}');
            case IntCellValue():
              print('  int: ${value.value}');
              print('  format: ${numFormat}');
            case BoolCellValue():
              print('  bool: ${value.value ? 'YES!!' : 'NO..' }');
              print('  format: ${numFormat}');
            case DoubleCellValue():
              print('  double: ${value.value}');
              print('  format: ${numFormat}');
            case DateCellValue():
              print('  date: ${value.year} ${value.month} ${value.day} (${value.asDateTimeLocal()})');
            case TimeCellValue():
              print('  time: ${value.hour} ${value.minute} ... (${value.asDuration()})');
            case DateTimeCellValue():
              print('  date with time: ${value.year} ${value.month} ${value.day} ${value.hour} ... (${value.asDateTimeLocal()})');
          }

          print('$row');
        }
      }
    }
  }
}

main.dart dosyamın içeriği

import 'package:flutter/material.dart';
import 'package:plan_okuyucu/api/file_connect.dart';

void main() {
  runApp(MaterialApp(home: MyApp()));
}



class MyApp extends StatefulWidget {

  @override
  State<MyApp> createState() => _MyHomePageState();
}


class _MyHomePageState extends State<MyApp> {
  var fc = FileConnect('plan_6.xlsx');

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("Excel read"),
      ),
      body: bodyBuild(context),
      floatingActionButton: FloatingActionButton(
        onPressed: () {
          deneme();
        },
        child: const Icon(Icons.add),
      ),// This trailing comma makes auto-formatting nicer for build methods.
    );
  }

  bodyBuild(BuildContext context) {
    return const Center(
      child: Column(
        mainAxisAlignment: MainAxisAlignment.center,
        children: <Widget>[
          Text("Dosya içeriği için butona tıklayınız"),
        ],
      ),
    );
  }

  void deneme() {
    var excelFile = fc.getExcel();
    fc.printExcelFile(excelFile);
  }

}

Uygulama açıldığında aşağıdaki gibi basit bir arayüz görünüyor, mavi buton excel’i okuyacak metodu tetikliyor.

Aşağıdaki gibi hata düşüyor;
Cannot open file, path = '/assets/plan_6.xlsx' (OS Error: No such file or directory, errno = 2)

Saatlerdir uğraşıyorum çözemedim. Basit bir txt okumaya çalıştım o da olmadı. Muhtemelen basit birşey ama nerede hata yapıyorum anlamadım.
Teşekkürler

bkz: CWD (Current Working Directory) Nedir?

1 Beğeni

Teşekkür ederim. Güzel, faydalı bir yazı olmuş. Aslında CWD hakkında malumatım vardı bundan olabileceğini düşünmüştüm fakat kaçırdığım nokta vardı sen tekrar CWD’yi belirtince aklımda yeniden ampul yandı.

Ben nasıl olsa uygulama bilgisayarımda home klasörü altında, AndroidStudioProjects klasörünün altindaki kendi klasöründe çalışıyordur diye düşünmüştüm açıkçası. Sen konuyu belirttikten sonra araştırdım. Uygulama derlenip APK haline geldikten sonra emülatör üzerinde çalışıyor, dolayısıyla emülatör üzerindeki android os’nin o uygulama için tahsis ettiği klasör CWD oluyormuş. CWD’yi emülatör 'de aramak aklıma gelmemişti ilk etapta.

Uygulama içinde kullanılacak bir görsel ya da dil dosyaları yukarıda bahsettiğim home içindeki proje dizininde assets diye bir klasörde tutulabiliyor, ben Excel dosyası için de aynı mantık olur diye düşündüm yanılmışım. Zaten mantık olarak da yanlış.

Güzel bir tecrübe oldu, geniş vaktimde aşağıya ilgili birkaç fonksiyon ve kod yazacam. Tekrar teşekkürler

Rica ederim.

Emulator (ve sandboxing) olaylari karistirsa da CWD konsepti baki.

File’in / ile baslamasi sikinti, degli mi? Yoksa hic bir aplikasyon kendi dizininin yukarisina erisemezdi.

Gerci chroot tam olarak bunu yapan bir mekanizma.

1 Beğeni