Comments (7)
- a
Path
type in the standard library that makes sure no forbidden characters are used
Which characters are forbidden depends on the file system, or at least the operating system. It's not just characters, Windows disallows some file names too ("con", "nul", etc.).
If it can also depend on the file system, then there is no way to validate a Path
object without actually trying to resolve the path and see if it works. (Which it doesn't if it's for a file or directory that hasn't been created yet.)
But probably doable to some degree, there are just limits on what can be validated up-front.
Which is why using a String
has been working well so far.
(Actually, a file path is not a Dart string, it's more like a C-string, defined as a sequence of bytes, not Unicode characters.)
The package:path
API also uses strings as file paths. It originally tried something else, and using strings was found to be much more convenient.
- A Linter rule that forbade the creation of
FileSystemEntityType
directly and his sub-types.
The FileSystemEntityType
is a final
class with no public constructor, basically an enum
without the exhaustiveness, so you can't create instances directly, and there are no subtypes.
- A function that makes the gap between
Path
andFileSystemEntityType
in the standard library, like the following
That would be something like
FileSystemEntity fromPath(String path) =>
switch (FileStat.statSync(path).type) {
FileSystemEntityType.file => File(path),
FileSystemEntityType.directory => Directory(path),
FileSystemEntityType.link => Link(path),
FileSystemEntityType.notFound => throw ArgumentError.value(path, "path", "Not found"),
_ => throw UnsupportedError("Unknown type"),
};
from sdk.
@lrhn I'm curious what package:path
tried in the past and how close it was to what I proposed, and why they finally moved to String
, could you clarify?
Regarding the linter, I wasn't clear about what I meant.
I would like to force in the codebase the use of fromPath
and not use Directory(path)
, File(path)
, and Link(path)
directly because it's error-prone.
Is there any reason why fromPath
is not something you wouldn't add to the standard library?
from sdk.
import 'dart:io';
class Path {
final String value;
Path(this.value);
}
class PathNotFoundException implements Exception {
final String path;
final OSError osError;
PathNotFoundException(this.path, this.osError);
@override
String toString() => 'PathNotFoundException: Path "$path" not found (${osError.message})';
}
FileSystemEntity pathToFileSystemEntity(Path path) {
FileSystemEntityType type = FileSystemEntity.typeSync(path.value);
if (type == FileSystemEntityType.notFound) {
throw PathNotFoundException(path.value, const OSError());
}
switch (type) {
case FileSystemEntityType.directory:
return Directory(path.value);
case FileSystemEntityType.file:
return File(path.value);
case FileSystemEntityType.link:
return Link(path.value);
default:
throw StateError("Unknown type of FileSystemEntity");
}
}
from sdk.
as i am the beginner i dont know much used of the github but i can help you with this
We may implement this by using linter rule
we define the path
then use linter rule
convert that code
example:
void main() {
try {
Path myPath = Path('/valid/path/to/something');
FileSystemEntity entity = pathToFileSystemEntity(myPath);
print('Entity type: ${entity.runtimeType}');
} catch (e) {
print('Error: $e');
}
}
from sdk.
While fromPath
can work, it works equally well from a String
, and equally badly in that it cannot represent a non-existing file.
If you want to create a new file, you do var file = File(path); file.createSync();
or similar. The fromPath
function would throw for a non-existing file, so it can't be used here, which means you still need to use the File
and Directory
constructors, which makes a lint prohibiting those untenable.
The problem with file systems is that they are the source of truth about what exists and what does not, and it can change at any time while a program is running. Creating a Path
object that, somehow, validates that its context is syntactically valid, could potentially end up becoming invalid if another process mounts another file system with different valid symbols (say, someone mounts an ISO-9660 CD-ROM), or maybe it was rejected too soon if someone mounts an Ext3 file system on Windows. (I have no idea how the OSes actually handle that, maybe it will work fine.)
(Heck, creating a File
object, or getting a File
object back from Directory.list
, doesn't guarantee that that path actually still represents a file. It's more of a query/response object than representing the actual state of the file system.)
If the Path
validation allows any possibly valid (on any file system, anywhere), then it won't reject much of anything.
The trade-offs are generally always such that using strings is good enough, and any advantage you can get by introducing a Path
class is so minuscule that it doesn't carry its own weight.
A string being a path is more of a role than a type, and you can't know whether it will work any easier than just trying to use it as a path.
from sdk.
@lrhn I see what you mean when you say that File
and Directory
are query objects, they are not like file descriptors. I wasn't seeing them in that way.
I'm not sure why you would want to represent a non-existing file. If it is for checking its nonexistence, you will get the result with the exception, that it's like a fail open in other languages.
A string being a path is more of a role than a type
Do you think it's a bad design decision to create a type for a "role" ?
typedef Path = String;
(Obviously, Path can become much more complex and offer more guarantees and convenient member function)
from sdk.
The reason to represent a non-existing file would be to create it.
It's definitely a possibility to create a Path
type, probably an extension type on a String
value, with the operations of package:path
, and maybe more.
If the type implements String
, it can be used where a string is allowed, so it can be defined in any package, without changing existing APIs.
from sdk.
Related Issues (20)
- Improve `dart:developer` Timeline API HOT 1
- Even though the types match, the analyzer still reports a type mismatch, but there are no errors at runtime HOT 3
- [vm/core] Inlining `_GrowableList.add` bloats program too much HOT 4
- vm/dart/isolates/shared_primitives_test changing from flaky to RTE on vm-reload-linux-debug-x64 HOT 2
- [diagnostic] don't report `DUPLICATE_FIELD_NAME` if the name is invalid
- Refactoring to convert params/args between positional and named HOT 2
- Analyzer exception doesn't specify affected file HOT 3
- VM always prints "<isolate> has no debugger is attached and is paused"
- [dart2wasm] UnimplementedError when calling Flutter's Matrix4.translate with an integer argument HOT 2
- `where` can't accept an async predicate HOT 6
- [Augmentations] Wrong error in the analyzer when augmenting enum member
- [Augmentations] No error in the analyzer when augmenting a function type with no augmented type
- [Augmentations] No error in analyzer for mixin and extension when augmentation is before original declaration HOT 1
- [Augmentations] Analyzer crash on co19/LanguageFeatures/Augmentation-libraries/augmenting_types_A01_t01
- [Augmentations] Analyzer error when augmenting representation variable
- [Augmentations] Omitted type bound is not inherited
- [Augmentations] No error in the analyzer if augmentation declares a different return type HOT 2
- The integer negative zero formats as "-0.0" HOT 7
- [dart2js] bug in global inference with `call` getter HOT 1
- DevTools URI opens to a white screen
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from sdk.