Can flutter do scanning directories (recursive)? - flutter

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.

Related

How to delete all files within a directory except files ending in .db

I want to be able to delete all files within the App cache directory, except files ending with .db.
void main() {
final dir = Directory(dirPath);
dir.deleteSync(recursive: true);
}
The above code will delete the entire directory, but I would like to avoid that.
How can I get the size of the cache directory in flutter?
void deleteFilesExceptExtension(String suffix, String path) {
final dir = Directory(path);
dir.list(recursive: true).listen((file) {
if (file is File && !file.path.endsWith(suffix)) file.deleteSync();
});
}
As for a directory's true size, you can refer to this question.

How to list all local mp3 files on flutter2(null safety)?

The code should be working on flutter2, with android and ios(if possible)
Searching for files
Do you want to simplify your life? Use this package:
import 'package:glob/glob.dart';
Stream<File> search(Directory dir) {
return Glob("**.mp3")
.list(root: dir.path)
.where((entity) => entity is File)
.cast<File>();
}
Do you want to avoid adding a new dependency in your project? Manipulate the Directory itself:
Stream<File> search(Directory dir) {
return dir
.list(recursive: true)
.where((entity) => entity is File && entity.path.endsWith(".mp3"))
.cast<File>();
}
Defining the search scope
You'll also need a Directory where you'll search for MP3 files.
Is it the root directory (i.e. search ALL the files in the device)? Use this answer.
Is it another directory? Pick one from this package.
Usage
final Directory dir = /* the directory you obtained in the last section */;
await search(dir).forEach((file) => print(file));

How to get files from selected folder with GtkFileChooserButton?

I am making a GTK+3 App with GJS where users select a folder from a GtkFileChooserButton (action property set to select-folder). I want to find all image files in the given folder the user have selected, so I can display one of the images.
I tried this._fileChooserButton.get_files() and this._folderChooseButton.get_uris() but they only return one file, which is the path to the selected folder. Like this:
_init(application) {
this._folderChooseButton.connect('file-set', () => {
this._onFolderChosen();
});
}
_onFolderChosen() {
let folder = this._folderChooseButton.get_file();
// somehow get files from the folder here
this._image.set_from_file(files[1]);
}
From the API it is not really clear to me, how do I find out which image files are inside the user's selected directory (and subdirectories)?
OK, after help from patrick, georges and matthias at guadec, here is what I got.
The get_file() function I tried returns a GFile, which in this case is a folder (in UNIX, folders are also files). In order to get the files within the directory path, we need to call enumerate_children_async() on our GFile, returned by the get_file() function.
The enumate_children_async() function takes five parameters:
A comma-separated attribute list. In our case, since we want the identifiers of the children in the directory, we want to use the attribute called standard::name.
FileQueryInfoFlag: This allows to either follow or not follow symbolic links. In this case, we will use FileQueryInfoFlag.NONE which will not follow symbolic links.
io_priority: How high priority the IO operation should have (we will use GLib.PRIORITY_DEFAULT)
cancellable: A cancellable, which is a way to cancel this operation, in this case we will leave it as null.
callback: This is the function/code you want to run in response to the files having been retreived.
More info on this function is at GJS-Docs at GNOME.org
The enumerate_children_async() function returns a GFileEnumerator, which we can use to retreive a number of the files, by calling next_files_async(), which takes these arguments:
num_files: How many files you want to retreive. In your case, we use 1.
io_priority and cancellable (same as above).
callback: Where we can run a function or code to actually retreive the file.
Below, is the final code for doing this.
const { Gio, GLib, GObject, Gtk } = imports.gi; // import Gio and GLib API at top of your document.
_onFolderChosen() {
let folder = this._folderChooseButton.get_file();
let files = folder.enumerate_children_async(
'standard::name',
Gio.FileQueryInfoFlags.NONE,
GLib.PRIORITY_DEFAULT,
null,
(source, result, data) => {
this._fileEnumerator = null;
try {
this._fileEnumerator = folder.enumerate_children_finish(result);
} catch (e) {
log('(Error) Could not retreive list of files! Error:' + e);
return;
}
this._readNextFile();
});
}
_readNextFile() {
if (!this._fileEnumerator)
return;
let fileInfo = null;
this._fileEnumerator.next_files_async(
1,
GLib.PRIORITY_DEFAULT,
null,
(source, result, data) => {
try {
fileInfo = this._fileEnumerator.next_files_finish(result);
} catch (e) {
log('Could not retreive the next file! Error:' + e);
return;
}
let file = fileInfo[0].get_name();
let filePath = GLib.build_filenamev([this._folderChooseButton.get_filename(), file]);
this._carousselImage.set_from_file(filePath);
});
}

How do I find the full directory for an IFile in Cake?

I'm writing a script to produce some artefacts from my build so I want to clean up unwanted files first. I'm using CleanDirectory(dirPath, predicate).
I'm finding it disturbingly hard to work out the directory for a file. If I use GetDirectoryName() that seems to just get me the immediate parent, not the full directory path.
Func<IFileSystemInfo, bool> predicate =
fileSystemInfo => {
// Dont filter out any directories
if (fileSystemInfo is IDirectory)
return false;
var path = fileSystemInfo.Path.FullPath;
var directory = ((DirectoryPath)path).GetDirectoryName();
...
}
Obviously I can use the .NET Framework System.IO classes to do this easily but then I get strings with the slashes in the wrong direction, and things do not smoothly inter-operate with Cake which uses POSIX paths.
OK I've worked out a solution. The key to IFileSystemInfo is to try and cast the Path to various derived types/interfaces, which then provide the functionality you are probably looking for. Example:
Func<IFileSystemInfo, bool> predicate =
fileSystemInfo => {
// Dont filter out any directories
if (fileSystemInfo is IDirectory)
return false;
// We can try and cast Path as an FilePath as know it's not a directory
var file = (FilePath) fileSystemInfo.Path;
if (file.FullPath.EndsWith("Help.xml", StringComparison.OrdinalIgnoreCase))
return false;
// GetDirectory() returns a Path of type DirectoryPath
var directory = file.GetDirectory().FullPath;
...
}

How to read a directory with using InputStream in eclipse plugin developement

I'm developing an eclipse plug-in and I need to traverse a directory and whole content of the directory. I found the method which reads a file in plug-in (bundleresource) as InputStream.
InputStream stream = Activator.class.getResourceAsStream("/dir1/dir2/file.ext");
this method works for files only. I need a way to read directories, list subdirectories and files like File.io.
Thanks.
Do you want to read a resource directory of your plugin? Otherwise you have to traverse a directory and open one stream per file:
String path = "c:\\temp\\";
File directory = new File(path);
if (directory.isDirectory()) {
String[] list = directory.list();
for (String entry : list) {
String absolutePath = path + entry;
System.out.println("processing " + absolutePath);
File file = new File(absolutePath);
if (file.isFile()) {
FileInputStream stream = new FileInputStream(file);
// use stream
stream.close();
}
}
}
If you want to traverse subdirectories as well you should wrap this into a recursive method, check if file is a directory and call the recursive method in this case.