I'm new to coding in Dart so please bear with me. I searched up how to read files with the readAsString() function from the flutter API. It says that it will read the entire content of the file and return it as a String. However, is there some sort of String max size that it can only read? I could not find the max size of a String in Dart online. Thanks.
Here's the code in case you want a look:
import 'dart:async';
import 'dart:io';
import 'package:path_provider/path_provider.dart';
class Storage {
Future<String> get localPath async {
final directory = await getApplicationDocumentsDirectory();
return directory.path;
}
Future<File> get localFile async {
final path = await localPath;
return File('$path/data.txt');
}
Future<List<String>> read() async {
try {
final file = await localFile;
String contents = await file.readAsString(); //the important part
return contents.split(";");
} catch (exception) {
return null;
}
}
void write(List data) async {
final file = await localFile;
String toWrite = "";
for (int i = 0; i < data.length; i++) {
toWrite += data.elementAt(i) + ";";
}
file.writeAsString(toWrite);
}
}
Maybe you want something like:
var myFileStream = File('path/to/file').openRead();
var firstChars = myFileStream.take(1024);
This will limit the memory part of the file to the first 1024 characters.
(I think. :)
Related
I have a project with encrypt an audio for secure my data audio and when the user purchase they can play the audio, but until now didn't find how to do that. I found another way by converting the audio data into a string and then encrypting it, I found a code but it's incomplete so I'm still confused about using it.
import 'dart:io';
import 'dart:typed_data';
import 'package:file_picker/file_picker.dart';
import 'package:path_provider/path_provider.dart';
class MediaFile {
Future<String> get docPath async {
Directory appDocDir = await getApplicationDocumentsDirectory();
return appDocDir.path;
}
Future<Uint8List> get audioFileData async {
final String path = await docPath;
final String theFilePath = '$path/test.mp3';
final File theFile = new File(theFilePath);
if (await theFile.exists()) {
return await theFile.readAsBytes();
} else {
File file = await FilePicker.getFile();
return await file.readAsBytes();
}
}
Future<String> dataToString() async {
Uint8List data = await audioFileData;
return new String.fromCharCodes(data);
}
Future<File> saveMediaAsString(String fileName, String fileContent) async {
String path = await docPath;
Directory dataDir = new Directory('$path/data');
if (await dataDir.exists()) {
File file = new File('$path/data/$fileName');
return file.writeAsString(fileContent);
}
await dataDir.create();
File file = new File('$path/data/$fileName');
return file.writeAsString(fileContent);
}
Future<String> readFromStringMediaFile(String fileName) async {
String path = await docPath;
File file = new File('$path/data/$fileName');
return file.readAsString();
}
Uint8List stringToData(dataStr) {
List<int> list = dataStr.codeUnits;
return new Uint8List.fromList(list);
}
Future<File> createAudioFile(String fileName, Uint8List bytes) async {
String path = await docPath;
File file = new File('$path/$fileName');
return await file.writeAsBytes(bytes);
}
//here you can see how to use them
Future<File> testFile() async {
String dataStr = await dataToString();
File savedFile = await saveMediaAsString('codedFile', dataStr);
String contentSavedFile = await readFromStringMediaFile('codedFile');
Uint8List bytes = stringToData(contentSavedFile);
return await createAudioFile('test.mp3', bytes);
}
}
Here comes the pdf converted to base64 from an API. I cannot view and download from within the application. I would be glad if you help.
Thanks in advance.
First you need to add "path_provider" and "open_file"
dependencies:
path_provider: ^2.0.9
open_file: ^3.2.1
Then create new class
class FileProcess {
static bool isFolderCreated = false;
static Directory? directory;
static checkDocumentFolder() async {
try {
if (!isFolderCreated) {
directory = await getApplicationDocumentsDirectory();
await directory!.exists().then((value) {
if (value) directory!.create();
isFolderCreated = true;
});
}
} catch (e) {
print(e.toString());
}
}
static Future<File> downloadFile() async {
final base64str = "put your base64 value";
Uint8List bytes = base64.decode(base64str);
await checkDocumentFolder();
String dir =
directory!.path + "/" + "your file name" + ".pdf";
File file = new File(dir);
if (!file.existsSync()) file.create();
await file.writeAsBytes(bytes);
return file;
}
}
After you create the class you can use it for download your pdf.
For open the file add this lines into your class
static void openFile(String fileName) {
String dir =
directory!.path + "/${fileName}.pdf";
OpenFile.open(dir));
}
After all you can use like
await FileProcess.downloadFile()
and
FileProcess.openFile(fileName)
These codes should be working.
I would compress a list of image file before uploading, but i have some doubts to convert type after using map a list of file, it return type List<Set<Future>>, not type List as I expect. How can I convert/cast to List of File in this situation, the compressImage function worked well with only one file. Thank you so much.
import 'package:image/image.dart' as Im;
import 'package:uuid/uuid.dart';
List<File> compressImageList(List<File> tempfileList) async {
List<Future<File>> compressedFileList =
tempfileList.map((file) => {compressImage(file)}).toList();
return compressedFileList ;
}
Future<File> compressImage(File tempFile) async {
String postId = Uuid().v4();
final tempDir = await getTemporaryDirectory();
final path = tempDir.path;
Im.Image? imageFile = Im.decodeImage(tempFile.readAsBytesSync());
final compressedImageFile = File('$path/img_$postId.jpg')
..writeAsBytesSync(Im.encodeJpg(imageFile!, quality: 85));
tempFile = compressedImageFile;
return tempFile;
}
i edit my function as below and it works , thank you.
Future<List<File>> compressImageList(List<File> tempfileList) async {
List<File> compressedFileList = [];
await Future.wait(tempfileList.map((file) async {
var compressImage2 = await compressImage(file);
compressedFileList.add(compressImage2);
}).toList());
return compressedFileList;
}
Not sure, haven't tested it, but try removing the {} on the 6th line (as shown above). These brackets signify that it is a type set, which is being returned by =>. If using => for a single statement you don't need to use brackets.
Do it like this;
List<File> compressImageList(List<File> tempfileList) {
List<File> compressedFiles = [];
tempfileList.forEach((file) async {
final compressedFile = await compressImage(file);
compressedFiles = [...compressedFiles, compressedFile];
});
return compressedFiles;
}
My flutter app user data takes up a lot of space. I'm currently using the following code to save the user data
class FileUtil {
static Future<String> get getFilePath async {
final directory = await getApplicationDocumentsDirectory();
return directory.path;
}
static Future<File> get getFile async {
final path = await getFilePath;
return File('$path/user.txt');
}
static Future<File> saveToFile(String data) async {
final file = await getFile;
return file.writeAsString(data);
}
static Future readFromFile() async {
try {
final file = await getFile;
String fileContents = await file.readAsString();
log(fileContents);
return json.decode(fileContents);
} catch (e) {
return "";
}
}
String formatData() {
String formattedString;
Map x = {};
x['a'] = a;
// other variables
formattedString = json.encode(x);
return formattedString;
}
void saveData() async {
try {
await saveToFile(formatData());
//print('DATA SAVED');
} catch (e) {
//print('Could not save data due to: $e');
}
}
}
Whenever the user interacts with something in the app that needs to be saved, I run saveData(). This happens quite often in my app. However, after using the app for a while, the user data can jump to a few hundred MB. I've used a JSON calculator to estimate the space of the formatData() output string and it's much less than 1MB. What should I do to minimise user data?
I'm trying to export a txt file as srt (which is written in plain text) in my app and it is working in the sense that I see srt's with the correct name in the specified folder but these files are 0B and I'm not sure where what is not fully working?
void add() async {
fileName = _fileNameCon.text.toString();
print("filename ---------> " + fileName);
newSubFile(fileName);
setState(() {
_fileNameCon.clear();
srt = "";
subnumber = 1;
stopWatch.reset();
});
}
void newSubFile(String title) async {
try {
// this is an android specific directory
Directory directory = await getExternalStorageDirectory();
final path = directory.path;
File newSrt = await File('$path/' + title + ".srt").create();
var writer = newSrt.openWrite();
print("----attempting to write to $path/$title----");
writer.write(srt);
writer.close();
print("----closing----");
} catch (e) {
print(e);
}
}
Imports
import 'dart:io'
import 'package:path/path.dart';
import 'package:path_provider/path_provider.dart';
Example:
Directory dir = await getExternalStorageDirectory();
final file = File(join('${dir.parent}/sub folder',"Output.srt"));
await file.writeAsString(subtitles)