Node: `fs.fileReadSync` doesn't understand `file://` URL strings

Created on 27 Apr 2018  路  6Comments  路  Source: nodejs/node

  • Version: 10.0.0
  • Platform: Darwin dionysus.local 17.5.0 Darwin Kernel Version 17.5.0: Mon Mar 5 22:24:32 PST 2018; root:xnu-4570.51.1~1/RELEASE_X86_64 x86_64
  • Subsystem: fs

Description

Assume /tmp/foo.txt exist. Reading the file with fs.fileReadSync('/tmp/foo.txt') works as expected, but using fs.fileReadSync('file:///tmp/foo.txt') fails to read the file.

Why it matters

I need to read files relative to the current file, but __dirname/__filename are not available when parsing modules. I can compute __dirname with import.meta.url by passing it to path.dirname, but the path is still prefixed with file://.

duplicate fs

Most helpful comment

I don't remember why it's the case, but I think it is intended that fs methods don't accept URL strings. /cc @jasnell

What you can do instead is create an URL object like so:

const url = new URL(import.meta.url);
fs.readFileSync(url)

All 6 comments

I don't remember why it's the case, but I think it is intended that fs methods don't accept URL strings. /cc @jasnell

What you can do instead is create an URL object like so:

const url = new URL(import.meta.url);
fs.readFileSync(url)

Yep, this is intentional. The reason is because it would be a non-compatible breaking change and would introduce a non-trivial performance regression even for the common cases.

Duplicate of #17658.

Any reason why import.meta.url.replace('file://', '') would not work?

@neroux You need some extra handling for URL percent encoding. Generally, some weirdnesses around encoded / characters need to be taken care of with file: URLs, but because import.meta.url can be trusted to always represent a valid file path that's not necessary. Additionally, on Windows one would need to also handle UNC paths which may have punycode-encoded hostnames.

See following, which is our implementation of a general purpose URL-to-file path converter https://github.com/nodejs/node/blob/b55a11d1b17b3e4b9650ef8e7b4e57ef83dc441d/lib/internal/url.js#L1335-L1386

@TimothyGu Good points, I guess I focused too much on the provided example :)
Thanks.

targos' URL solution does sound like the right approach in that case.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

Brekmister picture Brekmister  路  3Comments

loretoparisi picture loretoparisi  路  3Comments

vsemozhetbyt picture vsemozhetbyt  路  3Comments

willnwhite picture willnwhite  路  3Comments

Icemic picture Icemic  路  3Comments