2

Let's say I get a directory listing of .jpg files and then want to display them

const fs = require('fs');
fs.readDirSync(someAbsolutePathToFolder)
    .filter(f => f.endsWith('.jpg'))
    .forEach(filename => {
        const img = new Image();
        const filepath  = path.join(someAbsolutePathToFolder, filename);
        img.src = `file://${filepath.replace(/\\/g, '/')}`;
        document.body.appendChild(img);
    });

This will fail. As just one example, if the listing I got had names like

#001-image.jpg
#002-image.jpg

the code above results in URLs like

file://some/path/#001-image.jpg

Which you can see is a problem. The URL will be cut at the #.

This answer claims I should be using encodeURI but that also fails as it leaves the # unescaped.

Using encodeURIComponent also does not work. It replaces / and : and space and Electron does not find the file, at least not on Windows.

Up until this point I had something like this

const filepath  = path.join(someAbsolutePathToFolder, filename).replace(/\\/g, '/');
img.src = `file://${filepath.split('/').map(encodeURIComponent).join('/')}`;

but that also fails on windows because drive letters get convert from c:\dir\file to c%3a\dir\file which then appears to be a relative path to electron.

So I have more special cases trying to check for [a-z]: at at the beginning of the path as well as \\ for UNC paths.

Today I ran into the # issue mentioned above and I'm expecting more time bombs are waiting for me so I'm asking...

What is the correct way to convert a filename to a URL in a cross platform way?

Or to be more specific, how to solve the problem above. Given a directory listing of absolute paths of image files on the local platform generate URLs that will load those images if assigned to the src property of an image.

gman
  • 100,619
  • 31
  • 269
  • 393

2 Answers2

1

You can use Node's (v10+) pathToFileURL:

import { pathToFileURL } from 'url';
const url = pathToFileURL('/some/path/#001-image.jpg');
img.src = url.href;

See: https://nodejs.org/api/url.html#url_url_pathtofileurl_path

Erik J
  • 342
  • 1
  • 11
-1

This works fine for me:

const open = require('open')
const path = require('path')

const FILE_NAME = 'картинка.jpg'
const filePath  = path.join(__dirname, FILE_NAME)
const fileUrl = `file:///${ filePath.split('\\').join('/') }`

console.log(fileUrl)
open(fileUrl)
Mark Minerov
  • 309
  • 1
  • 8
  • actually you don't need to encode your URL to open it locally, i have edited my answer – Mark Minerov Apr 01 '20 at 10:02
  • 1
    Thakns but that solution doesn't work as pointed out in the question. Be in Windows. Name the file `foo#bar.jpg`. Assign it to an image as specified in the question. – gman Apr 01 '20 at 12:11