Problem Explanation
I have a file that looks like this:
myfile1.txt
[
{
"question": "Thanks for the help",
"answer choices": [
"Hi",
"stack",
"over",
"flow",
],
},
...
]
This file contains data that needs to be set to a variable in a separate Dart file. The file type of this data does not matter, so if a .dart file would be easier to work with that would be perfectly fine.
Example of dart file that calls for the above file:
main.dart
void main() {
List<Map<String, dynamic>> data;
for (int i=0; i<5; i++) {
data = getFile("myfile$i.txt");
// Does stuff here
}
}
Note: getFile() does not actually have to be used. It's just a placeholder for the example.
Question: How would I set the data in this file to the variable data while in a function (like main()).
My attempt
Ideally, I wouldn't want to make many changes to the data file but here is what I did:
myfile1.dart
List<Map<String, dynamic>> data = [
...
]
I changed the file type to a .dart file and created a variable that would be set to the data.
I then modified my main.dart file like so:
main.dart
void main() {
for (int i=0; i<5; i++) {
import "myfile$i.dart";
// Does stuff here
}
}
This approach fails because import cannot be called from inside a function.
You can't use the word import there. It's reserved word, used for loading flutter/dart packages, class files, etc. It's not for "loading" some arbitrary data from a file.
Flutter official website has a cookbook example for reading and writing data from and to files. Perhaps their example would work for you?
This isn't JavaScript. Before any of the program is running, all the potential Dart code must have already been compiled. You don't get to keep compiling Dart into anything after the first step of main() is active.
Related
I need to scan my assets directory for other files and directories, like
-assets
-category1
-file.1
-category2
-file.1
-file.2
Is it possible at all using Flutter, Dart? Can't find any guide to scan directories.
import 'dart:io';
void main(List<String> args) async {
FileSystemEntity entity = Directory.current;
if (args.isNotEmpty) {
//if you pass the/path/you/wish
//this block will be handled
String arg = args.first;
entityForAbsolutePath = FileSystemEntity.isDirectorySync(arg) ? Directory(arg) : File(arg);
}
var dir = Directory(entityForAbsolutePath.absolute.path);
Stream<File> scannedFiles = scanningFilesWithAsyncRecursive(dir);
scannedFiles.listen((File file) {
print(file.path);
});
}
//async* + yield* for recursive functions
Stream<File> scanningFilesWithAsyncRecursive(Directory dir) async* {
//dirList is FileSystemEntity list for every directories/subdirectories
//entities in this list might be file, directory or link
var dirList = dir.list();
await for (final FileSystemEntity entity in dirList) {
if (entity is File) {
yield entity;
} else if (entity is Directory){
yield* scanningFilesWithAsyncRecursive(Directory(entity.path));
}
}
}
You can benefit from this idea.
if you run this snippet as entry point, like this:
$ dart your_dart_project/bin/main.dart /home/uname/any/absolute/path/you/wish
it will take the/any/path/you/wish as root and travers all of subdirectories and prints every file name as absolute path like:
home/uname/any/absolute/path/you/wish/myfile.any
home/uname/any/absolute/path/you/wish/myfile1.any
home/uname/any/absolute/path/you/wish/subdir/mysubdirfile1.any
home/uname/any/absolute/path/you/wish/subdir/mysubdirfile2.any
home/uname/any/absolute/path/you/wish/subdir/inner/myinnerfile1.any
P.S. if you will not show any path to dart command like this:
$ dart your_dart_project/bin/main.dart
it will travers in the directory your_dart_project/bin,
the line FileSystemEntity entity = Directory.current; tells about it
You can read platform files and directories if you can load "dart:io" (everything but flutter web). This doesn't work for the assets. The rootBundle can give you a json string added during the build which lists the assets and fonts (AssetManifest.json and FontManifest.json), but otherwise, there are really no "directories" in the asset bundle, just assets accessible using a path-like syntax.
i am learning imagepicker from https://pub.dev/packages/image_picker ,
but i don't why i got an error when i have use the way step by step.
this is the problem :
first, i declare a File variable
File _imageFile ;
then i use it in a method,
_getimg() async{
var _img = await ImagePicker(source: ImageSource.gallery);
setState(() {
_imageFile = _img ;
});
}
and then i got this error :
A value of type 'File (where File is defined in
D:\Flutter\flutter\bin\cache\pkg\sky_engine\lib\io\file.dart)' can't
be assigned to a variable of type 'File (where File is defined in
D:\Flutter\flutter\bin\cache\pkg\sky_engine\lib\html\html_dart2js.dart)'.
There is a conflict between Files declaration. The html package has one declaration of a class File and the io package has another declaration (same name, different origin).
In fact, using html is for web and io is used for console, server or mobile apps, so check your imports and delete io or html depending in the type of project you are working on.
Another solution is to define your imports like this:
import 'package:html/html.dart' as h; //"h" can change, is just an example
import 'dart:io' as i; //"i" also can be another char or word, is just an example
//And when you need to create a File,
//you can decide if you want to create
//an io File or an html File
main(){
i.File f1 = ...; //The io File, starting with "i."
h.File f2 = ...; //The html File, starting with "h."
}
Assume I have a flutter test file foo_test.dart with:
void main() {
final file = ...how to get the path of this file... 'foo_test.dart';
...
}
How can I achieve that?
The following snippet allows to retrieve the file containing main():
final mainFile = Uri.parse(RegExp(r'#.*main \((.*):.*:.*\)')
.firstMatch(StackTrace.current.toString())
.group(1))
.toFilePath();
I can load one file and traverse it with babel, it goes something like this:
var babylon = require("babylon");
let contents = fs.readFileSync("example.js","utf-8");
let ast = babylon.parse(contents);
Now the question is, how can I get the AST (Abstract Syntax Tree) if I have multiple files in my program.
main.js
export const getFoo(){
return "a"
}
example.js
import {getFoo} from './main'
let bar = getFoo() + "baz";
Obviously I would like to see the function declaration and the function call expression into the same AST, but also at the same time getting the line numbers and columns (node.loc) information to also show the specific file.
You can concatenate the AST from several files if you know their paths and can load them.
import {parse} from '#babel/parser';
const a = 'var a = 1;'; // or fs.readFileSync("a.js","utf-8");
const b = 'var b = 2;'; // or fs.readFileSync("b.js","utf-8");
const astA = parse(a, { sourceFilename: 'a.js' });
const astB = parse(b, { sourceFilename: 'b.js' });
const ast = {
type: 'Program',
body: [].concat(astA.program.body, astB.program.body)
};
Source example
But I can't find out how to get AST from several files without loading them directly. I tried to write a babel plugin to analyze code from an imported file and I haven't realized how to do that.
lets say I have a text file with lines as such:
[4/20/11 17:07:12:875 CEST] 00000059 FfdcProvider W com.test.ws.ffdc.impl.FfdcProvider logIncident FFDC1003I: FFDC Incident emitted on D:/Prgs/testing/WebSphere/AppServer/profiles/ProcCtr01/logs/ffdc/server1_3d203d20_11.04.20_17.07.12.8755227341908890183253.txt com.test.testserver.management.cmdframework.CmdNotificationListener 134
[4/20/11 17:07:27:609 CEST] 0000005d wle E CWLLG2229E: An exception occurred in an EJB call. Error: Snapshot with ID Snapshot.8fdaaf3f-ce3f-426e-9347-3ac7e8a3863e not found.
com.lombardisoftware.core.TeamWorksException: Snapshot with ID Snapshot.8fdaaf3f-ce3f-426e-9347-3ac7e8a3863e not found.
at com.lombardisoftware.server.ejb.persistence.CommonDAO.assertNotNull(CommonDAO.java:70)
Is there anyway to easily import a data source such as this into protovis, if not what would the easiest way to parse this into a JSON format. For example for the first entry might be parsed like so:
[
{
"Date": "4/20/11 17:07:12:875 CEST",
"Status": "00000059",
"Msg": "FfdcProvider W com.test.ws.ffdc.impl.FfdcProvider logIncident FFDC1003I",
},
]
Thanks, David
Protovis itself doesn't offer any utilities for parsing text files, so your options are:
Use Javascript to parse the text into an object, most likely using regex.
Pre-process the text using the text-parsing language or utility of your choice, exporting a JSON file.
Which you choose depends on several factors:
Is the data somewhat static, or are you going to be running this on a new or dynamic file each time you look at it? With static data, it might be easiest to pre-process; with dynamic data, this may add an annoying extra step.
How much data do you have? Parsing a 20K text file in Javascript is totally fine; parsing a 2MB file will be really slow, and will cause the browser to hang while it's working (unless you use Workers).
If there's a lot of processing involved, would you rather put that load on the server (by using a server-side script for pre-processing) or on the client (by doing it in the browser)?
If you wanted to do this in Javascript, based on the sample you provided, you might do something like this:
// Assumes var text = 'your text';
// use the utility of your choice to load your text file into the
// variable (e.g. jQuery.get()), or just paste it in.
var lines = text.split(/[\r\n\f]+/),
// regex to match your log entry beginning
patt = /^\[(\d\d?\/\d\d?\/\d\d? \d\d:\d\d:\d\d:\d{3} [A-Z]+)\] (\d{8})/,
items = [],
currentItem;
// loop through the lines in the file
lines.forEach(function(line) {
// look for the beginning of a log entry
var initialData = line.match(patt);
if (initialData) {
// start a new item, using the captured matches
currentItem = {
Date: initialData[1],
Status: initialData[2],
Msg: line.substr(initialData[0].length + 1)
}
items.push(currentItem);
} else {
// this is a continuation of the last item
currentItem.Msg += "\n" + line;
}
});
// items now contains an array of objects with your data