| OLD | NEW |
| 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 part of dart.io; | 5 part of dart.io; |
| 6 | 6 |
| 7 class FileSystemEntityType { | 7 class FileSystemEntityType { |
| 8 static const FILE = const FileSystemEntityType._internal(0); | 8 static const FILE = const FileSystemEntityType._internal(0); |
| 9 static const DIRECTORY = const FileSystemEntityType._internal(1); | 9 static const DIRECTORY = const FileSystemEntityType._internal(1); |
| 10 static const LINK = const FileSystemEntityType._internal(2); | 10 static const LINK = const FileSystemEntityType._internal(2); |
| (...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 161 * | 161 * |
| 162 * [FileSystemEntity] objects are returned from directory listing | 162 * [FileSystemEntity] objects are returned from directory listing |
| 163 * operations. To determine if a FileSystemEntity is a [File] or a | 163 * operations. To determine if a FileSystemEntity is a [File] or a |
| 164 * [Directory], perform a type check: | 164 * [Directory], perform a type check: |
| 165 * | 165 * |
| 166 * if (entity is File) (entity as File).readAsStringSync(); | 166 * if (entity is File) (entity as File).readAsStringSync(); |
| 167 */ | 167 */ |
| 168 abstract class FileSystemEntity { | 168 abstract class FileSystemEntity { |
| 169 String get path; | 169 String get path; |
| 170 | 170 |
| 171 external static _getType(String path, bool followLinks); | |
| 172 external static _identical(String path1, String path2); | |
| 173 | |
| 174 static int _getTypeSync(String path, bool followLinks) { | |
| 175 var result = _getType(path, followLinks); | |
| 176 _throwIfError(result, 'Error getting type of FileSystemEntity'); | |
| 177 return result; | |
| 178 } | |
| 179 | |
| 180 static Future<int> _getTypeAsync(String path, bool followLinks) { | |
| 181 // Get a new file service port for each request. We could also cache one. | |
| 182 var service = _FileUtils._newServicePort(); | |
| 183 List request = new List(3); | |
| 184 request[0] = _TYPE_REQUEST; | |
| 185 request[1] = path; | |
| 186 request[2] = followLinks; | |
| 187 return service.call(request).then((response) { | |
| 188 if (_isErrorResponse(response)) { | |
| 189 throw _exceptionFromResponse(response, "Error getting type", path); | |
| 190 } | |
| 191 return response; | |
| 192 }); | |
| 193 } | |
| 194 | |
| 195 /** | |
| 196 * Synchronously checks whether two paths refer to the same object in the | |
| 197 * file system. Returns a [:Future<bool>:] that completes with the result. | |
| 198 * | |
| 199 * Comparing a link to its target returns false, as does comparing two links | |
| 200 * that point to the same target. To check the target of a link, use | |
| 201 * Link.target explicitly to fetch it. Directory links appearing | |
| 202 * inside a path are followed, though, to find the file system object. | |
| 203 * | |
| 204 * Completes the returned Future with an error if one of the paths points | |
| 205 * to an object that does not exist. | |
| 206 */ | |
| 207 static Future<bool> identical(String path1, String path2) { | |
| 208 // Get a new file service port for each request. We could also cache one. | |
| 209 var service = _FileUtils._newServicePort(); | |
| 210 List request = new List(3); | |
| 211 request[0] = _IDENTICAL_REQUEST; | |
| 212 request[1] = path1; | |
| 213 request[2] = path2; | |
| 214 return service.call(request).then((response) { | |
| 215 if (_isErrorResponse(response)) { | |
| 216 throw _exceptionFromResponse(response, | |
| 217 "Error in FileSystemEntity.identical($path1, $path2)", ""); | |
| 218 } | |
| 219 return response; | |
| 220 }); | |
| 221 } | |
| 222 | |
| 223 | |
| 224 /** | |
| 225 * Synchronously checks whether two paths refer to the same object in the | |
| 226 * file system. | |
| 227 * | |
| 228 * Comparing a link to its target returns false, as does comparing two links | |
| 229 * that point to the same target. To check the target of a link, use | |
| 230 * Link.target explicitly to fetch it. Directory links appearing | |
| 231 * inside a path are followed, though, to find the file system object. | |
| 232 * | |
| 233 * Throws an error if one of the paths points to an object that does not | |
| 234 * exist. | |
| 235 */ | |
| 236 static bool identicalSync(String path1, String path2) { | |
| 237 var result = _identical(path1, path2); | |
| 238 _throwIfError(result, 'Error in FileSystemEntity.identicalSync'); | |
| 239 return result; | |
| 240 } | |
| 241 | |
| 242 /** | 171 /** |
| 243 * Checks whether the file system entity with this path exists. Returns | 172 * Checks whether the file system entity with this path exists. Returns |
| 244 * a [:Future<bool>:] that completes with the result. | 173 * a [:Future<bool>:] that completes with the result. |
| 245 * | 174 * |
| 246 * Since FileSystemEntity is abstract, every FileSystemEntity object | 175 * Since FileSystemEntity is abstract, every FileSystemEntity object |
| 247 * is actually an instance of one of the subclasses [File], | 176 * is actually an instance of one of the subclasses [File], |
| 248 * [Directory], and [Link]. Calling [exists] on an instance of one | 177 * [Directory], and [Link]. Calling [exists] on an instance of one |
| 249 * of these subclasses checks whether the object exists in the file | 178 * of these subclasses checks whether the object exists in the file |
| 250 * system object exists and is of the correct type (file, directory, | 179 * system object exists and is of the correct type (file, directory, |
| 251 * or link). To check whether a path points to an object on the | 180 * or link). To check whether a path points to an object on the |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 309 * [path] of this [FileSystemEntity]. | 238 * [path] of this [FileSystemEntity]. |
| 310 * Identical to [:FileStat.statSync(this.path):]. | 239 * Identical to [:FileStat.statSync(this.path):]. |
| 311 * | 240 * |
| 312 * Returns a [FileStat] object containing the data returned by stat(). | 241 * Returns a [FileStat] object containing the data returned by stat(). |
| 313 * | 242 * |
| 314 * If the call fails, returns a [FileStat] object with .type set to | 243 * If the call fails, returns a [FileStat] object with .type set to |
| 315 * FileSystemEntityType.NOT_FOUND and the other fields invalid. | 244 * FileSystemEntityType.NOT_FOUND and the other fields invalid. |
| 316 */ | 245 */ |
| 317 FileStat statSync(); | 246 FileStat statSync(); |
| 318 | 247 |
| 248 /** |
| 249 * Deletes this [FileSystemEntity]. |
| 250 * |
| 251 * If the [FileSystemEntity] is a directory, and if [recursive] is false, |
| 252 * the directory must be empty. Otherwise, if [recursive] is true, the |
| 253 * directory and all sub-directories and files in the directories are |
| 254 * deleted. Links are not followed when deleting recursively. Only the link |
| 255 * is deleted, not its target. |
| 256 * |
| 257 * If [recursive] is true, the [FileSystemEntity] is deleted even if the type |
| 258 * of the [FileSystemEntity] doesn't match the content of the file system. |
| 259 * This behavior allows [delete] to be used to unconditionally delete any file |
| 260 * system object. |
| 261 * |
| 262 * Returns a [:Future<FileSystemEntity>:] that completes with this |
| 263 * [FileSystemEntity] when the deletion is done. If the [FileSystemEntity] |
| 264 * cannot be deleted, the future completes with an exception. |
| 265 */ |
| 266 Future<FileSystemEntity> delete({recursive: false}) |
| 267 => _delete(recursive: recursive); |
| 268 |
| 269 /** |
| 270 * Synchronously deletes this [FileSystemEntity]. |
| 271 * |
| 272 * If the [FileSystemEntity] is a directory, and if [recursive] is false, |
| 273 * the directory must be empty. Otherwise, if [recursive] is true, the |
| 274 * directory and all sub-directories and files in the directories are |
| 275 * deleted. Links are not followed when deleting recursively. Only the link |
| 276 * is deleted, not its target. |
| 277 * |
| 278 * If [recursive] is true, the [FileSystemEntity] is deleted even if the type |
| 279 * of the [FileSystemEntity] doesn't match the content of the file system. |
| 280 * This behavior allows [deleteSync] to be used to unconditionally delete any |
| 281 * file system object. |
| 282 * |
| 283 * Throws an exception if the [FileSystemEntity] cannot be deleted. |
| 284 */ |
| 285 void deleteSync({recursive: false}) |
| 286 => _deleteSync(recursive: recursive); |
| 319 | 287 |
| 320 | 288 |
| 321 /** | 289 /** |
| 322 * Start watch the [FileSystemEntity] for changes. | 290 * Start watch the [FileSystemEntity] for changes. |
| 323 * | 291 * |
| 324 * The implementation uses platform-depending event-based APIs for receiving | 292 * The implementation uses platform-depending event-based APIs for receiving |
| 325 * file-system notifixations, thus behvaiour depends on the platform. | 293 * file-system notifixations, thus behvaiour depends on the platform. |
| 326 * | 294 * |
| 327 * * `Windows`: Uses `ReadDirectoryChangesW`. The implementation supports | 295 * * `Windows`: Uses `ReadDirectoryChangesW`. The implementation supports |
| 328 * only watching dirctories but supports recursive watching. | 296 * only watching dirctories but supports recursive watching. |
| 329 * * `Linux`: Uses `inotify`. The implementation supports watching both | 297 * * `Linux`: Uses `inotify`. The implementation supports watching both |
| 330 * files and dirctories, but doesn't support recursive watching. | 298 * files and dirctories, but doesn't support recursive watching. |
| 331 * * `Mac OS`: Uses `FSEvents`. The implementation supports watching both | 299 * * `Mac OS`: Uses `FSEvents`. The implementation supports watching both |
| 332 * files and dirctories, and also recursive watching. Note that FSEvents | 300 * files and dirctories, and also recursive watching. Note that FSEvents |
| 333 * always use recursion internally, so when disabled, some events are | 301 * always use recursion internally, so when disabled, some events are |
| 334 * ignored. | 302 * ignored. |
| 335 * | 303 * |
| 336 * The system will start listen for events once the returned [Stream] is | 304 * The system will start listen for events once the returned [Stream] is |
| 337 * being listened to, not when the call to [watch] is issued. Note that the | 305 * being listened to, not when the call to [watch] is issued. Note that the |
| 338 * returned [Stream] is endless. To stop the [Stream], simply cancel the | 306 * returned [Stream] is endless. To stop the [Stream], simply cancel the |
| 339 * subscription. | 307 * subscription. |
| 340 */ | 308 */ |
| 341 Stream<FileSystemEvent> watch({int events: FileSystemEvent.ALL, | 309 Stream<FileSystemEvent> watch({int events: FileSystemEvent.ALL, |
| 342 bool recursive: false}) | 310 bool recursive: false}) |
| 343 => new _FileSystemWatcher(_trimTrailingPathSeparators(path), | 311 => new _FileSystemWatcher(_trimTrailingPathSeparators(path), |
| 344 events, | 312 events, |
| 345 recursive).stream; | 313 recursive).stream; |
| 346 | 314 |
| 315 Future<FileSystemEntity> _delete({recursive: false}); |
| 316 void _deleteSync({recursive: false}); |
| 317 |
| 318 /** |
| 319 * Synchronously checks whether two paths refer to the same object in the |
| 320 * file system. Returns a [:Future<bool>:] that completes with the result. |
| 321 * |
| 322 * Comparing a link to its target returns false, as does comparing two links |
| 323 * that point to the same target. To check the target of a link, use |
| 324 * Link.target explicitly to fetch it. Directory links appearing |
| 325 * inside a path are followed, though, to find the file system object. |
| 326 * |
| 327 * Completes the returned Future with an error if one of the paths points |
| 328 * to an object that does not exist. |
| 329 */ |
| 330 static Future<bool> identical(String path1, String path2) { |
| 331 // Get a new file service port for each request. We could also cache one. |
| 332 var service = _FileUtils._newServicePort(); |
| 333 List request = new List(3); |
| 334 request[0] = _IDENTICAL_REQUEST; |
| 335 request[1] = path1; |
| 336 request[2] = path2; |
| 337 return service.call(request).then((response) { |
| 338 if (_isErrorResponse(response)) { |
| 339 throw _exceptionFromResponse(response, |
| 340 "Error in FileSystemEntity.identical($path1, $path2)", ""); |
| 341 } |
| 342 return response; |
| 343 }); |
| 344 } |
| 345 |
| 346 |
| 347 /** |
| 348 * Synchronously checks whether two paths refer to the same object in the |
| 349 * file system. |
| 350 * |
| 351 * Comparing a link to its target returns false, as does comparing two links |
| 352 * that point to the same target. To check the target of a link, use |
| 353 * Link.target explicitly to fetch it. Directory links appearing |
| 354 * inside a path are followed, though, to find the file system object. |
| 355 * |
| 356 * Throws an error if one of the paths points to an object that does not |
| 357 * exist. |
| 358 */ |
| 359 static bool identicalSync(String path1, String path2) { |
| 360 var result = _identical(path1, path2); |
| 361 _throwIfError(result, 'Error in FileSystemEntity.identicalSync'); |
| 362 return result; |
| 363 } |
| 364 |
| 347 /** | 365 /** |
| 348 * Test if [watch] is supported on the current system. | 366 * Test if [watch] is supported on the current system. |
| 349 * | 367 * |
| 350 * Mac OS 10.6 and below is not supported. | 368 * Mac OS 10.6 and below is not supported. |
| 351 */ | 369 */ |
| 352 static bool get isWatchSupported => _FileSystemWatcher.isSupported; | 370 static bool get isWatchSupported => _FileSystemWatcher.isSupported; |
| 353 | 371 |
| 354 | |
| 355 /** | 372 /** |
| 356 * Finds the type of file system object that a path points to. Returns | 373 * Finds the type of file system object that a path points to. Returns |
| 357 * a [:Future<FileSystemEntityType>:] that completes with the result. | 374 * a [:Future<FileSystemEntityType>:] that completes with the result. |
| 358 * | 375 * |
| 359 * [FileSystemEntityType] has the constant instances FILE, DIRECTORY, | 376 * [FileSystemEntityType] has the constant instances FILE, DIRECTORY, |
| 360 * LINK, and NOT_FOUND. [type] will return LINK only if the optional | 377 * LINK, and NOT_FOUND. [type] will return LINK only if the optional |
| 361 * named argument [followLinks] is false, and [path] points to a link. | 378 * named argument [followLinks] is false, and [path] points to a link. |
| 362 * If the path does not point to a file system object, or any other error | 379 * If the path does not point to a file system object, or any other error |
| 363 * occurs in looking up the path, NOT_FOUND is returned. The only | 380 * occurs in looking up the path, NOT_FOUND is returned. The only |
| 364 * error or exception that may be put on the returned future is ArgumentError, | 381 * error or exception that may be put on the returned future is ArgumentError, |
| (...skipping 11 matching lines...) Expand all Loading... |
| 376 * LINK, and NOT_FOUND. [type] will return LINK only if the optional | 393 * LINK, and NOT_FOUND. [type] will return LINK only if the optional |
| 377 * named argument [followLinks] is false, and [path] points to a link. | 394 * named argument [followLinks] is false, and [path] points to a link. |
| 378 * If the path does not point to a file system object, or any other error | 395 * If the path does not point to a file system object, or any other error |
| 379 * occurs in looking up the path, NOT_FOUND is returned. The only | 396 * occurs in looking up the path, NOT_FOUND is returned. The only |
| 380 * error or exception that may be thrown is ArgumentError, | 397 * error or exception that may be thrown is ArgumentError, |
| 381 * caused by passing the wrong type of arguments to the function. | 398 * caused by passing the wrong type of arguments to the function. |
| 382 */ | 399 */ |
| 383 static FileSystemEntityType typeSync(String path, {bool followLinks: true}) | 400 static FileSystemEntityType typeSync(String path, {bool followLinks: true}) |
| 384 => FileSystemEntityType._lookup(_getTypeSync(path, followLinks)); | 401 => FileSystemEntityType._lookup(_getTypeSync(path, followLinks)); |
| 385 | 402 |
| 386 | |
| 387 /** | 403 /** |
| 388 * Checks if type(path, followLinks: false) returns | 404 * Checks if type(path, followLinks: false) returns |
| 389 * FileSystemEntityType.LINK. | 405 * FileSystemEntityType.LINK. |
| 390 */ | 406 */ |
| 391 static Future<bool> isLink(String path) => _getTypeAsync(path, false) | 407 static Future<bool> isLink(String path) => _getTypeAsync(path, false) |
| 392 .then((type) => (type == FileSystemEntityType.LINK._type)); | 408 .then((type) => (type == FileSystemEntityType.LINK._type)); |
| 393 | 409 |
| 394 /** | 410 /** |
| 395 * Checks if type(path) returns FileSystemEntityType.FILE. | 411 * Checks if type(path) returns FileSystemEntityType.FILE. |
| 396 */ | 412 */ |
| (...skipping 20 matching lines...) Expand all Loading... |
| 417 static bool isFileSync(String path) => | 433 static bool isFileSync(String path) => |
| 418 (_getTypeSync(path, true) == FileSystemEntityType.FILE._type); | 434 (_getTypeSync(path, true) == FileSystemEntityType.FILE._type); |
| 419 | 435 |
| 420 /** | 436 /** |
| 421 * Synchronously checks if typeSync(path) returns | 437 * Synchronously checks if typeSync(path) returns |
| 422 * FileSystemEntityType.DIRECTORY. | 438 * FileSystemEntityType.DIRECTORY. |
| 423 */ | 439 */ |
| 424 static bool isDirectorySync(String path) => | 440 static bool isDirectorySync(String path) => |
| 425 (_getTypeSync(path, true) == FileSystemEntityType.DIRECTORY._type); | 441 (_getTypeSync(path, true) == FileSystemEntityType.DIRECTORY._type); |
| 426 | 442 |
| 443 external static _getType(String path, bool followLinks); |
| 444 external static _identical(String path1, String path2); |
| 445 |
| 446 static int _getTypeSync(String path, bool followLinks) { |
| 447 var result = _getType(path, followLinks); |
| 448 _throwIfError(result, 'Error getting type of FileSystemEntity'); |
| 449 return result; |
| 450 } |
| 451 |
| 452 static Future<int> _getTypeAsync(String path, bool followLinks) { |
| 453 // Get a new file service port for each request. We could also cache one. |
| 454 var service = _FileUtils._newServicePort(); |
| 455 List request = new List(3); |
| 456 request[0] = _TYPE_REQUEST; |
| 457 request[1] = path; |
| 458 request[2] = followLinks; |
| 459 return service.call(request).then((response) { |
| 460 if (_isErrorResponse(response)) { |
| 461 throw _exceptionFromResponse(response, "Error getting type", path); |
| 462 } |
| 463 return response; |
| 464 }); |
| 465 } |
| 427 | 466 |
| 428 static _throwIfError(Object result, String msg, [String path]) { | 467 static _throwIfError(Object result, String msg, [String path]) { |
| 429 if (result is OSError) { | 468 if (result is OSError) { |
| 430 throw new FileException(msg, path, result); | 469 throw new FileException(msg, path, result); |
| 431 } else if (result is ArgumentError) { | 470 } else if (result is ArgumentError) { |
| 432 throw result; | 471 throw result; |
| 433 } | 472 } |
| 434 } | 473 } |
| 435 | 474 |
| 436 static String _trimTrailingPathSeparators(String path) { | 475 static String _trimTrailingPathSeparators(String path) { |
| (...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 541 } | 580 } |
| 542 } | 581 } |
| 543 | 582 |
| 544 | 583 |
| 545 abstract class _FileSystemWatcher { | 584 abstract class _FileSystemWatcher { |
| 546 external factory _FileSystemWatcher(String path, int events, bool recursive); | 585 external factory _FileSystemWatcher(String path, int events, bool recursive); |
| 547 external static bool get isSupported; | 586 external static bool get isSupported; |
| 548 | 587 |
| 549 Stream<FileSystemEvent> get stream; | 588 Stream<FileSystemEvent> get stream; |
| 550 } | 589 } |
| OLD | NEW |