diff --git a/components/CHANGELOG.md b/components/CHANGELOG.md
index 86561e42..9f9d0923 100644
--- a/components/CHANGELOG.md
+++ b/components/CHANGELOG.md
@@ -11,7 +11,6 @@ All Notable changes to `League\Uri\Components` will be documented in this file
 - `Modifier::prependQueryParameters` returns a modifier with prepend query paramters
 - `Modifier::when` conditional method to ease component building logic.
 - `Modifier::with*` method from the underlying `Uri` object are proxy to improve DX.
-- `Modifier::displayUriString` shows the URI in a human-readable format which may be an invalid URI.
 - `Query::decoded` the string representation of the component decoded.
 - `URLSearchParams::decoded` the string representation of the component decoded.
 - `tryNew` named constructor added to all components class to returns a new instance on success or `null` on failure.
diff --git a/components/Modifier.php b/components/Modifier.php
index fdd7fd19..1cc75091 100644
--- a/components/Modifier.php
+++ b/components/Modifier.php
@@ -23,7 +23,6 @@
 use League\Uri\Components\Host;
 use League\Uri\Components\Path;
 use League\Uri\Components\Query;
-use League\Uri\Components\UserInfo;
 use League\Uri\Contracts\Conditionable;
 use League\Uri\Contracts\PathInterface;
 use League\Uri\Contracts\UriAccess;
@@ -94,32 +93,6 @@ public function __toString(): string
         return $this->uri->__toString();
     }
 
-    public function displayUriString(): string
-    {
-        $userInfo = UserInfo::fromUri($this->uri);
-        $host = $this->uri->getHost();
-        if (null !== $host) {
-            $hostIp = self::ipv4Converter()->toDecimal($host);
-            $host = IdnConverter::toUnicode((string) IPv6Converter::compress(match (true) {
-                '' === $host,
-                null === $hostIp,
-                $host === $hostIp => $host,
-                default => $hostIp,
-            }))->domain();
-        }
-
-        return UriString::build([
-            'scheme' => $this->uri->getScheme(),
-            'user' => $userInfo->getUser(),
-            'pass' => $userInfo->getPass(),
-            'host' => $host,
-            'port' => $this->uri->getPort(),
-            'path' => Path::fromUri($this->uri)->withoutDotSegments()->decoded(),
-            'query' => Query::fromUri($this->uri)->decoded(),
-            'fragment' => Fragment::fromUri($this->uri)->decoded(),
-        ]);
-    }
-
     final public function __call(string $name, array $arguments): static
     {
         static $allowedMethods = [
diff --git a/components/ModifierTest.php b/components/ModifierTest.php
index 4aeb856f..b2eb581e 100644
--- a/components/ModifierTest.php
+++ b/components/ModifierTest.php
@@ -832,35 +832,6 @@ public function testItCanSlicePathSegments(): void
         self::assertSame('http://www.localhost.com/the/sky/', Modifier::from($uri)->sliceSegments(2, 2)->getUriString());
     }
 
-    #[DataProvider('idnUriProvider')]
-    public function testItReturnsTheCorrectUriString(string $expected, string $input): void
-    {
-        self::assertSame($expected, Modifier::from($input)->displayUriString());
-    }
-
-    public static function idnUriProvider(): iterable
-    {
-        yield 'basic uri stays the same' => [
-            'expected' => 'http://example.com/foo/bar',
-            'input' => 'http://example.com/foo/bar',
-        ];
-
-        yield 'idn host are changed' => [
-            'expected' => 'http://bébé.be',
-            'input' => 'http://xn--bb-bjab.be',
-        ];
-
-        yield 'idn host are the same' => [
-            'expected' => 'http://bébé.be',
-            'input' => 'http://bébé.be',
-        ];
-
-        yield 'the rest of the URI is not affected and uses RFC3986 rules' => [
-            'expected' => 'http://bébé.be?q=toto le héros',
-            'input' => 'http://bébé.be:80?q=toto%20le%20h%C3%A9ros',
-        ];
-    }
-
     #[DataProvider('ipv6NormalizationUriProvider')]
     public function testItCanExpandOrCompressTheHost(
         string $inputUri,
@@ -912,49 +883,4 @@ public function it_will_remove_empty_pairs_fix_issue_133(): void
         self::assertNull($removeEmptyPairs('https://a.b/c?=d'));
         self::assertNull($removeEmptyPairs('https://a.b/c?='));
     }
-
-    #[Test]
-    #[DataProvider('providesUriToDisplay')]
-    public function it_will_generate_the_display_uri_string(string $input, string $output): void
-    {
-        self::assertSame($output, Modifier::from($input)->displayUriString());
-    }
-
-    public static function providesUriToDisplay(): iterable
-    {
-        yield 'empty string' => [
-            'input' => '',
-            'output' => '',
-        ];
-
-        yield 'host IPv6' => [
-            'input' => 'https://[fe80:0000:0000:0000:0000:0000:0000:000a%25en1]/foo/bar',
-            'output' => 'https://[fe80::a%en1]/foo/bar',
-        ];
-
-        yield 'IPv6 gets expanded if needed' => [
-            'input' => 'http://bébé.be?q=toto%20le%20h%C3%A9ros',
-            'output' => 'http://bébé.be?q=toto le héros',
-        ];
-
-        yield 'complex URI' => [
-            'input' => 'https://xn--google.com/secret/../search?q=%F0%9F%8D%94',
-            'output' => 'https://䕮䕵䕶䕱.com/search?q=🍔',
-        ];
-
-        yield 'basic uri stays the same' => [
-            'input' => 'http://example.com/foo/bar',
-            'output' => 'http://example.com/foo/bar',
-        ];
-
-        yield 'idn host are changed' => [
-            'input' => 'http://xn--bb-bjab.be',
-            'output' => 'http://bébé.be',
-        ];
-
-        yield 'idn host are the same' => [
-            'input' => 'http://bébé.be',
-            'output' => 'http://bébé.be',
-        ];
-    }
 }
