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

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));

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.

Can flutter do scanning directories (recursive)?

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.

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;
...
}

Saving screenshots with protractor

I'm attempting to save a screenshot using a generic method in protractor. Two features, it creates the folder if it does not exist and it saves the file (with certain conditions).
export function WriteScreenShot(data: string, filename: string) {
let datetime = moment().format('YYYYMMDD-hhmmss');
filename = `../../../test-reports/${filename}.${datetime}.png`;
let path =filename.substring(0, filename.lastIndexOf('/'));
if (!fs.existsSync(path)) {
fs.mkdirSync(path);
}
let stream = fs.createWriteStream(filename);
stream.write(new Buffer(data, 'base64'));
stream.end();
}
This can be used by calling browser.takeScreenshot().then(png => WriteScreenShot(png, 'login/login-page')); Using this example call, a file will be created, I assumed, in the path relative where my WriteScreenShot method's file resides. But that does not appear to be the case.
For example, when I run my spec test in the spec's folder, the image gets saved in the correct place. But if I run it at the project root, an error is capture. Obviously, this has to do with my relative path reference. How do I capture the project's root directory and build from that so that I can run the test from any directory?
This is a classical directory access error. Let me just explain what is happening to your code -
let path =filename.substring(0, filename.lastIndexOf('/'));
The above line outputs to ../../../test-reports
fs.existsSync checks whether thispath exists or not -
case 1 :(postive flow) Your spec folder is in the same current working directory in which you are trying to create reports folder. When you run your test, the path exists, it generates the test-reports directory & screenshots and your code works fine.
case 2:(negative flow) When you try to run it from the root directory which is the current working directory now, fs.existsSync tries to check the path & the reports folder inside it. If it doesn't exist , fs.mkdirSync tries to create your directories but it would fail as it cannot create multiple directories.
You should be using native path module of nodejs to extract the path instead of using file substring and the mkdirp external module for creating multiple directories.
import * as path from 'path';
let {mkdirp} = require('mkdirp'); // npm i -D mkdirp
export function WriteScreenShot(data: string, filename: string) {
let datetime = moment().format('YYYYMMDD-hhmmss');
filename = `../../../test-reports/${filename}.${datetime}.png`;
let filePath = path.dirname(filename); // output: '../../..' (relative path)
// or
let filePath = path.resolve(__dirname); // output: 'your_root_dir_path' (absolute path)
// or
let filePath = path.resolve('.'); // output: 'your_root_dir_path' (absolute path)
if (!fs.existsSync(filePath )) {
mkdirp.sync(filePath); // creates multiple folders if they don't exist
}
let stream = fs.createWriteStream(filename);
stream.write(new Buffer(data, 'base64'));
stream.end();
}
If you are curious to know the difference btw mkdir & mkdir-p please read this SO thread.

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.