39 : fullPath (
other.fullPath)
45 fullPath = parseAbsolutePath (
newPath);
51 fullPath =
other.fullPath;
56 : fullPath (std::move (
other.fullPath))
62 fullPath = std::move (
other.fullPath);
66JUCE_DECLARE_DEPRECATED_STATIC (
const File File::nonexistent{};)
69static String removeEllipsis (
const String& path)
74 if (path.contains (
".\\"))
76 if (path.contains (
"./"))
81 bool anythingChanged =
false;
83 for (
int i = 1; i < toks.size(); ++i)
87 if (t ==
".." && toks[i - 1] !=
"..")
89 anythingChanged =
true;
95 anythingChanged =
true;
107static String normaliseSeparators (
const String& path)
109 auto normalisedPath = path;
112 String doubleSeparator (separator + separator);
114 auto uncPath = normalisedPath.startsWith (doubleSeparator)
115 && ! normalisedPath.fromFirstOccurrenceOf (doubleSeparator,
false,
false).startsWith (separator);
118 normalisedPath = normalisedPath.fromFirstOccurrenceOf (doubleSeparator,
false,
false);
120 while (normalisedPath.contains (doubleSeparator))
121 normalisedPath = normalisedPath.replace (doubleSeparator, separator);
123 return uncPath ? doubleSeparator + normalisedPath
139 auto path = normaliseSeparators (removeEllipsis (p.
replaceCharacter (
'/',
'\\')));
157 else if (! path.containsChar (
':'))
178 auto path = normaliseSeparators (removeEllipsis (p));
180 if (path.startsWithChar (
'~'))
186 + path.substring (1);
191 auto userName = path.substring (1).upToFirstOccurrenceOf (
"/",
false,
false);
193 if (
auto* pw = getpwnam (userName.toUTF8()))
199 #if JUCE_DEBUG || JUCE_LOG_ASSERTIONS
200 if (! (path.startsWith (
"./") || path.startsWith (
"../")))
211 #if JUCE_LOG_ASSERTIONS
222 path = path.dropLastCharacters (1);
235 #define NAMES_ARE_CASE_SENSITIVE 1
240 #if NAMES_ARE_CASE_SENSITIVE
249 #if NAMES_ARE_CASE_SENSITIVE
292 if (
newFile.fullPath == fullPath)
298 #if ! NAMES_ARE_CASE_SENSITIVE
315 if (
newFile.fullPath == fullPath)
321 if (! replaceInternal (
newFile))
333 if (! f.copyFileTo (
newDirectory.getChildFile (f.getFileName())))
337 if (! f.copyDirectoryTo (
newDirectory.getChildFile (f.getFileName())))
347String File::getPathUpToLastSlash()
const
387 auto ourPath = getPathUpToLastSlash();
426 auto path = fullPath;
467 path.appendCharPointer (r);
556 return in.openedOk() ?
in.readEntireStreamAsString()
579 results.
add (
di.getFile());
608 bool putNumbersInBrackets)
const
618 if (
prefix.trim().endsWithChar (
')'))
620 putNumbersInBrackets =
true;
638 if (putNumbersInBrackets)
640 newName <<
'(' << ++
number <<
')';
652 }
while (f.exists());
665 putNumbersInBrackets);
698 return fullPath[
dotPos] ==
'.';
734 return fin.release();
768 return tempFile.overwriteTargetFileWithTemporary();
775 if (
out.failedToOpen())
785 return tempFile.overwriteTargetFileWithTemporary();
797 if (
in1.openedOk() &&
in2.openedOk())
799 const int bufferSize = 4096;
828 if (s.isNotEmpty() && s[1] ==
':')
840 auto s =
original.removeCharacters (
"\"#@,;:<>*^|?\\/");
843 auto len = s.length();
847 auto lastDot = s.lastIndexOfChar (
'.');
864static int countNumberOfSeparators (String::CharPointerType s)
870 auto c = s.getAndAdvance();
908 #if NAMES_ARE_CASE_SENSITIVE
976 #if JUCE_MAC || JUCE_LINUX
1015 : range (0, file.getSize())
1021 : range (
fileRange.getIntersectionWith (
Range<int64> (0, file.getSize())))
1035 :
UnitTest (
"Files", UnitTestCategories::files)
1038 void runTest()
override
1040 beginTest (
"Reading");
1045 expect (! File().exists());
1046 expect (! File().existsAsFile());
1047 expect (! File().isDirectory());
1049 expect (File(
"/").isDirectory());
1051 expect (
home.isDirectory());
1052 expect (
home.exists());
1053 expect (!
home.existsAsFile());
1058 expect (
home.getVolumeTotalSize() > 1024 * 1024);
1059 expect (
home.getBytesFreeOnVolume() > 0);
1060 expect (!
home.isHidden());
1061 expect (
home.isOnHardDisk());
1062 expect (!
home.isOnCDRomDrive());
1064 expect (
home.setAsCurrentWorkingDirectory());
1070 expect (
roots.size() > 0);
1073 for (
int i = 0; i <
roots.size(); ++i)
1074 if (
roots[i].exists())
1081 beginTest (
"Writing");
1083 File
demoFolder (temp.getChildFile (
"JUCE UnitTests Temp Folder.folder"));
1087 expect (
demoFolder.getParentDirectory() == temp);
1088 expect (temp.isDirectory());
1094 expect (
tempFile.getFileExtension() ==
".txt");
1095 expect (
tempFile.hasFileExtension (
".txt"));
1096 expect (
tempFile.hasFileExtension (
"txt"));
1097 expect (
tempFile.withFileExtension (
"xyz").hasFileExtension (
".xyz"));
1098 expect (
tempFile.withFileExtension (
"xyz").hasFileExtension (
"abc;xyz;foo"));
1099 expect (
tempFile.withFileExtension (
"xyz").hasFileExtension (
"xyz;foo"));
1100 expect (!
tempFile.withFileExtension (
"h").hasFileExtension (
"bar;foo;xx"));
1101 expect (
tempFile.getSiblingFile (
"foo").isAChildOf (temp));
1102 expect (
tempFile.hasWriteAccess());
1104 expect (
home.getChildFile (
".") ==
home);
1105 expect (
home.getChildFile (
"..") ==
home.getParentDirectory());
1106 expect (
home.getChildFile (
".xyz").getFileName() ==
".xyz");
1107 expect (
home.getChildFile (
"..xyz").getFileName() ==
"..xyz");
1108 expect (
home.getChildFile (
"...xyz").getFileName() ==
"...xyz");
1109 expect (
home.getChildFile (
"./xyz") ==
home.getChildFile (
"xyz"));
1110 expect (
home.getChildFile (
"././xyz") ==
home.getChildFile (
"xyz"));
1111 expect (
home.getChildFile (
"../xyz") ==
home.getParentDirectory().getChildFile (
"xyz"));
1112 expect (
home.getChildFile (
".././xyz") ==
home.getParentDirectory().getChildFile (
"xyz"));
1113 expect (
home.getChildFile (
".././xyz/./abc") ==
home.getParentDirectory().getChildFile (
"xyz/abc"));
1114 expect (
home.getChildFile (
"./../xyz") ==
home.getParentDirectory().getChildFile (
"xyz"));
1115 expect (
home.getChildFile (
"a1/a2/a3/./../../a4") ==
home.getChildFile (
"a1/a4"));
1119 fo.write (
"0123456789", 10);
1125 expectEquals (
tempFile.loadFileAsString(), String (
"0123456789"));
1126 expect (!
demoFolder.containsSubDirectories());
1134 demoFolder.getNonexistentChildFile (
"tempFolder",
"",
false).createDirectory();
1137 expect (
demoFolder.containsSubDirectories());
1139 expect (
tempFile.hasWriteAccess());
1141 expect (!
tempFile.hasWriteAccess());
1143 expect (
tempFile.hasWriteAccess());
1147 Time
t2 =
tempFile.getLastModificationTime();
1148 expect (std::abs ((
int) (
t2.toMilliseconds() -
t.toMilliseconds())) <= 1000);
1153 expect (
mb.getSize() == 10);
1154 expect (
mb[0] ==
'0');
1160 expect (
fo.openedOk());
1162 expect (
fo.setPosition (7));
1163 expect (
fo.truncate().wasOk());
1165 fo.write (
"789", 3);
1170 beginTest (
"Memory-mapped files");
1174 expect (
mmf.getSize() == 10);
1175 expect (
mmf.getData() !=
nullptr);
1176 expect (
memcmp (
mmf.getData(),
"0123456789", 10) == 0);
1182 expect (
tempFile2.appendData (
"xxxxxxxxxx", 10));
1186 expect (
mmf.getSize() == 10);
1187 expect (
mmf.getData() !=
nullptr);
1188 memcpy (
mmf.getData(),
"abcdefghij", 10);
1193 expect (
mmf.getSize() == 10);
1194 expect (
mmf.getData() !=
nullptr);
1195 expect (
memcmp (
mmf.getData(),
"abcdefghij", 10) == 0);
1201 beginTest (
"More writing");
1203 expect (
tempFile.appendData (
"abcdefghij", 10));
1205 expect (
tempFile.replaceWithData (
"abcdefghij", 10));
1222 URL url (
"https://audio.dev/foo/bar/");
1223 expectEquals (url.toString (
false), String (
"https://audio.dev/foo/bar/"));
1224 expectEquals (url.getChildURL (
"x").toString (
false), String (
"https://audio.dev/foo/bar/x"));
1225 expectEquals (url.getParentURL().toString (
false), String (
"https://audio.dev/foo"));
1226 expectEquals (url.getParentURL().getParentURL().toString (
false), String (
"https://audio.dev/"));
1227 expectEquals (url.getParentURL().getParentURL().getParentURL().toString (
false), String (
"https://audio.dev/"));
1228 expectEquals (url.getParentURL().getChildURL (
"x").toString (
false), String (
"https://audio.dev/foo/x"));
1229 expectEquals (url.getParentURL().getParentURL().getParentURL().getChildURL (
"x").toString (
false), String (
"https://audio.dev/x"));
1233 URL url (
"https://audio.dev/foo/bar");
1234 expectEquals (url.toString (
false), String (
"https://audio.dev/foo/bar"));
1235 expectEquals (url.getChildURL (
"x").toString (
false), String (
"https://audio.dev/foo/bar/x"));
1236 expectEquals (url.getParentURL().toString (
false), String (
"https://audio.dev/foo"));
1237 expectEquals (url.getParentURL().getParentURL().toString (
false), String (
"https://audio.dev/"));
1238 expectEquals (url.getParentURL().getParentURL().getParentURL().toString (
false), String (
"https://audio.dev/"));
1239 expectEquals (url.getParentURL().getChildURL (
"x").toString (
false), String (
"https://audio.dev/foo/x"));
1240 expectEquals (url.getParentURL().getParentURL().getParentURL().getChildURL (
"x").toString (
false), String (
"https://audio.dev/x"));
1245static FileTests fileUnitTests;
bool isEmpty() const noexcept
void removeRange(int startIndex, int numberToRemove)
int indexOf(ParameterType elementToLookFor) const
void add(const ElementType &newElement)
static juce_wchar toLowerCase(juce_wchar character) noexcept
static bool isDigit(char character) noexcept
bool replaceWithText(const String &textToWrite, bool asUnicode=false, bool writeUnicodeHeaderBytes=false, const char *lineEndings="\r\n") const
bool isSymbolicLink() const
int getNumberOfChildFiles(int whatToLookFor, const String &wildCardPattern="*") const
bool moveFileTo(const File &targetLocation) const
bool operator==(const File &) const
bool containsSubDirectories() const
static void findFileSystemRoots(Array< File > &results)
bool hasIdenticalContentTo(const File &other) const
FileOutputStream * createOutputStream(size_t bufferSize=0x8000) const
static String createLegalPathName(const String &pathNameToFix)
static String addTrailingSeparator(const String &path)
String getFileExtension() const
Time getLastModificationTime() const
bool existsAsFile() const
bool copyFileTo(const File &targetLocation) const
bool deleteRecursively(bool followSymlinks=false) const
static File JUCE_CALLTYPE getSpecialLocation(const SpecialLocationType type)
const String & getFullPathName() const noexcept
String getFileName() const
bool replaceWithData(const void *dataToWrite, size_t numberOfBytes) const
bool setLastAccessTime(Time newTime) const
File getChildFile(StringRef relativeOrAbsolutePath) const
void readLines(StringArray &destLines) const
static bool isAbsolutePath(StringRef path)
File getSiblingFile(StringRef siblingFileName) const
bool createSymbolicLink(const File &linkFileToCreate, bool overwriteExisting) const
String getFileNameWithoutExtension() const
Array< File > findChildFiles(int whatToLookFor, bool searchRecursively, const String &wildCardPattern="*") const
File getNonexistentSibling(bool putNumbersInBrackets=true) const
@ userApplicationDataDirectory
String getRelativePathFrom(const File &directoryToBeRelativeTo) const
bool appendText(const String &textToAppend, bool asUnicode=false, bool writeUnicodeHeaderBytes=false, const char *lineEndings="\r\n") const
@ findFilesAndDirectories
File getNonexistentChildFile(const String &prefix, const String &suffix, bool putNumbersInBrackets=true) const
bool operator!=(const File &) const
bool setCreationTime(Time newTime) const
static String descriptionOfSizeInBytes(int64 bytes)
bool setReadOnly(bool shouldBeReadOnly, bool applyRecursively=false) const
static File createTempFile(StringRef fileNameEnding)
static juce_wchar getSeparatorChar()
static bool areFileNamesCaseSensitive()
String loadFileAsString() const
FileInputStream * createInputStream() const
bool operator>(const File &) const
File getLinkedTarget() const
File getParentDirectory() const
bool appendData(const void *dataToAppend, size_t numberOfBytes) const
bool operator<(const File &) const
Time getCreationTime() const
bool setExecutePermission(bool shouldBeExecutable) const
File withFileExtension(StringRef newExtension) const
static String createLegalFileName(const String &fileNameToFix)
bool replaceFileIn(const File &targetLocation) const
bool isAChildOf(const File &potentialParentDirectory) const
static File createFileWithoutCheckingPath(const String &absolutePath) noexcept
bool startAsProcess(const String ¶meters=String()) const
String getNativeLinkedTarget() const
bool hasFileExtension(StringRef extensionToTest) const
bool copyDirectoryTo(const File &newDirectory) const
bool loadFileAsData(MemoryBlock &result) const
bool setLastModificationTime(Time newTime) const
Time getLastAccessTime() const
Result createDirectory() const
static File getCurrentWorkingDirectory()
static StringRef getSeparatorString()
File & operator=(const String &newAbsolutePath)
static void JUCE_CALLTYPE writeToLog(const String &message)
MemoryMappedFile(const File &file, AccessMode mode, bool exclusive=false)
static bool JUCE_CALLTYPE openDocument(const String &documentURL, const String ¶meters)
static Random & getSystemRandom() noexcept
static Result fail(const String &errorMessage) noexcept
static Result ok() noexcept
String::CharPointerType text
static String repeatedString(StringRef stringToRepeat, int numberOfTimesToRepeat)
int indexOfChar(juce_wchar characterToLookFor) const noexcept
int length() const noexcept
bool endsWithChar(juce_wchar character) const noexcept
bool isEmpty() const noexcept
int64 hashCode64() const noexcept
bool containsChar(juce_wchar character) const noexcept
String removeCharacters(StringRef charactersToRemove) const
bool endsWithIgnoreCase(StringRef text) const noexcept
static String toHexString(IntegerType number)
int lastIndexOfChar(juce_wchar character) const noexcept
String trimCharactersAtEnd(StringRef charactersToTrim) const
String replaceCharacter(juce_wchar characterToReplace, juce_wchar characterToInsertInstead) const
String substring(int startIndex, int endIndex) const
int hashCode() const noexcept
bool isNotEmpty() const noexcept
static Time JUCE_CALLTYPE getCurrentTime() noexcept