diff --git a/docs/uri/7.0/rfc3986.md b/docs/uri/7.0/rfc3986.md
index 71a5d295..900a0eb9 100644
--- a/docs/uri/7.0/rfc3986.md
+++ b/docs/uri/7.0/rfc3986.md
@@ -122,10 +122,6 @@ echo $uri->getPath();      //displays "/how/are/you"
 echo $uri->getQuery();     //displays "foo=baz"
 echo $uri->getFragment();  //displays "title"
 echo $uri->getOrigin();    //returns ''
-echo $uri->toString();
-//displays "http://foo:bar@www.example.com:81/how/are/you?foo=baz#title"
-echo json_encode($uri);
-//displays "http:\/\/foo:bar@www.example.com:81\/how\/are\/you?foo=baz#title"
 $uri->getComponents(); 
 // returns array {
 //   "scheme" => "http",
@@ -253,6 +249,32 @@ Uri::new('https://example.com/123')
 
 The method takes into account i18n while comparing both URI if the PHP's `idn_*` functions can be used.
 
+## URI string representation
+
+The `Uri` class handles URI according to RFC3986 as such you can retrieve its string representation using the
+`toString` method. But `URI` can have multiple string representation depending on its scheme or context. As
+such the package provides several other string representations:
+
+```php
+use League\Uri\Uri;
+
+$uri = Uri::new("http://foo:bar@www.example.com:81/how/are/you?foo=baz#title");
+
+echo $uri->toString(); //displays RFC3986 string representation
+echo $uri;             //displays RFC3986 string representation
+echo json_encode($uri); //display JSON encoded string representation
+
+/**
+ * NEW in version 7.6+
+ */
+
+echo $uri->toNormalizedString(); //displays the normalized URI string representation
+echo $uri->toDisplayString();    //displays the URI display representation
+echo $uri->toRfc8089String();    //display the string file representation according to RFC8089 or null if the scheme is not file
+echo $uri->toUnixPath();         //display the string path as a Unix Path or null if the scheme is not file
+echo $uri->toWindowsPath();      //display the string path as a Windows Path  or null if the scheme is not file
+```
+
 ## Modifying URI properties
 
 Use the modifying methods exposed by all URI instances to replace one of the URI component.
@@ -379,3 +401,4 @@ $uri->equals('eXAMPLE://a/./b/../b/%63/%7bfoo%7d', excludeFragment: false); // r
 
 In the last example the `equals` method took into account the URI `fragment` component. The `isSameDocument`
 follow closely RFC3986 and never takes into account the URI `fragment` component. 
