1 /* 2 ============================================================================== 3 4 This file is part of the JUCE library. 5 Copyright (c) 2020 - Raw Material Software Limited 6 7 JUCE is an open source library subject to commercial or open-source 8 licensing. 9 10 The code included in this file is provided under the terms of the ISC license 11 http://www.isc.org/downloads/software-support-policy/isc-license. Permission 12 To use, copy, modify, and/or distribute this software for any purpose with or 13 without fee is hereby granted provided that the above copyright notice and 14 this permission notice appear in all copies. 15 16 JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER 17 EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE 18 DISCLAIMED. 19 20 ============================================================================== 21 */ 22 23 #if ! DOXYGEN && (JUCE_MAC || JUCE_IOS) 24 #if __LP64__ 25 using OSType = unsigned int; 26 #else 27 using OSType = unsigned long; 28 #endif 29 #endif 30 31 namespace juce 32 { 33 34 //============================================================================== 35 /** 36 Represents a local file or directory. 37 38 This class encapsulates the absolute pathname of a file or directory, and 39 has methods for finding out about the file and changing its properties. 40 41 To read or write to the file, there are methods for returning an input or 42 output stream. 43 44 @see FileInputStream, FileOutputStream 45 46 @tags{Core} 47 */ 48 class JUCE_API File final 49 { 50 public: 51 //============================================================================== 52 /** Creates an (invalid) file object. 53 54 The file is initially set to an empty path, so getFullPathName() will return 55 an empty string. 56 57 You can use its operator= method to point it at a proper file. 58 */ 59 File() = default; 60 61 /** Creates a file from an absolute path. 62 63 If the path supplied is a relative path, it is taken to be relative 64 to the current working directory (see File::getCurrentWorkingDirectory()), 65 but this isn't a recommended way of creating a file, because you 66 never know what the CWD is going to be. 67 68 On the Mac/Linux, the path can include "~" notation for referring to 69 user home directories. 70 */ 71 File (const String& absolutePath); 72 73 /** Creates a copy of another file object. */ 74 File (const File&); 75 76 /** Destructor. */ 77 ~File() = default; 78 79 /** Sets the file based on an absolute pathname. 80 81 If the path supplied is a relative path, it is taken to be relative 82 to the current working directory (see File::getCurrentWorkingDirectory()), 83 but this isn't a recommended way of creating a file, because you 84 never know what the CWD is going to be. 85 86 On the Mac/Linux, the path can include "~" notation for referring to 87 user home directories. 88 */ 89 File& operator= (const String& newAbsolutePath); 90 91 /** Copies from another file object. */ 92 File& operator= (const File& otherFile); 93 94 /** Move constructor */ 95 File (File&&) noexcept; 96 97 /** Move assignment operator */ 98 File& operator= (File&&) noexcept; 99 100 //============================================================================== 101 /** Checks whether the file actually exists. 102 103 @returns true if the file exists, either as a file or a directory. 104 @see existsAsFile, isDirectory 105 */ 106 bool exists() const; 107 108 /** Checks whether the file exists and is a file rather than a directory. 109 110 @returns true only if this is a real file, false if it's a directory 111 or doesn't exist 112 @see exists, isDirectory 113 */ 114 bool existsAsFile() const; 115 116 /** Checks whether the file is a directory that exists. 117 118 @returns true only if the file is a directory which actually exists, so 119 false if it's a file or doesn't exist at all 120 @see exists, existsAsFile 121 */ 122 bool isDirectory() const; 123 124 /** Checks whether the path of this file represents the root of a file system, 125 irrespective of its existence. 126 127 This will return true for "C:", "D:", etc on Windows and "/" on other 128 platforms. 129 */ 130 bool isRoot() const; 131 132 /** Returns the size of the file in bytes. 133 134 @returns the number of bytes in the file, or 0 if it doesn't exist. 135 */ 136 int64 getSize() const; 137 138 /** Utility function to convert a file size in bytes to a neat string description. 139 140 So for example 100 would return "100 bytes", 2000 would return "2 KB", 141 2000000 would produce "2 MB", etc. 142 */ 143 static String descriptionOfSizeInBytes (int64 bytes); 144 145 //============================================================================== 146 /** Returns the complete, absolute path of this file. 147 148 This includes the filename and all its parent folders. On Windows it'll 149 also include the drive letter prefix; on Mac or Linux it'll be a complete 150 path starting from the root folder. 151 152 If you just want the file's name, you should use getFileName() or 153 getFileNameWithoutExtension(). 154 155 @see getFileName, getRelativePathFrom 156 */ getFullPathName()157 const String& getFullPathName() const noexcept { return fullPath; } 158 159 /** Returns the last section of the pathname. 160 161 Returns just the final part of the path - e.g. if the whole path 162 is "/moose/fish/foo.txt" this will return "foo.txt". 163 164 For a directory, it returns the final part of the path - e.g. for the 165 directory "/moose/fish" it'll return "fish". 166 167 If the filename begins with a dot, it'll return the whole filename, e.g. for 168 "/moose/.fish", it'll return ".fish" 169 170 @see getFullPathName, getFileNameWithoutExtension 171 */ 172 String getFileName() const; 173 174 /** Creates a relative path that refers to a file relatively to a given directory. 175 176 e.g. File ("/moose/foo.txt").getRelativePathFrom (File ("/moose/fish/haddock")) 177 would return "../../foo.txt". 178 179 If it's not possible to navigate from one file to the other, an absolute 180 path is returned. If the paths are invalid, an empty string may also be 181 returned. 182 183 @param directoryToBeRelativeTo the directory which the resultant string will 184 be relative to. If this is actually a file rather than 185 a directory, its parent directory will be used instead. 186 If it doesn't exist, it's assumed to be a directory. 187 @see getChildFile, isAbsolutePath 188 */ 189 String getRelativePathFrom (const File& directoryToBeRelativeTo) const; 190 191 //============================================================================== 192 /** Returns the file's extension. 193 194 Returns the file extension of this file, also including the dot. 195 196 e.g. "/moose/fish/foo.txt" would return ".txt" 197 198 @see hasFileExtension, withFileExtension, getFileNameWithoutExtension 199 */ 200 String getFileExtension() const; 201 202 /** Checks whether the file has a given extension. 203 204 @param extensionToTest the extension to look for - it doesn't matter whether or 205 not this string has a dot at the start, so ".wav" and "wav" 206 will have the same effect. To compare with multiple extensions, this 207 parameter can contain multiple strings, separated by semi-colons - 208 so, for example: hasFileExtension (".jpeg;png;gif") would return 209 true if the file has any of those three extensions. 210 211 @see getFileExtension, withFileExtension, getFileNameWithoutExtension 212 */ 213 bool hasFileExtension (StringRef extensionToTest) const; 214 215 /** Returns a version of this file with a different file extension. 216 217 e.g. File ("/moose/fish/foo.txt").withFileExtension ("html") returns "/moose/fish/foo.html" 218 219 @param newExtension the new extension, either with or without a dot at the start (this 220 doesn't make any difference). To get remove a file's extension altogether, 221 pass an empty string into this function. 222 223 @see getFileName, getFileExtension, hasFileExtension, getFileNameWithoutExtension 224 */ 225 File withFileExtension (StringRef newExtension) const; 226 227 /** Returns the last part of the filename, without its file extension. 228 229 e.g. for "/moose/fish/foo.txt" this will return "foo". 230 231 @see getFileName, getFileExtension, hasFileExtension, withFileExtension 232 */ 233 String getFileNameWithoutExtension() const; 234 235 //============================================================================== 236 /** Returns a 32-bit hash-code that identifies this file. 237 238 This is based on the filename. Obviously it's possible, although unlikely, that 239 two files will have the same hash-code. 240 */ 241 int hashCode() const; 242 243 /** Returns a 64-bit hash-code that identifies this file. 244 245 This is based on the filename. Obviously it's possible, although unlikely, that 246 two files will have the same hash-code. 247 */ 248 int64 hashCode64() const; 249 250 //============================================================================== 251 /** Returns a file that represents a relative (or absolute) sub-path of the current one. 252 253 This will find a child file or directory of the current object. 254 255 e.g. 256 File ("/moose/fish").getChildFile ("foo.txt") will produce "/moose/fish/foo.txt". 257 File ("/moose/fish").getChildFile ("haddock/foo.txt") will produce "/moose/fish/haddock/foo.txt". 258 File ("/moose/fish").getChildFile ("../foo.txt") will produce "/moose/foo.txt". 259 260 If the string is actually an absolute path, it will be treated as such, e.g. 261 File ("/moose/fish").getChildFile ("/foo.txt") will produce "/foo.txt" 262 263 @see getSiblingFile, getParentDirectory, getRelativePathFrom, isAChildOf 264 */ 265 File getChildFile (StringRef relativeOrAbsolutePath) const; 266 267 /** Returns a file which is in the same directory as this one. 268 269 This is equivalent to getParentDirectory().getChildFile (name). 270 271 @see getChildFile, getParentDirectory 272 */ 273 File getSiblingFile (StringRef siblingFileName) const; 274 275 //============================================================================== 276 /** Returns the directory that contains this file or directory. 277 278 e.g. for "/moose/fish/foo.txt" this will return "/moose/fish". 279 280 If you are already at the root directory ("/" or "C:") then this method will 281 return the root directory. 282 */ 283 File getParentDirectory() const; 284 285 /** Checks whether a file is somewhere inside a directory. 286 287 Returns true if this file is somewhere inside a subdirectory of the directory 288 that is passed in. Neither file actually has to exist, because the function 289 just checks the paths for similarities. 290 291 e.g. File ("/moose/fish/foo.txt").isAChildOf ("/moose") is true. 292 File ("/moose/fish/foo.txt").isAChildOf ("/moose/fish") is also true. 293 */ 294 bool isAChildOf (const File& potentialParentDirectory) const; 295 296 //============================================================================== 297 /** Chooses a filename relative to this one that doesn't already exist. 298 299 If this file is a directory, this will return a child file of this 300 directory that doesn't exist, by adding numbers to a prefix and suffix until 301 it finds one that isn't already there. 302 303 If the prefix + the suffix doesn't exist, it won't bother adding a number. 304 305 e.g. File ("/moose/fish").getNonexistentChildFile ("foo", ".txt", true) might 306 return "/moose/fish/foo(2).txt" if there's already a file called "foo.txt". 307 308 @param prefix the string to use for the filename before the number 309 @param suffix the string to add to the filename after the number 310 @param putNumbersInBrackets if true, this will create filenames in the 311 format "prefix(number)suffix", if false, it will leave the 312 brackets out. 313 */ 314 File getNonexistentChildFile (const String& prefix, 315 const String& suffix, 316 bool putNumbersInBrackets = true) const; 317 318 /** Chooses a filename for a sibling file to this one that doesn't already exist. 319 320 If this file doesn't exist, this will just return itself, otherwise it 321 will return an appropriate sibling that doesn't exist, e.g. if a file 322 "/moose/fish/foo.txt" exists, this might return "/moose/fish/foo(2).txt". 323 324 @param putNumbersInBrackets whether to add brackets around the numbers that 325 get appended to the new filename. 326 */ 327 File getNonexistentSibling (bool putNumbersInBrackets = true) const; 328 329 //============================================================================== 330 /** Compares the pathnames for two files. */ 331 bool operator== (const File&) const; 332 /** Compares the pathnames for two files. */ 333 bool operator!= (const File&) const; 334 /** Compares the pathnames for two files. */ 335 bool operator< (const File&) const; 336 /** Compares the pathnames for two files. */ 337 bool operator> (const File&) const; 338 339 //============================================================================== 340 /** Checks whether a file can be created or written to. 341 342 @returns true if it's possible to create and write to this file. If the file 343 doesn't already exist, this will check its parent directory to 344 see if writing is allowed. 345 @see setReadOnly 346 */ 347 bool hasWriteAccess() const; 348 349 /** Changes the write-permission of a file or directory. 350 351 @param shouldBeReadOnly whether to add or remove write-permission 352 @param applyRecursively if the file is a directory and this is true, it will 353 recurse through all the subfolders changing the permissions 354 of all files 355 @returns true if it manages to change the file's permissions. 356 @see hasWriteAccess 357 */ 358 bool setReadOnly (bool shouldBeReadOnly, 359 bool applyRecursively = false) const; 360 361 /** Changes the execute-permissions of a file. 362 363 @param shouldBeExecutable whether to add or remove execute-permission 364 @returns true if it manages to change the file's permissions. 365 */ 366 bool setExecutePermission (bool shouldBeExecutable) const; 367 368 /** Returns true if this file is a hidden or system file. 369 The criteria for deciding whether a file is hidden are platform-dependent. 370 */ 371 bool isHidden() const; 372 373 /** Returns a unique identifier for the file, if one is available. 374 375 Depending on the OS and file-system, this may be a unix inode number or 376 a win32 file identifier, or 0 if it fails to find one. The number will 377 be unique on the filesystem, but not globally. 378 */ 379 uint64 getFileIdentifier() const; 380 381 //============================================================================== 382 /** Returns the last modification time of this file. 383 384 @returns the time, or an invalid time if the file doesn't exist. 385 @see setLastModificationTime, getLastAccessTime, getCreationTime 386 */ 387 Time getLastModificationTime() const; 388 389 /** Returns the last time this file was accessed. 390 391 @returns the time, or an invalid time if the file doesn't exist. 392 @see setLastAccessTime, getLastModificationTime, getCreationTime 393 */ 394 Time getLastAccessTime() const; 395 396 /** Returns the time that this file was created. 397 398 @returns the time, or an invalid time if the file doesn't exist. 399 @see getLastModificationTime, getLastAccessTime 400 */ 401 Time getCreationTime() const; 402 403 /** Changes the modification time for this file. 404 405 @param newTime the time to apply to the file 406 @returns true if it manages to change the file's time. 407 @see getLastModificationTime, setLastAccessTime, setCreationTime 408 */ 409 bool setLastModificationTime (Time newTime) const; 410 411 /** Changes the last-access time for this file. 412 413 @param newTime the time to apply to the file 414 @returns true if it manages to change the file's time. 415 @see getLastAccessTime, setLastModificationTime, setCreationTime 416 */ 417 bool setLastAccessTime (Time newTime) const; 418 419 /** Changes the creation date for this file. 420 421 @param newTime the time to apply to the file 422 @returns true if it manages to change the file's time. 423 @see getCreationTime, setLastModificationTime, setLastAccessTime 424 */ 425 bool setCreationTime (Time newTime) const; 426 427 /** If possible, this will try to create a version string for the given file. 428 429 The OS may be able to look at the file and give a version for it - e.g. with 430 executables, bundles, dlls, etc. If no version is available, this will 431 return an empty string. 432 */ 433 String getVersion() const; 434 435 //============================================================================== 436 /** Creates an empty file if it doesn't already exist. 437 438 If the file that this object refers to doesn't exist, this will create a file 439 of zero size. 440 441 If it already exists or is a directory, this method will do nothing. 442 443 If the parent directories of the File do not exist then this method will 444 recursively create the parent directories. 445 446 @returns a result to indicate whether the file was created successfully, 447 or an error message if it failed. 448 @see createDirectory 449 */ 450 Result create() const; 451 452 /** Creates a new directory for this filename. 453 454 This will try to create the file as a directory, and will also create 455 any parent directories it needs in order to complete the operation. 456 457 @returns a result to indicate whether the directory was created successfully, or 458 an error message if it failed. 459 @see create 460 */ 461 Result createDirectory() const; 462 463 /** Deletes a file. 464 465 If this file is actually a directory, it may not be deleted correctly if it 466 contains files. See deleteRecursively() as a better way of deleting directories. 467 468 If this file is a symlink, then the symlink will be deleted and not the target 469 of the symlink. 470 471 @returns true if the file has been successfully deleted (or if it didn't exist to 472 begin with). 473 @see deleteRecursively 474 */ 475 bool deleteFile() const; 476 477 /** Deletes a file or directory and all its subdirectories. 478 479 If this file is a directory, this will try to delete it and all its subfolders. If 480 it's just a file, it will just try to delete the file. 481 482 483 @param followSymlinks If true, then any symlink pointing to a directory will also 484 recursively delete the contents of that directory 485 @returns true if the file and all its subfolders have been successfully 486 deleted (or if it didn't exist to begin with). 487 @see deleteFile 488 */ 489 bool deleteRecursively (bool followSymlinks = false) const; 490 491 /** Moves this file or folder to the trash. 492 493 @returns true if the operation succeeded. It could fail if the trash is full, or 494 if the file is write-protected, so you should check the return value 495 and act appropriately. 496 */ 497 bool moveToTrash() const; 498 499 /** Moves or renames a file. 500 501 Tries to move a file to a different location. 502 If the target file already exists, this will attempt to delete it first, and 503 will fail if this can't be done. 504 505 Note that the destination file isn't the directory to put it in, it's the actual 506 filename that you want the new file to have. 507 508 Also note that on some OSes (e.g. Windows), moving files between different 509 volumes may not be possible. 510 511 @returns true if the operation succeeds 512 */ 513 bool moveFileTo (const File& targetLocation) const; 514 515 /** Copies a file. 516 517 Tries to copy a file to a different location. 518 If the target file already exists, this will attempt to delete it first, and 519 will fail if this can't be done. 520 521 @returns true if the operation succeeds 522 */ 523 bool copyFileTo (const File& targetLocation) const; 524 525 /** Replaces a file. 526 527 Replace the file in the given location, assuming the replaced files identity. 528 Depending on the file system this will preserve file attributes such as 529 creation date, short file name, etc. 530 531 If replacement succeeds the original file is deleted. 532 533 @returns true if the operation succeeds 534 */ 535 bool replaceFileIn (const File& targetLocation) const; 536 537 /** Copies a directory. 538 539 Tries to copy an entire directory, recursively. 540 541 If this file isn't a directory or if any target files can't be created, this 542 will return false. 543 544 @param newDirectory the directory that this one should be copied to. Note that this 545 is the name of the actual directory to create, not the directory 546 into which the new one should be placed, so there must be enough 547 write privileges to create it if it doesn't exist. Any files inside 548 it will be overwritten by similarly named ones that are copied. 549 */ 550 bool copyDirectoryTo (const File& newDirectory) const; 551 552 //============================================================================== 553 /** Used in file searching, to specify whether to return files, directories, or both. 554 */ 555 enum TypesOfFileToFind 556 { 557 findDirectories = 1, /**< Use this flag to indicate that you want to find directories. */ 558 findFiles = 2, /**< Use this flag to indicate that you want to find files. */ 559 findFilesAndDirectories = 3, /**< Use this flag to indicate that you want to find both files and directories. */ 560 ignoreHiddenFiles = 4 /**< Add this flag to avoid returning any hidden files in the results. */ 561 }; 562 563 /** Searches this directory for files matching a wildcard pattern. 564 565 Assuming that this file is a directory, this method will search it 566 for either files or subdirectories whose names match a filename pattern. 567 Note that the order in which files are returned is completely undefined! 568 569 @param whatToLookFor a value from the TypesOfFileToFind enum, specifying whether to 570 return files, directories, or both. If the ignoreHiddenFiles flag 571 is also added to this value, hidden files won't be returned 572 @param searchRecursively if true, all subdirectories will be recursed into to do 573 an exhaustive search 574 @param wildCardPattern the filename pattern to search for, e.g. "*.txt" 575 @returns the set of files that were found 576 577 @see getNumberOfChildFiles, RangedDirectoryIterator 578 */ 579 Array<File> findChildFiles (int whatToLookFor, 580 bool searchRecursively, 581 const String& wildCardPattern = "*") const; 582 583 /** Searches inside a directory for files matching a wildcard pattern. 584 Note that there's a newer, better version of this method which returns the results 585 array, and in almost all cases, you should use that one instead! This one is kept around 586 mainly for legacy code to use. 587 */ 588 int findChildFiles (Array<File>& results, int whatToLookFor, 589 bool searchRecursively, const String& wildCardPattern = "*") const; 590 591 /** Searches inside a directory and counts how many files match a wildcard pattern. 592 593 Assuming that this file is a directory, this method will search it 594 for either files or subdirectories whose names match a filename pattern, 595 and will return the number of matches found. 596 597 This isn't a recursive call, and will only search this directory, not 598 its children. 599 600 @param whatToLookFor a value from the TypesOfFileToFind enum, specifying whether to 601 count files, directories, or both. If the ignoreHiddenFiles flag 602 is also added to this value, hidden files won't be counted 603 @param wildCardPattern the filename pattern to search for, e.g. "*.txt" 604 @returns the number of matches found 605 606 @see findChildFiles, RangedDirectoryIterator 607 */ 608 int getNumberOfChildFiles (int whatToLookFor, 609 const String& wildCardPattern = "*") const; 610 611 /** Returns true if this file is a directory that contains one or more subdirectories. 612 @see isDirectory, findChildFiles 613 */ 614 bool containsSubDirectories() const; 615 616 //============================================================================== 617 /** Creates a stream to read from this file. 618 619 Note that this is an old method, and actually it's usually best to avoid it and 620 instead use an RAII pattern with an FileInputStream directly, e.g. 621 @code 622 FileInputStream input (fileToOpen); 623 624 if (input.openedOk()) 625 { 626 input.read (etc... 627 } 628 @endcode 629 630 @returns a stream that will read from this file (initially positioned at the 631 start of the file), or nullptr if the file can't be opened for some reason 632 @see createOutputStream, loadFileAsData 633 */ 634 std::unique_ptr<FileInputStream> createInputStream() const; 635 636 /** Creates a stream to write to this file. 637 638 Note that this is an old method, and actually it's usually best to avoid it and 639 instead use an RAII pattern with an FileOutputStream directly, e.g. 640 @code 641 FileOutputStream output (fileToOpen); 642 643 if (output.openedOk()) 644 { 645 output.read etc... 646 } 647 @endcode 648 649 If the file exists, the stream that is returned will be positioned ready for 650 writing at the end of the file. If you want to write to the start of the file, 651 replacing the existing content, then you can do the following: 652 @code 653 FileOutputStream output (fileToOverwrite); 654 655 if (output.openedOk()) 656 { 657 output.setPosition (0); 658 output.truncate(); 659 ... 660 } 661 @endcode 662 663 @returns a stream that will write to this file (initially positioned at the 664 end of the file), or nullptr if the file can't be opened for some reason 665 @see createInputStream, appendData, appendText 666 */ 667 std::unique_ptr<FileOutputStream> createOutputStream (size_t bufferSize = 0x8000) const; 668 669 //============================================================================== 670 /** Loads a file's contents into memory as a block of binary data. 671 672 Of course, trying to load a very large file into memory will blow up, so 673 it's better to check first. 674 675 @param result the data block to which the file's contents should be appended - note 676 that if the memory block might already contain some data, you 677 might want to clear it first 678 @returns true if the file could all be read into memory 679 */ 680 bool loadFileAsData (MemoryBlock& result) const; 681 682 /** Reads a file into memory as a string. 683 684 Attempts to load the entire file as a zero-terminated string. 685 686 This makes use of InputStream::readEntireStreamAsString, which can 687 read either UTF-16 or UTF-8 file formats. 688 */ 689 String loadFileAsString() const; 690 691 /** Reads the contents of this file as text and splits it into lines, which are 692 appended to the given StringArray. 693 */ 694 void readLines (StringArray& destLines) const; 695 696 //============================================================================== 697 /** Appends a block of binary data to the end of the file. 698 699 This will try to write the given buffer to the end of the file. 700 701 @returns false if it can't write to the file for some reason 702 */ 703 bool appendData (const void* dataToAppend, 704 size_t numberOfBytes) const; 705 706 /** Replaces this file's contents with a given block of data. 707 708 This will delete the file and replace it with the given data. 709 710 A nice feature of this method is that it's safe - instead of deleting 711 the file first and then re-writing it, it creates a new temporary file, 712 writes the data to that, and then moves the new file to replace the existing 713 file. This means that if the power gets pulled out or something crashes, 714 you're a lot less likely to end up with a corrupted or unfinished file.. 715 716 Returns true if the operation succeeds, or false if it fails. 717 718 @see appendText 719 */ 720 bool replaceWithData (const void* dataToWrite, 721 size_t numberOfBytes) const; 722 723 /** Appends a string to the end of the file. 724 725 This will try to append a text string to the file, as either 16-bit unicode 726 or 8-bit characters in the default system encoding. 727 728 It can also write the 'ff fe' unicode header bytes before the text to indicate 729 the endianness of the file. 730 731 If lineEndings is nullptr, then line endings in the text won't be modified. If you 732 pass "\\n" or "\\r\\n" then this function will replace any existing line feeds. 733 734 @see replaceWithText 735 */ 736 bool appendText (const String& textToAppend, 737 bool asUnicode = false, 738 bool writeUnicodeHeaderBytes = false, 739 const char* lineEndings = "\r\n") const; 740 741 /** Replaces this file's contents with a given text string. 742 743 This will delete the file and replace it with the given text. 744 745 A nice feature of this method is that it's safe - instead of deleting 746 the file first and then re-writing it, it creates a new temporary file, 747 writes the text to that, and then moves the new file to replace the existing 748 file. This means that if the power gets pulled out or something crashes, 749 you're a lot less likely to end up with an empty file.. 750 751 For an explanation of the parameters here, see the appendText() method. 752 753 Returns true if the operation succeeds, or false if it fails. 754 755 @see appendText 756 */ 757 bool replaceWithText (const String& textToWrite, 758 bool asUnicode = false, 759 bool writeUnicodeHeaderBytes = false, 760 const char* lineEndings = "\r\n") const; 761 762 /** Attempts to scan the contents of this file and compare it to another file, returning 763 true if this is possible and they match byte-for-byte. 764 */ 765 bool hasIdenticalContentTo (const File& other) const; 766 767 //============================================================================== 768 /** Creates a set of files to represent each file root. 769 770 e.g. on Windows this will create files for "c:\", "d:\" etc according 771 to which ones are available. On the Mac/Linux, this will probably 772 just add a single entry for "/". 773 */ 774 static void findFileSystemRoots (Array<File>& results); 775 776 /** Finds the name of the drive on which this file lives. 777 @returns the volume label of the drive, or an empty string if this isn't possible 778 */ 779 String getVolumeLabel() const; 780 781 /** Returns the serial number of the volume on which this file lives. 782 @returns the serial number, or zero if there's a problem doing this 783 */ 784 int getVolumeSerialNumber() const; 785 786 /** Returns the number of bytes free on the drive that this file lives on. 787 788 @returns the number of bytes free, or 0 if there's a problem finding this out 789 @see getVolumeTotalSize 790 */ 791 int64 getBytesFreeOnVolume() const; 792 793 /** Returns the total size of the drive that contains this file. 794 795 @returns the total number of bytes that the volume can hold 796 @see getBytesFreeOnVolume 797 */ 798 int64 getVolumeTotalSize() const; 799 800 /** Returns true if this file is on a CD or DVD drive. */ 801 bool isOnCDRomDrive() const; 802 803 /** Returns true if this file is on a hard disk. 804 805 This will fail if it's a network drive, but will still be true for 806 removable hard-disks. 807 */ 808 bool isOnHardDisk() const; 809 810 /** Returns true if this file is on a removable disk drive. 811 812 This might be a usb-drive, a CD-rom, or maybe a network drive. 813 */ 814 bool isOnRemovableDrive() const; 815 816 //============================================================================== 817 /** Launches the file as a process. 818 819 - if the file is executable, this will run it. 820 821 - if it's a document of some kind, it will launch the document with its 822 default viewer application. 823 824 - if it's a folder, it will be opened in Explorer, Finder, or equivalent. 825 826 @see revealToUser 827 */ 828 bool startAsProcess (const String& parameters = String()) const; 829 830 /** Opens Finder, Explorer, or whatever the OS uses, to show the user this file's location. 831 @see startAsProcess 832 */ 833 void revealToUser() const; 834 835 //============================================================================== 836 /** A set of types of location that can be passed to the getSpecialLocation() method. 837 */ 838 enum SpecialLocationType 839 { 840 /** The user's home folder. This is the same as using File ("~"). */ 841 userHomeDirectory, 842 843 /** The user's default documents folder. On Windows, this might be the user's 844 "My Documents" folder. On the Mac it'll be their "Documents" folder. Linux 845 doesn't tend to have one of these, so it might just return their home folder. 846 */ 847 userDocumentsDirectory, 848 849 /** The folder that contains the user's desktop objects. */ 850 userDesktopDirectory, 851 852 /** The most likely place where a user might store their music files. */ 853 userMusicDirectory, 854 855 /** The most likely place where a user might store their movie files. */ 856 userMoviesDirectory, 857 858 /** The most likely place where a user might store their picture files. */ 859 userPicturesDirectory, 860 861 /** The folder in which applications store their persistent user-specific settings. 862 On Windows, this might be "\Documents and Settings\username\Application Data". 863 On the Mac, it might be "~/Library". If you're going to store your settings in here, 864 always create your own sub-folder to put them in, to avoid making a mess. 865 On GNU/Linux it is "~/.config". 866 */ 867 userApplicationDataDirectory, 868 869 /** An equivalent of the userApplicationDataDirectory folder that is shared by all users 870 of the computer, rather than just the current user. 871 872 On the Mac it'll be "/Library", on Windows, it could be something like 873 "\Documents and Settings\All Users\Application Data". 874 875 On GNU/Linux it is "/opt". 876 877 Depending on the setup, this folder may be read-only. 878 */ 879 commonApplicationDataDirectory, 880 881 /** A place to put documents which are shared by all users of the machine. 882 On Windows this may be somewhere like "C:\Users\Public\Documents", on OSX it 883 will be something like "/Users/Shared". Other OSes may have no such concept 884 though, so be careful. 885 */ 886 commonDocumentsDirectory, 887 888 /** The folder that should be used for temporary files. 889 Always delete them when you're finished, to keep the user's computer tidy! 890 */ 891 tempDirectory, 892 893 /** Returns this application's executable file. 894 895 If running as a plug-in or DLL, this will (where possible) be the DLL rather than the 896 host app. 897 898 On the mac this will return the unix binary, not the package folder - see 899 currentApplicationFile for that. 900 901 See also invokedExecutableFile, which is similar, but if the exe was launched from a 902 file link, invokedExecutableFile will return the name of the link. 903 */ 904 currentExecutableFile, 905 906 /** Returns this application's location. 907 908 If running as a plug-in or DLL, this will (where possible) be the DLL rather than the 909 host app. 910 911 On the mac this will return the package folder (if it's in one), not the unix binary 912 that's inside it - compare with currentExecutableFile. 913 */ 914 currentApplicationFile, 915 916 /** Returns the file that was invoked to launch this executable. 917 This may differ from currentExecutableFile if the app was started from e.g. a link - this 918 will return the name of the link that was used, whereas currentExecutableFile will return 919 the actual location of the target executable. 920 */ 921 invokedExecutableFile, 922 923 /** In a plugin, this will return the path of the host executable. */ 924 hostApplicationPath, 925 926 #if JUCE_WINDOWS || DOXYGEN 927 /** On a Windows machine, returns the location of the Windows/System32 folder. */ 928 windowsSystemDirectory, 929 #endif 930 931 /** The directory in which applications normally get installed. 932 So on windows, this would be something like "C:\Program Files", on the 933 Mac "/Applications", or "/usr" on linux. 934 */ 935 globalApplicationsDirectory, 936 937 #if JUCE_WINDOWS || DOXYGEN 938 /** On a Windows machine, returns the directory in which 32 bit applications 939 normally get installed. On a 64 bit machine this would be something like 940 "C:\Program Files (x86)", whereas for 32 bit machines this would match 941 globalApplicationsDirectory and be something like "C:\Program Files". 942 943 @see globalApplicationsDirectory 944 */ 945 globalApplicationsDirectoryX86 946 #endif 947 }; 948 949 /** Finds the location of a special type of file or directory, such as a home folder or 950 documents folder. 951 952 @see SpecialLocationType 953 */ 954 static File JUCE_CALLTYPE getSpecialLocation (const SpecialLocationType type); 955 956 //============================================================================== 957 /** Returns a temporary file in the system's temp directory. 958 This will try to return the name of a non-existent temp file. 959 To get the temp folder, you can use getSpecialLocation (File::tempDirectory). 960 */ 961 static File createTempFile (StringRef fileNameEnding); 962 963 //============================================================================== 964 /** Returns the current working directory. 965 @see setAsCurrentWorkingDirectory 966 */ 967 static File getCurrentWorkingDirectory(); 968 969 /** Sets the current working directory to be this file. 970 971 For this to work the file must point to a valid directory. 972 973 @returns true if the current directory has been changed. 974 @see getCurrentWorkingDirectory 975 */ 976 bool setAsCurrentWorkingDirectory() const; 977 978 //============================================================================== 979 /** The system-specific file separator character. 980 On Windows, this will be '\', on Mac/Linux, it'll be '/' 981 */ 982 static juce_wchar getSeparatorChar(); 983 984 /** The system-specific file separator character, as a string. 985 On Windows, this will be '\', on Mac/Linux, it'll be '/' 986 */ 987 static StringRef getSeparatorString(); 988 989 //============================================================================== 990 /** Returns a version of a filename with any illegal characters removed. 991 992 This will return a copy of the given string after removing characters 993 that are not allowed in a legal filename, and possibly shortening the 994 string if it's too long. 995 996 Because this will remove slashes, don't use it on an absolute pathname - use 997 createLegalPathName() for that. 998 999 @see createLegalPathName 1000 */ 1001 static String createLegalFileName (const String& fileNameToFix); 1002 1003 /** Returns a version of a path with any illegal characters removed. 1004 1005 Similar to createLegalFileName(), but this won't remove slashes, so can 1006 be used on a complete pathname. 1007 1008 @see createLegalFileName 1009 */ 1010 static String createLegalPathName (const String& pathNameToFix); 1011 1012 /** Indicates whether filenames are case-sensitive on the current operating system. */ 1013 static bool areFileNamesCaseSensitive(); 1014 1015 /** Returns true if the string seems to be a fully-specified absolute path. */ 1016 static bool isAbsolutePath (StringRef path); 1017 1018 /** Creates a file that simply contains this string, without doing the sanity-checking 1019 that the normal constructors do. 1020 1021 Best to avoid this unless you really know what you're doing. 1022 */ 1023 static File createFileWithoutCheckingPath (const String& absolutePath) noexcept; 1024 1025 /** Adds a separator character to the end of a path if it doesn't already have one. */ 1026 static String addTrailingSeparator (const String& path); 1027 1028 //============================================================================== 1029 /** Tries to create a symbolic link and returns a boolean to indicate success */ 1030 bool createSymbolicLink (const File& linkFileToCreate, bool overwriteExisting) const; 1031 1032 /** Returns true if this file is a link or alias that can be followed using getLinkedTarget(). */ 1033 bool isSymbolicLink() const; 1034 1035 /** If this file is a link or alias, this returns the file that it points to. 1036 If the file isn't actually link, it'll just return itself. 1037 */ 1038 File getLinkedTarget() const; 1039 1040 /** Create a symbolic link to a native path and return a boolean to indicate success. 1041 1042 Use this method if you want to create a link to a relative path or a special native 1043 file path (such as a device file on Windows). 1044 */ 1045 static bool createSymbolicLink (const File& linkFileToCreate, 1046 const String& nativePathOfTarget, 1047 bool overwriteExisting); 1048 1049 /** This returns the native path that the symbolic link points to. The returned path 1050 is a native path of the current OS and can be a relative, absolute or special path. */ 1051 String getNativeLinkedTarget() const; 1052 1053 #if JUCE_WINDOWS || DOXYGEN 1054 /** Windows ONLY - Creates a win32 .LNK shortcut file that links to this file. */ 1055 bool createShortcut (const String& description, const File& linkFileToCreate) const; 1056 1057 /** Windows ONLY - Returns true if this is a win32 .LNK file. */ 1058 bool isShortcut() const; 1059 #else 1060 1061 #endif 1062 1063 //============================================================================== 1064 #if JUCE_MAC || JUCE_IOS || DOXYGEN 1065 /** OSX ONLY - Finds the OSType of a file from the its resources. */ 1066 OSType getMacOSType() const; 1067 1068 /** OSX ONLY - Returns true if this file is actually a bundle. */ 1069 bool isBundle() const; 1070 #endif 1071 1072 #if JUCE_MAC || DOXYGEN 1073 /** OSX ONLY - Adds this file to the OSX dock */ 1074 void addToDock() const; 1075 #endif 1076 1077 //============================================================================== 1078 /** Comparator for files */ 1079 struct NaturalFileComparator 1080 { NaturalFileComparatorNaturalFileComparator1081 NaturalFileComparator (bool shouldPutFoldersFirst) noexcept : foldersFirst (shouldPutFoldersFirst) {} 1082 compareElementsNaturalFileComparator1083 int compareElements (const File& firstFile, const File& secondFile) const 1084 { 1085 if (foldersFirst && (firstFile.isDirectory() != secondFile.isDirectory())) 1086 return firstFile.isDirectory() ? -1 : 1; 1087 1088 #if NAMES_ARE_CASE_SENSITIVE 1089 return firstFile.getFullPathName().compareNatural (secondFile.getFullPathName(), true); 1090 #else 1091 return firstFile.getFullPathName().compareNatural (secondFile.getFullPathName(), false); 1092 #endif 1093 } 1094 1095 bool foldersFirst; 1096 }; 1097 1098 /* These static objects are deprecated because it's too easy to accidentally use them indirectly 1099 during a static constructor, which leads to very obscure order-of-initialisation bugs. 1100 Use File::getSeparatorChar() and File::getSeparatorString(), and instead of File::nonexistent, 1101 just use File() or {}. 1102 */ 1103 JUCE_DEPRECATED_STATIC (static const juce_wchar separator;) 1104 JUCE_DEPRECATED_STATIC (static const StringRef separatorString;) 1105 JUCE_DEPRECATED_STATIC (static const File nonexistent;) 1106 1107 private: 1108 //============================================================================== 1109 String fullPath; 1110 1111 static String parseAbsolutePath (const String&); 1112 String getPathUpToLastSlash() const; 1113 1114 Result createDirectoryInternal (const String&) const; 1115 bool copyInternal (const File&) const; 1116 bool moveInternal (const File&) const; 1117 bool replaceInternal (const File&) const; 1118 bool setFileTimesInternal (int64 m, int64 a, int64 c) const; 1119 void getFileTimesInternal (int64& m, int64& a, int64& c) const; 1120 bool setFileReadOnlyInternal (bool) const; 1121 bool setFileExecutableInternal (bool) const; 1122 }; 1123 1124 } // namespace juce 1125