skip to Main Content

I use the Flutter_downloader package to download from the API and the file name contains spaces and special characters. For example, "abc ông @.text" will be changed to "abc____.text" when saving the file.

My code:

await FlutterDownloader.enqueue(
  url: url,
  savedDir: localPath,
  saveInPublicStorage: true,
  fileName: ""abc ông @.text");

I want to keep its filename as "abc ông @.text"

3

Answers


  1. From the package’s behavior, there is no direct way to change this behavior in the package itself.

    One possible workaround is to post-process the downloaded file and rename it to the desired filename. This can be done using the dart:io package’s File class, specifically the rename method.

    So you need to download it, get the path and rename it

    Here’s an example of how to do this:

    import 'dart:io';
    
    // Assume this is your downloaded file
    File downloadedFile = File('path_to_downloaded_file/abc____.text');
    
    // This is your desired filename
    String desiredFileName = fileUrl.split("/").last //i.e "abc ông @.text";
    
    // Rename the file
    downloadedFile.renameSync('path_to_downloaded_file/$desiredFileName');
    
    

    In this code, renameSync changes the name of the file at the given path, which should reflect your desired filename with spaces and special characters.

    Please note that you need to handle the case where a file with the same name already exists in the directory. The renameSync method will throw an exception in such a case. If you want to overwrite existing files, you can use renameSync in combination with deleteSync:

    if (File('path_to_downloaded_file/$desiredFileName').existsSync()) {
      File('path_to_downloaded_file/$desiredFileName').deleteSync();
    }
    
    downloadedFile.renameSync('path_to_downloaded_file/$desiredFileName');
    
    

    This code checks if a file with the desired name already exists, and if it does, deletes it before renaming the downloaded file.

    Login or Signup to reply.
  2. Looking inside the code of the Flutter Downloader package, you can see the following method:

    - (NSString *)sanitizeFilename:(nullable NSString *)filename {
        // Define a list of allowed characters for filenames
        NSMutableCharacterSet *allowedCharacters = [[NSMutableCharacterSet alloc] init];
    
        // Allow alphabetical characters (lowercase and uppercase)
        [allowedCharacters formUnionWithCharacterSet:[NSCharacterSet letterCharacterSet]];
    
        // Allow digits
        [allowedCharacters addCharactersInRange:NSMakeRange('0', 10)]; // ASCII digits
    
        // Allow additional characters: -_.()
        [allowedCharacters addCharactersInString:@"-_.()"];
    
        // Allow empty spaces
        [allowedCharacters addCharactersInString:@" "];
    
        // Remove the backslash (if you want to disallow it)
        [allowedCharacters removeCharactersInString:@"\"];
    
        // Now, you have a character set that allows the specified characters
        NSCharacterSet *finalCharacterSet = [allowedCharacters copy];
        if (filename == nil || [filename isEqual:[NSNull null]] || [filename isEqualToString:@""]) {
               NSString *defaultFilename = @"default_filename";
               return defaultFilename;
           }
        // Create a mutable string to build the sanitized filename
        NSMutableString *sanitizedFilename = [NSMutableString string];
        
        // Iterate over each character in the original filename
        for (NSUInteger i = 0; i < filename.length; i++) {
            unichar character = [filename characterAtIndex:i];
            
            // Check if the character is in the allowed set
            if ([allowedCharacters characterIsMember:character]) {
                // Append the allowed character to the sanitized filename
                [sanitizedFilename appendFormat:@"%C", character];
            } else {
                // Replace forbidden characters with an underscore
                [sanitizedFilename appendString:@"_"];
            }
        }
        
        // Ensure the sanitized filename is not empty
        if ([sanitizedFilename isEqualToString:@""]) {
            // Provide a default filename if the sanitized one is empty
            NSString *defaultFilename = @"default_filename";
            sanitizedFilename = [[NSMutableString alloc] initWithString:defaultFilename];
        }
        
        return sanitizedFilename;
    }
    

    As you can see, they have a method to sanitize the file name and this is why your special characters and spaces are replaced.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search