+
diff --git a/interfaces/Contracts/UriInterface.php b/interfaces/Contracts/UriInterface.php
index 3b36ba13..0cfafe72 100644
--- a/interfaces/Contracts/UriInterface.php
+++ b/interfaces/Contracts/UriInterface.php
@@ -24,6 +24,9 @@
  *
  * @method string|null getUsername() returns the user component of the URI.
  * @method string|null getPassword() returns the scheme-specific information about how to gain authorization to access the resource.
+ * @method string|null toUnixPath() returns the Unix filesystem path. The method returns null for any other scheme
+ * @method string|null toWindowsPath() returns the Windows filesystem path. The method returns null for any other scheme
+ * @method string|null toRfc8089() returns a string representation of a File URI according to RFC8089. The method returns null for any other scheme
  * @method string toNormalizedString() returns the normalized string representation of the URI
  * @method array toComponents() returns an associative array containing all the URI components.
  * @method self normalize() returns a new URI instance with normalized components
diff --git a/uri/CHANGELOG.md b/uri/CHANGELOG.md
index 86e611d5..522155c1 100644
--- a/uri/CHANGELOG.md
+++ b/uri/CHANGELOG.md
@@ -23,6 +23,10 @@ All Notable changes to `League\Uri` will be documented in this file
 - `Uri::getOrigin`
 - `Uri::isSameOrigin`
 - `Uri::isCrossOrigin`
+- `Uri::todisplayString` shows the URI in a human-readable format which may be an invalid URI.
+- `Uri::toUnixPath` returns the URI path as a Unix Path or `null`
+- `Uri::toWindowsPath` returns the URI path as a Windows Path or `null`
+- `Uri::toRfc8089` return the URI in a RFC8089 formator `null`
 
 ### Fixed
 
diff --git a/uri/Uri.php b/uri/Uri.php
index a021b4bd..ee437ceb 100644
--- a/uri/Uri.php
+++ b/uri/Uri.php
@@ -1000,25 +1000,112 @@ private function isNonEmptyHostUriWithoutFragmentAndQuery(): bool
         return $this->isNonEmptyHostUri() && null === $this->fragment && null === $this->query;
     }
 
+    public function __toString(): string
+    {
+        return $this->toString();
+    }
+
+    public function jsonSerialize(): string
+    {
+        return $this->toString();
+    }
+
     public function toString(): string
     {
         return $this->uri;
     }
 
+    public function toNormalizedString(): string
+    {
+        return $this->normalize()->toString();
+    }
+
+    public function toDisplayString(): string
+    {
+        /** @var ComponentMap $components */
+        $components = array_map(
+            fn (?string $value): ?string => (null === $value || '' === $value) ? $value : rawurldecode($value),
+            $this->normalize()->toComponents()
+        );
+
+        if (null !== $components['host']) {
+            $components['host'] = IdnaConverter::toUnicode($components['host'])->domain();
+        }
+
+        if ('/' === $components['path'] && null !== $this->authority) {
+            $components['path'] = '';
+        }
+
+        return UriString::build($components);
+    }
+
     /**
-     * {@inheritDoc}
+     * Returns the Unix filesystem path.
+     *
+     * The method will return null if a scheme is present and is not the `file` scheme
      */
-    public function __toString(): string
+    public function toUnixPath(): ?string
     {
-        return $this->toString();
+        return match ($this->scheme) {
+            'file', null => rawurldecode($this->path),
+            default => null,
+        };
     }
 
     /**
-     * {@inheritDoc}
+     * Returns the Windows filesystem path.
+     *
+     * The method will return null if a scheme is present and is not the `file` scheme
      */
