I want to load all the image file names in images/pets/ to List<String> animals. How can I do that?
path_provider you can get the directory the temp and appDir directory
final directory = await getApplicationDocumentsDirectory();
String imagesDirectory = directory + "/images/pets/";
After you can use the listSync method to find files of this Directory
final myDir = new Directory(imagesDirectory);
List<FileSystemEntity> _images;
_images = myDir.listSync(recursive: true, followLinks: false);
I hope that I have helped in some way
Flutter generates a file called AssetManifest.json which you can read up through the default bundle the same way you would read a normal text file from the assets.
var manifestContent = DefaultAssetBundle.of(context).loadString('AssetManifest.json');
Read and parse this file and then create a list from all the properties you need with their paths. Just double check to make sure you have the correct path, this can change in the future. It seems to me like a placeholder.
Pseudo-code for reading AssetManifest.json
var manifestContent = DefaultAssetBundle.of(context).loadString('AssetManifest.json');
var manifestMap = json.decode(manifestContent);
var imagePetPaths = manifestMap.keys.where((key) => key.contains('images/pets/'));
// You can either use the keys and fetch the value from the map,
or just use the key value since it's the same as the one in the pubspec.yaml
Continuing from AdsHan's Answer
final dir = await getApplicationDocumentsDirectory();
final imagesDirectory = Directory(dir.path + "/images/pets/");
List<String> images = [];
final _imagesFile = imagesDirectory.listSync(followLinks: false, recursive: true);
_imagesFile.forEach((img) {
String imgString = img.toString().substring(
img.toString().lastIndexOf('/') + 1,
img.toString().length);
images.add(imgString);
});
Related
I am trying to create a Word file and download the created file in clients browser.
The creation part seems to work fine and I can open the file manually from its Folder.
But the downloaded file in browser does not open correctly and produces an error
"The file is corrupt and cannot be opened"
I am using the code from here
Microsoft instructions for downloading a file in Blazor
My code seems like this
private async Task CreateAndDownloadWordFile()
{
var destination = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
var fileName = destination + "\\test12.docx";
//SpreadsheetDocument spreadsheetDocument = SpreadsheetDocument.Create(destination, SpreadsheetDocumentType.Workbook);
using (WordprocessingDocument doc = WordprocessingDocument.Create
(fileName, DocumentFormat.OpenXml.WordprocessingDocumentType.Document))
{
// Add a main document part.
MainDocumentPart mainPart = doc.AddMainDocumentPart();
// Create the document structure and add some text.
mainPart.Document = new Document();
Body body = mainPart.Document.AppendChild(new Body());
Paragraph para = body.AppendChild(new Paragraph());
Run run = para.AppendChild(new Run());
// String msg contains the text, "Hello, Word!"
run.AppendChild(new Text("New text in document"));
}
var fileStream = GetFileStream();
using var streamRef = new DotNetStreamReference(stream: fileStream);
await JS.InvokeVoidAsync("downloadFileFromStream", fileName, streamRef);
}
private Stream GetFileStream()
{
var randomBinaryData = new byte[50 * 1024];
var fileStream = new MemoryStream(randomBinaryData);
return fileStream;
}
And I use this Javascript code
async function downloadFileFromStream(fileName, contentStreamReference) {
const arrayBuffer = await contentStreamReference.arrayBuffer();
const blob = new Blob([arrayBuffer]);
const url = URL.createObjectURL(blob);
triggerFileDownload(fileName, url);
URL.revokeObjectURL(url);
}
function triggerFileDownload(fileName, url) {
const anchorElement = document.createElement('a');
anchorElement.href = url;
anchorElement.download = fileName ?? '';
anchorElement.click();
anchorElement.remove();
}
Any ideas?
But the downloaded file in browser does not open correctly
That is probably because you
First create a Word document
And then download var randomBinaryData = new byte[50 * 1024];
the downloaded file in browser
Check those. Are they exactly 50 * 1024 bytes ?
--
Also, you shouldn't pass the full C:\... path to the download funtion.
var fileStream = File.OpenRead(filename);
using var streamRef = new DotNetStreamReference(stream: fileStream);
//await JS.InvokeVoidAsync("downloadFileFromStream", fileName, streamRef);
await JS.InvokeVoidAsync("downloadFileFromStream", "suggestedName", streamRef);
I have a bunch of xml files in assets folder, I add path to pubspec.yaml and path looks like this 'assets/data/somename.xml' I need to get data from them and this is the way how i got it now
List filePathList = ['assets/data/widow.xml','assets/data/door.xml'];
for(int i = 0;i<filePathList.length;i++){
var xmlFile = XmlDocument.parse(await rootBundle.loadString(filePathList[i]));
checkListtemplateXmlList.add(xmlFile);
}
How you can see i use realy bad way to take data from files,
there will be many more xml files in the future so i need some solution to this problem to not add path in filePathList for every file in assets folder.
Also i made a loadData function that load all files like i want, but my json files are in directory that i got with using getApplicationDocumentDirectory class. There is a code
static Future<void> loadData() async {
final dir = await getApplicationDocumentsDirectory();
List<FileSystemEntity> files = await dir.list().toList();
for (int i = 0; i < files.length; i++) {
String filepath = files[i].path;
File newFile = File(filepath);
String name = p.basenameWithoutExtension(newFile.path);
String myExtension = p.extension(filepath);
if(myExtension != '.json'){
} else{
checkLists.add(CheckList(name));
}
}
for(int i = 0;i< checkLists.length;i++){
await checkLists[i].readFile();
}
}
how i can do something like this in my getXmlData function
Inside the pubspec define only the folder:
assets:
- assets/data/
This will "load" all files inside the data folder.
And using this code:
// This will give a list of all files inside the `assets`.
var assets = await rootBundle.loadString('AssetManifest.json');
And use a filter to get all xml files.
Map json = json.decode(assets);
List get = json.keys.where((element) => element.endsWith(".xml")).toList();
I'm having a couple of tables in a particular database and so i was hoping to get the size of the database when the data is dumped into the particular tables.
This is how i tried
var db = await openDatabase('dummy.db');
int count = Sqflite.firstIntValue(await db.rawQuery('SELECT COUNT(*) FROM dummyTable1'));
I know this approach is wrong since I'm getting only the number of rows in the particular table but how to get the size of the particular table?
Something like this will tell you the size of your db
final databasesPath = await getDatabasesPath();
String path = join(databasesPath, 'dummy.db');
final file = File(path);
Now you can get the file size with
final size = file.lengthSync();
or
final size = await file.length();
or alternatively if flutter db support it, you can have a look here:
https://www.sqlite.org/pragma.html#pragma_page_count
I am using this piece of code to create a SecondaryTile.
public static async Task<bool> PinToStartAsync(Playlist playlist, bool isPlaylist)
{
var tilename = playlist.Name;
var tileid = Uri.EscapeDataString(isPlaylist ? tilename : $"{tilename}+++{playlist.Artist}");
var filename = Uri.EscapeDataString(tilename);
var path = LogoPath;
if (playlist.DisplayItem.Source != null && await (await GetSecondaryTileFolder()).TryGetItemAsync(filename) == null)
{
await (await GetStorageItemThumbnailAsync(playlist.DisplayItem.Source.Path)).SaveAsync(SecondaryTileFolder, filename);
path = $"ms-appdata:///local/SecondaryTiles/{filename}.png";
}
var tile = new SecondaryTile(tileid, tilename, isPlaylist.ToString(), new Uri(path), TileSize.Default);
tile.VisualElements.ShowNameOnSquare150x150Logo = tile.VisualElements.ShowNameOnSquare310x310Logo = tile.VisualElements.ShowNameOnWide310x150Logo = true;
if (SecondaryTile.Exists(tilename)) await tile.RequestDeleteAsync();
else await tile.RequestCreateAsync();
return SecondaryTile.Exists(tilename);
}
This piece of code works fine when the playlist name is like 123 or helloworld. However, when I use unicode in the tilename, it causes problem.
Below is an image of SecondaryTiles that I created. The name of first two has some unicode characters.
So it is not able to display the Thumbnail I stored locally, even though I created those images successfully.
Another problem with unicode character is that, the SecondaryTile.Exists(tilename) will always return false.
I have noticed the problem with unicode so I added Uri.EscapeDataString to tileid and filename so that they are uri safe. However, I do want my tiles to have names with unicode characters.
How should I allow unicode characters in tilename?
---Code Update---
public static async Task<bool> PinToStartAsync(Playlist playlist, bool isPlaylist)
{
var tilename = playlist.Name;
var tileid = WebUtility.UrlEncode(isPlaylist ? tilename : $"{tilename}+++{playlist.Artist}");
var filename = tileid + ".png";
var path = DefaultAlbumCoverPath;
if (playlist.DisplayItem.Source != null && !await (await GetSecondaryTileFolder()).Contains(filename))
{
await (await GetStorageItemThumbnailAsync(playlist.DisplayItem.Source.Path)).SaveAsync(SecondaryTileFolder, tileid);
path = $"ms-appdata:///local/SecondaryTiles/" + filename;
}
var tile = new SecondaryTile(tileid, tilename, isPlaylist.ToString(), new Uri(path), TileSize.Default);
tile.VisualElements.ShowNameOnSquare150x150Logo = tile.VisualElements.ShowNameOnSquare310x310Logo = tile.VisualElements.ShowNameOnWide310x150Logo = true;
if (SecondaryTile.Exists(tileid)) await tile.RequestDeleteAsync();
else await tile.RequestCreateAsync();
return SecondaryTile.Exists(tileid);
}
Since the SecondaryTile accesses the image through the path, the entire URI must be path-safe, which is a prerequisite for the software to successfully access the image.
From this perspective, there is nothing wrong with your handling.
In fact, these images are stored in the application's local storage and are not publicly available. The name doesn't need to be concerned.
But you can translate the image name via `Uri.UnescapeDataString()` when exporting these images or you want to get its name.
Update
As you can see from the picture you gave, the tile can display Chinese text (although it is illegible because it is white background + white text), so your question appears on the image.
You don't have to use Uri.EscapeDataString to change the file name, which will exceed the limit when converting long filenames.
You can save the image as the original name, but you can use the following methods when using the link:
string imagePath = $"ms-appdata:///local/SecondaryTiles/{WebUtility.UrlEncode("测试图片")}.png";
Using WebUtility.UrlEncode() in the link can solve this problem well, and the image will be recognized normally.
Another problem with unicode character is that, the SecondaryTile.Exists(tilename) will always return false.
This has nothing to do with Unicode, the main problem is your code:
if (SecondaryTile.Exists(tilename))
await tile.RequestDeleteAsync();
else
await tile.RequestCreateAsync();
Your code has a key problem. When it detects the Tile with the same id, it only deletes it, but does not create a new Tile, so it naturally returns false when it detects.
Best regards.
I need to download an image with GS and save it in a specific drive folder.
I'm able to save the image in the root folder but i cannot save it in a specific folder:
function downloadFile(fileURL,folder) {
var fileName = "";
var fileSize = 0;
var response = UrlFetchApp.fetch(fileURL, {muteHttpExceptions: true});
var rc = response.getResponseCode();
if (rc == 200) {
var fileBlob = response.getBlob()
var folder = DriveApp.getFoldersByName(folder);
if (folder != null) {
var file = DriveApp.createFile(fileBlob);
fileName = file.getName();
fileSize = file.getSize();
}
}
var fileInfo = { "rc":rc, "fileName":fileName, "fileSize":fileSize };
return fileInfo;
}
Question: what have I to add to use the variable "folder"?
I found a lot of examples with "DocList" Class that is not in use anymore
Many thanks
Well, I guess GAS has make a lot of progress on developing its API, the function
createFile(blob) of an object Folder will do the job:
https://developers.google.com/apps-script/reference/drive/folder#createfileblob
// Create an image file in Google Drive using the Maps service.
var blob = Maps.newStaticMap().setCenter('76 9th Avenue, New York NY').getBlob();
DriveApp.getRootFolder().createFile(blob);
It's quite late for the answer but just incase some one runs into the situation.
Are you familiar with this app? It does exactly what you're asking for.
However, if you want to re-create this for your own purposes, I would change your declaration of variable file to read as such:
var file = folder.next().createFile(fileBlob);
when you create your variable folder, the method you use creates a FolderIterator, not a single folder. You have to call the next() method to get a Folder object.
To be precise with your script and avoid saving to an incorrect-but-similarly-named folder, I would recommend passing the folder ID to your script rather than the folder Name. If you pass the folder ID, you could declare folder as:
var folder = DriveApp.getFolderById(folder);
and then continue the script as you have it written. I hope that helps.
Working on similar problem, I came up with the solution below to save a file to a folder. If the folder doesn't exist it creates it, otherwise it saves the file specified by "FOLDER_NAME"
var folderExists = checkFolderExists("FOLDER_NAME");
if (folderExists) {
saveFolder = DriveApp.getFolderById(folderExists);
} else {
saveFolder = DriveApp.createFolder("FOLDER_NAME");
}
// Make a copy of the file in the root drive.
var file = DriveApp.getFileById(sheetID);
// Take the copy of the file created above and move it into the folder:
var newFile = DriveApp.getFolderById(saveFolder.getId()).addFile(file);
// Remove the copy of the file in the root drive.
var docfile = file.getParents().next().removeFile(file);
Further to Eric's answer, I have also provided a utility function that checks if the folder exists. It's reusable in any project.
function checkFolderExists(fName) {
try {
var folderId;
var folders = DriveApp.getFolders();
while (folders.hasNext()) {
var folder = folders.next();
folderName = folder.getName();
if (folderName == fName) {
folderId = folder.getId();
}
}
} catch(e) {
log("Services::checkFolderExists()" + e.toString());
throw e;
}
return folderId;
}