How do I create a "fake" dart:io File from MemoryFileSystem bytes?

Viewed 42

I have the in-memory bytes of a decrypt epub file, but the package that I want to open this epub file with only accepts dart:io File objects.

I don't want to create real local file => just for security

Is there a way to create a "fake" dart:io File, simply wrapping my in-memory bytes, so that I can pass this "fake" File to the package?

I'm using vocsy_epub_viewer package to open epub files

filePath should be a local file filePath should be a local file

import 'package:archive/archive.dart';
import 'package:flutter/material.dart';
import 'package:vocsy_epub_viewer/epub_viewer.dart';
import 'package:file_picker/file_picker.dart';
import 'package:path_provider/path_provider.dart';
import 'package:encrypt/encrypt.dart' as en;
import 'dart:io';
import 'package:cross_file/cross_file.dart';
import 'package:file/memory.dart';
import 'package:file/file.dart' as F;

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Ebook(),
    );
  }
}

class Ebook extends StatefulWidget {
  @override
  State<Ebook> createState() => _EbookState();
}

class _EbookState extends State<Ebook> {
  Directory? _temp;
  String? path;
  @override
  void initState() {
    address();
    super.initState();
  }

  Future decodeEpub(String path) async {
    final bytes = await File(path).readAsBytes();
    Archive archive =
        await ZipDecoder().decodeBytes(bytes, password: '7web', verify: true);
    final data = await archive.first.content;
    final key = en.Key.fromUtf8('qwertyuiopasdfghjklmnbvcxzasdfgh');
    final iv = en.IV.fromLength(16);
    final decrypted = await en.AES(key).decrypt(en.Encrypted(data), iv: iv);
    // XFile file = await XFile.fromData(decrypted,name:'2.epub',path:"${_appDocumentsDirectory!.path}/2.epub" );
    // File file1= await File(file.path).create(recursive: true);
    // File file = MemoryFileSystem().file('${temp!.path}/2.epub')..create(recursive: true)
    //   ..writeAsBytesSync(decrypted);
    File file = await File('${_temp!.path}/2.epub').writeAsBytes(decrypted);  // it must be change ******

    print(file.path);

    return file.path;
  }

  void address() async {
    final temp = await getTemporaryDirectory();
    setState(() {
      _temp = temp;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            ElevatedButton(
                onPressed: () async {
                  FilePickerResult? result =
                      await FilePicker.platform.pickFiles();
                  if (result != null) {
                    File file = File(result.files.single.path!);
                    path = await decodeEpub(file.path);
                    print('?= $path , ${file.path}');
                  } else {
                    print('cancel');
                  }
                },
                child: Text('add File')),
            ElevatedButton(
              onPressed: () {
                EpubViewer.setConfig(
                    themeColor: Theme.of(context).primaryColor,
                    identifier: "iosBook",
                    scrollDirection: EpubScrollDirection.ALLDIRECTIONS,
                    allowSharing: true,
                    enableTts: true,
                    nightMode: false);
                EpubViewer.open(path!, lastLocation: EpubLocator());
              },
              child: Text("open"),
            ),
          ],
        ),
      ),
    );
  }
}
1 Answers

I don't want to create real local file => just for security

This is not actually true because EPUBs are structured as a zip file and folioreader, the framework used behind the vocsy_epub_viewer, will "unzip" the file to a temp folder (or one predefined). So, in the end, it's not going to be secure anyway.

Just extract the EPUB to the temp folder from path_provider and remove it afterwards. Otherwise, you're going to need a new framework to read EPUBs that don't have this behaviour or even customize the vocsy_epub_viewer/folioreader sources yourself to make it secure.

Related