-    public function jsonSerialize(): string
+    public function toWindowsPath(): ?string
     {
-        return $this->toString();
+        static $regexpWindowsPath = ',^(?<root>[a-zA-Z]:),';
+
+        if (!in_array($this->scheme, ['file', null], true)) {
+            return null;
+        }
+
+        $originalPath = $this->path;
+        $path = $originalPath;
+        if ('/' === ($path[0] ?? '')) {
+            $path = substr($path, 1);
+        }
+
+        if (1 === preg_match($regexpWindowsPath, $path, $matches)) {
+            $root = $matches['root'];
+            $path = substr($path, strlen($root));
+
+            return $root.str_replace('/', '\\', rawurldecode($path));
+        }
+
+        $host = $this->host;
+
+        return match (null) {
+            $host => str_replace('/', '\\', rawurldecode($originalPath)),
+            default => '\\\\'.$host.'\\'.str_replace('/', '\\', rawurldecode($path)),
+        };
+    }
+
+    /**
+     * Returns a string representation of a File URI according to RFC8089.
+     *
+     * The method will return null if the URI scheme is not the `file` scheme
+     *
+     * @see https://datatracker.ietf.org/doc/html/rfc8089
+     */
+    public function toRfc8089(): ?string
+    {
+        $path = $this->path;
+
+        return match (true) {
+            'file' !== $this->scheme => null,
+            in_array($this->authority, ['', null, 'localhost'], true) => 'file:'.match (true) {
+                '' === $path,
+                '/' === $path[0] => $path,
+                default => '/'.$path,
+            },
+            default => $this->toString(),
+        };
     }
 
     /**
@@ -1408,11 +1495,6 @@ public function equals(UriInterface|Stringable|string $uri, bool $excludeFragmen
         };
     }
 
-    public function toNormalizedString(): string
-    {
-        return $this->normalize()->toString();
-    }
-
     /**
      * Tells whether the URI contains an Internationalized Domain Name (IDN).
      */
diff --git a/uri/UriTest.php b/uri/UriTest.php
index df2bd816..44564b62 100644
--- a/uri/UriTest.php
+++ b/uri/UriTest.php
@@ -11,12 +11,14 @@
 
 namespace League\Uri;
 
+use GuzzleHttp\Psr7\Utils;
 use League\Uri\Components\HierarchicalPath;
 use League\Uri\Components\Port;
 use League\Uri\Exceptions\SyntaxError;
 use PHPUnit\Framework\Attributes\CoversClass;
 use PHPUnit\Framework\Attributes\DataProvider;
 use PHPUnit\Framework\Attributes\Group;
+use PHPUnit\Framework\Attributes\Test;
 use PHPUnit\Framework\TestCase;
 use Psr\Http\Message\UriInterface as Psr7UriInterface;
 use TypeError;
@@ -792,4 +794,191 @@ public static function getCrossOriginExamples(): array
             'cross origin using a blob' => ['blob:http://mozilla.org:443/', 'https://mozilla.org/123', true],
         ];
     }
+
+    #[DataProvider('idnUriProvider')]
+    public function testItReturnsTheCorrectUriString(string $expected, string $input): void
+    {
+        self::assertSame($expected, Uri::new($input)->toDisplayString());
+    }
+
+    public static function idnUriProvider(): iterable
+    {
+        yield 'basic uri stays the same' => [
+            'expected' => 'http://example.com/foo/bar',
+            'input' => 'http://example.com/foo/bar',
+        ];
+
+        yield 'idn host are changed' => [
+            'expected' => 'http://bébé.be',
+            'input' => 'http://xn--bb-bjab.be',
+        ];
+
+        yield 'idn host are the same' => [
+            'expected' => 'http://bébé.be',
+            'input' => 'http://bébé.be',
+        ];
+
+        yield 'the rest of the URI is not affected and uses RFC3986 rules' => [
+            'expected' => 'http://bébé.be?q=toto le héros',
+            'input' => 'http://bébé.be:80?q=toto%20le%20h%C3%A9ros',
+        ];
+    }
+
+    #[DataProvider('unixpathProvider')]
+    public function testReturnsUnixPath(?string $expected, string $input): void
+    {
+        self::assertSame($expected, Uri::new($input)->toUnixPath());
+        self::assertSame($expected, Uri::new(Utils::uriFor($input))->toUnixPath());
+    }
+
+    public static function unixpathProvider(): array
+    {
+        return [
+            'relative path' => [
+                'expected' => 'path',
+                'input' => 'path',
+            ],
+            'absolute path' => [
+                'expected' => '/path',
+                'input' => 'file:///path',
+            ],
+            'path with empty char' => [
+                'expected' => '/path empty/bar',
+                'input' => 'file:///path%20empty/bar',
+            ],
+            'relative path with dot segments' => [
+                'expected' => 'path/./relative',
+                'input' => 'path/./relative',
+            ],
+            'absolute path with dot segments' => [
+                'expected' => '/path/./../relative',
+                'input' => 'file:///path/./../relative',
+            ],
+            'unsupported scheme' => [
+                'expected' => null,
+                'input' => 'http://example.com/foo/bar',
+            ],
+        ];
+    }
+
+    #[DataProvider('windowLocalPathProvider')]
+    public function testReturnsWindowsPath(?string $expected, string $input): void
+    {
+        self::assertSame($expected, Uri::new($input)->toWindowsPath());
+    }
+
+    public static function windowLocalPathProvider(): array
+    {
+        return [
+            'relative path' => [
+                'expected' => 'path',
+                'input' => 'path',
+            ],
+            'relative path with dot segments' => [
+                'expected' => 'path\.\relative',
+                'input' => 'path/./relative',
+            ],
+            'absolute path' => [
+                'expected' => 'c:\windows\My Documents 100%20\foo.txt',
+                'input' => 'file:///c:/windows/My%20Documents%20100%2520/foo.txt',
+            ],
+            'windows relative path' => [
+                'expected' => 'c:My Documents 100%20\foo.txt',
+                'input' => 'file:///c:My%20Documents%20100%2520/foo.txt',
+            ],
+            'absolute path with `|`' => [
+                'expected' => 'c:\windows\My Documents 100%20\foo.txt',
+                'input' => 'file:///c:/windows/My%20Documents%20100%2520/foo.txt',
+            ],
+            'windows relative path with `|`' => [
+                'expected' => 'c:My Documents 100%20\foo.txt',
+                'input' => 'file:///c:My%20Documents%20100%2520/foo.txt',
+            ],
+            'absolute path with dot segments' => [
+                'expected' => '\path\.\..\relative',
+                'input' => '/path/./../relative',
+            ],
+            'absolute UNC path' => [
+                'expected' => '\\\\server\share\My Documents 100%20\foo.txt',
+                'input' => 'file://server/share/My%20Documents%20100%2520/foo.txt',
+            ],
+            'unsupported scheme' => [
+                'expected' => null,
+                'input' => 'http://example.com/foo/bar',
+            ],
+        ];
+    }
+
+    #[DataProvider('rfc8089UriProvider')]
+    public function testReturnsRFC8089UriString(?string $expected, string $input): void
+    {
+        self::assertSame($expected, Uri::new($input)->toRfc8089());
+    }
+
+    public static function rfc8089UriProvider(): iterable
+    {
+        return [
+            'localhost' => [
+                'expected' => 'file:/etc/fstab',
+                'input' => 'file://localhost/etc/fstab',
+            ],
+            'empty authority' => [
+                'expected' => 'file:/etc/fstab',
+                'input' => 'file:///etc/fstab',
+            ],
+            'file with authority' => [
+                'expected' => 'file://yesman/etc/fstab',
+                'input' => 'file://yesman/etc/fstab',
+            ],
+            'invalid scheme' => [
+                'expected' => null,
+                'input' => 'foobar://yesman/etc/fstab',
+            ],
+        ];
+    }
+
+    #[Test]
+    #[DataProvider('providesUriToDisplay')]
+    public function it_will_generate_the_display_uri_string(string $input, string $output): void
+    {
+        self::assertSame($output, Uri::new($input)->toDisplayString());
+    }
+
+    public static function providesUriToDisplay(): iterable
+    {
+        yield 'empty string' => [
+            'input' => '',
+            'output' => '',
+        ];
+
+        yield 'host IPv6' => [
+            'input' => 'https://[fe80:0000:0000:0000:0000:0000:0000:000a%25en1]/foo/bar',
+            'output' => 'https://[fe80::a%en1]/foo/bar',
+        ];
+
+        yield 'IPv6 gets expanded if needed' => [
+            'input' => 'http://bébé.be?q=toto%20le%20h%C3%A9ros',
+            'output' => 'http://bébé.be?q=toto le héros',
+        ];
+
+        yield 'complex URI' => [
+            'input' => 'https://xn--google.com/secret/../search?q=%F0%9F%8D%94',
+            'output' => 'https://䕮䕵䕶䕱.com/search?q=🍔',
+        ];
+
+        yield 'basic uri stays the same' => [
+            'input' => 'http://example.com/foo/bar',
+            'output' => 'http://example.com/foo/bar',
+        ];
+
+        yield 'idn host are changed' => [
+            'input' => 'http://xn--bb-bjab.be',
+            'output' => 'http://bébé.be',
+        ];
+
+        yield 'idn host are the same' => [
+            'input' => 'http://bébé.be',
+            'output' => 'http://bébé.be',
+        ];
+    }
 }