OpenShot Library | libopenshot-audio  0.2.0
juce_File.cpp
1 /*
2  ==============================================================================
3 
4  This file is part of the JUCE library.
5  Copyright (c) 2017 - ROLI Ltd.
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 namespace juce
24 {
25 
26 File::File (const String& fullPathName)
27  : fullPath (parseAbsolutePath (fullPathName))
28 {
29 }
30 
32 {
33  File f;
34  f.fullPath = path;
35  return f;
36 }
37 
38 File::File (const File& other)
39  : fullPath (other.fullPath)
40 {
41 }
42 
43 File& File::operator= (const String& newPath)
44 {
45  fullPath = parseAbsolutePath (newPath);
46  return *this;
47 }
48 
49 File& File::operator= (const File& other)
50 {
51  fullPath = other.fullPath;
52  return *this;
53 }
54 
55 File::File (File&& other) noexcept
56  : fullPath (std::move (other.fullPath))
57 {
58 }
59 
60 File& File::operator= (File&& other) noexcept
61 {
62  fullPath = std::move (other.fullPath);
63  return *this;
64 }
65 
66 JUCE_DECLARE_DEPRECATED_STATIC (const File File::nonexistent{};)
67 
68 //==============================================================================
69 static String removeEllipsis (const String& path)
70 {
71  // This will quickly find both /../ and /./ at the expense of a minor
72  // false-positive performance hit when path elements end in a dot.
73  #if JUCE_WINDOWS
74  if (path.contains (".\\"))
75  #else
76  if (path.contains ("./"))
77  #endif
78  {
79  StringArray toks;
80  toks.addTokens (path, File::getSeparatorString(), {});
81  bool anythingChanged = false;
82 
83  for (int i = 1; i < toks.size(); ++i)
84  {
85  auto& t = toks[i];
86 
87  if (t == ".." && toks[i - 1] != "..")
88  {
89  anythingChanged = true;
90  toks.removeRange (i - 1, 2);
91  i = jmax (0, i - 2);
92  }
93  else if (t == ".")
94  {
95  anythingChanged = true;
96  toks.remove (i--);
97  }
98  }
99 
100  if (anythingChanged)
101  return toks.joinIntoString (File::getSeparatorString());
102  }
103 
104  return path;
105 }
106 
107 bool File::isRoot() const
108 {
109  return fullPath.isNotEmpty() && *this == getParentDirectory();
110 }
111 
112 String File::parseAbsolutePath (const String& p)
113 {
114  if (p.isEmpty())
115  return {};
116 
117 #if JUCE_WINDOWS
118  // Windows..
119  auto path = removeEllipsis (p.replaceCharacter ('/', '\\'));
120 
121  if (path.startsWithChar (getSeparatorChar()))
122  {
123  if (path[1] != getSeparatorChar())
124  {
125  /* When you supply a raw string to the File object constructor, it must be an absolute path.
126  If you're trying to parse a string that may be either a relative path or an absolute path,
127  you MUST provide a context against which the partial path can be evaluated - you can do
128  this by simply using File::getChildFile() instead of the File constructor. E.g. saying
129  "File::getCurrentWorkingDirectory().getChildFile (myUnknownPath)" would return an absolute
130  path if that's what was supplied, or would evaluate a partial path relative to the CWD.
131  */
132  jassertfalse;
133 
135  }
136  }
137  else if (! path.containsChar (':'))
138  {
139  /* When you supply a raw string to the File object constructor, it must be an absolute path.
140  If you're trying to parse a string that may be either a relative path or an absolute path,
141  you MUST provide a context against which the partial path can be evaluated - you can do
142  this by simply using File::getChildFile() instead of the File constructor. E.g. saying
143  "File::getCurrentWorkingDirectory().getChildFile (myUnknownPath)" would return an absolute
144  path if that's what was supplied, or would evaluate a partial path relative to the CWD.
145  */
146  jassertfalse;
147 
149  }
150 #else
151  // Mac or Linux..
152 
153  // Yes, I know it's legal for a unix pathname to contain a backslash, but this assertion is here
154  // to catch anyone who's trying to run code that was written on Windows with hard-coded path names.
155  // If that's why you've ended up here, use File::getChildFile() to build your paths instead.
156  jassert ((! p.containsChar ('\\')) || (p.indexOfChar ('/') >= 0 && p.indexOfChar ('/') < p.indexOfChar ('\\')));
157 
158  auto path = removeEllipsis (p);
159 
160  if (path.startsWithChar ('~'))
161  {
162  if (path[1] == getSeparatorChar() || path[1] == 0)
163  {
164  // expand a name of the form "~/abc"
166  + path.substring (1);
167  }
168  else
169  {
170  // expand a name of type "~dave/abc"
171  auto userName = path.substring (1).upToFirstOccurrenceOf ("/", false, false);
172 
173  if (auto* pw = getpwnam (userName.toUTF8()))
174  path = addTrailingSeparator (pw->pw_dir) + path.fromFirstOccurrenceOf ("/", false, false);
175  }
176  }
177  else if (! path.startsWithChar (getSeparatorChar()))
178  {
179  #if JUCE_DEBUG || JUCE_LOG_ASSERTIONS
180  if (! (path.startsWith ("./") || path.startsWith ("../")))
181  {
182  /* When you supply a raw string to the File object constructor, it must be an absolute path.
183  If you're trying to parse a string that may be either a relative path or an absolute path,
184  you MUST provide a context against which the partial path can be evaluated - you can do
185  this by simply using File::getChildFile() instead of the File constructor. E.g. saying
186  "File::getCurrentWorkingDirectory().getChildFile (myUnknownPath)" would return an absolute
187  path if that's what was supplied, or would evaluate a partial path relative to the CWD.
188  */
189  jassertfalse;
190 
191  #if JUCE_LOG_ASSERTIONS
192  Logger::writeToLog ("Illegal absolute path: " + path);
193  #endif
194  }
195  #endif
196 
198  }
199 #endif
200 
201  while (path.endsWithChar (getSeparatorChar()) && path != getSeparatorString()) // careful not to turn a single "/" into an empty string.
202  path = path.dropLastCharacters (1);
203 
204  return path;
205 }
206 
208 {
209  return path.endsWithChar (getSeparatorChar()) ? path
210  : path + getSeparatorChar();
211 }
212 
213 //==============================================================================
214 #if JUCE_LINUX
215  #define NAMES_ARE_CASE_SENSITIVE 1
216 #endif
217 
219 {
220  #if NAMES_ARE_CASE_SENSITIVE
221  return true;
222  #else
223  return false;
224  #endif
225 }
226 
227 static int compareFilenames (const String& name1, const String& name2) noexcept
228 {
229  #if NAMES_ARE_CASE_SENSITIVE
230  return name1.compare (name2);
231  #else
232  return name1.compareIgnoreCase (name2);
233  #endif
234 }
235 
236 bool File::operator== (const File& other) const { return compareFilenames (fullPath, other.fullPath) == 0; }
237 bool File::operator!= (const File& other) const { return compareFilenames (fullPath, other.fullPath) != 0; }
238 bool File::operator< (const File& other) const { return compareFilenames (fullPath, other.fullPath) < 0; }
239 bool File::operator> (const File& other) const { return compareFilenames (fullPath, other.fullPath) > 0; }
240 
241 //==============================================================================
242 bool File::setReadOnly (const bool shouldBeReadOnly,
243  const bool applyRecursively) const
244 {
245  bool worked = true;
246 
247  if (applyRecursively && isDirectory())
248  for (auto& f : findChildFiles (File::findFilesAndDirectories, false))
249  worked = f.setReadOnly (shouldBeReadOnly, true) && worked;
250 
251  return setFileReadOnlyInternal (shouldBeReadOnly) && worked;
252 }
253 
254 bool File::setExecutePermission (bool shouldBeExecutable) const
255 {
256  return setFileExecutableInternal (shouldBeExecutable);
257 }
258 
259 bool File::deleteRecursively (bool followSymlinks) const
260 {
261  bool worked = true;
262 
263  if (isDirectory() && (followSymlinks || ! isSymbolicLink()))
264  for (auto& f : findChildFiles (File::findFilesAndDirectories, false))
265  worked = f.deleteRecursively (followSymlinks) && worked;
266 
267  return deleteFile() && worked;
268 }
269 
270 bool File::moveFileTo (const File& newFile) const
271 {
272  if (newFile.fullPath == fullPath)
273  return true;
274 
275  if (! exists())
276  return false;
277 
278  #if ! NAMES_ARE_CASE_SENSITIVE
279  if (*this != newFile)
280  #endif
281  if (! newFile.deleteFile())
282  return false;
283 
284  return moveInternal (newFile);
285 }
286 
287 bool File::copyFileTo (const File& newFile) const
288 {
289  return (*this == newFile)
290  || (exists() && newFile.deleteFile() && copyInternal (newFile));
291 }
292 
293 bool File::replaceFileIn (const File& newFile) const
294 {
295  if (newFile.fullPath == fullPath)
296  return true;
297 
298  if (! newFile.exists())
299  return moveFileTo (newFile);
300 
301  if (! replaceInternal (newFile))
302  return false;
303 
304  deleteFile();
305  return true;
306 }
307 
308 bool File::copyDirectoryTo (const File& newDirectory) const
309 {
310  if (isDirectory() && newDirectory.createDirectory())
311  {
312  for (auto& f : findChildFiles (File::findFiles, false))
313  if (! f.copyFileTo (newDirectory.getChildFile (f.getFileName())))
314  return false;
315 
316  for (auto& f : findChildFiles (File::findDirectories, false))
317  if (! f.copyDirectoryTo (newDirectory.getChildFile (f.getFileName())))
318  return false;
319 
320  return true;
321  }
322 
323  return false;
324 }
325 
326 //==============================================================================
327 String File::getPathUpToLastSlash() const
328 {
329  auto lastSlash = fullPath.lastIndexOfChar (getSeparatorChar());
330 
331  if (lastSlash > 0)
332  return fullPath.substring (0, lastSlash);
333 
334  if (lastSlash == 0)
335  return getSeparatorString();
336 
337  return fullPath;
338 }
339 
341 {
342  return createFileWithoutCheckingPath (getPathUpToLastSlash());
343 }
344 
345 //==============================================================================
347 {
348  return fullPath.substring (fullPath.lastIndexOfChar (getSeparatorChar()) + 1);
349 }
350 
352 {
353  auto lastSlash = fullPath.lastIndexOfChar (getSeparatorChar()) + 1;
354  auto lastDot = fullPath.lastIndexOfChar ('.');
355 
356  if (lastDot > lastSlash)
357  return fullPath.substring (lastSlash, lastDot);
358 
359  return fullPath.substring (lastSlash);
360 }
361 
362 bool File::isAChildOf (const File& potentialParent) const
363 {
364  if (potentialParent.fullPath.isEmpty())
365  return false;
366 
367  auto ourPath = getPathUpToLastSlash();
368 
369  if (compareFilenames (potentialParent.fullPath, ourPath) == 0)
370  return true;
371 
372  if (potentialParent.fullPath.length() >= ourPath.length())
373  return false;
374 
375  return getParentDirectory().isAChildOf (potentialParent);
376 }
377 
378 int File::hashCode() const { return fullPath.hashCode(); }
379 int64 File::hashCode64() const { return fullPath.hashCode64(); }
380 
381 //==============================================================================
383 {
384  auto firstChar = *(path.text);
385 
386  return firstChar == getSeparatorChar()
387  #if JUCE_WINDOWS
388  || (firstChar != 0 && path.text[1] == ':');
389  #else
390  || firstChar == '~';
391  #endif
392 }
393 
394 File File::getChildFile (StringRef relativePath) const
395 {
396  auto r = relativePath.text;
397 
398  if (isAbsolutePath (r))
399  return File (String (r));
400 
401  #if JUCE_WINDOWS
402  if (r.indexOf ((juce_wchar) '/') >= 0)
403  return getChildFile (String (r).replaceCharacter ('/', '\\'));
404  #endif
405 
406  auto path = fullPath;
407  auto separatorChar = getSeparatorChar();
408 
409  while (*r == '.')
410  {
411  auto lastPos = r;
412  auto secondChar = *++r;
413 
414  if (secondChar == '.') // remove "../"
415  {
416  auto thirdChar = *++r;
417 
418  if (thirdChar == separatorChar || thirdChar == 0)
419  {
420  auto lastSlash = path.lastIndexOfChar (separatorChar);
421 
422  if (lastSlash >= 0)
423  path = path.substring (0, lastSlash);
424 
425  while (*r == separatorChar) // ignore duplicate slashes
426  ++r;
427  }
428  else
429  {
430  r = lastPos;
431  break;
432  }
433  }
434  else if (secondChar == separatorChar || secondChar == 0) // remove "./"
435  {
436  while (*r == separatorChar) // ignore duplicate slashes
437  ++r;
438  }
439  else
440  {
441  r = lastPos;
442  break;
443  }
444  }
445 
446  path = addTrailingSeparator (path);
447  path.appendCharPointer (r);
448  return File (path);
449 }
450 
452 {
453  return getParentDirectory().getChildFile (fileName);
454 }
455 
456 //==============================================================================
458 {
459  const char* suffix;
460  double divisor = 0;
461 
462  if (bytes == 1) { suffix = " byte"; }
463  else if (bytes < 1024) { suffix = " bytes"; }
464  else if (bytes < 1024 * 1024) { suffix = " KB"; divisor = 1024.0; }
465  else if (bytes < 1024 * 1024 * 1024) { suffix = " MB"; divisor = 1024.0 * 1024.0; }
466  else { suffix = " GB"; divisor = 1024.0 * 1024.0 * 1024.0; }
467 
468  return (divisor > 0 ? String (bytes / divisor, 1) : String (bytes)) + suffix;
469 }
470 
471 //==============================================================================
473 {
474  if (exists())
475  return Result::ok();
476 
477  auto parentDir = getParentDirectory();
478 
479  if (parentDir == *this)
480  return Result::fail ("Cannot create parent directory");
481 
482  auto r = parentDir.createDirectory();
483 
484  if (r.wasOk())
485  {
486  FileOutputStream fo (*this, 8);
487  r = fo.getStatus();
488  }
489 
490  return r;
491 }
492 
494 {
495  if (isDirectory())
496  return Result::ok();
497 
498  auto parentDir = getParentDirectory();
499 
500  if (parentDir == *this)
501  return Result::fail ("Cannot create parent directory");
502 
503  auto r = parentDir.createDirectory();
504 
505  if (r.wasOk())
506  r = createDirectoryInternal (fullPath.trimCharactersAtEnd (getSeparatorString()));
507 
508  return r;
509 }
510 
511 //==============================================================================
512 Time File::getLastModificationTime() const { int64 m, a, c; getFileTimesInternal (m, a, c); return Time (m); }
513 Time File::getLastAccessTime() const { int64 m, a, c; getFileTimesInternal (m, a, c); return Time (a); }
514 Time File::getCreationTime() const { int64 m, a, c; getFileTimesInternal (m, a, c); return Time (c); }
515 
516 bool File::setLastModificationTime (Time t) const { return setFileTimesInternal (t.toMilliseconds(), 0, 0); }
517 bool File::setLastAccessTime (Time t) const { return setFileTimesInternal (0, t.toMilliseconds(), 0); }
518 bool File::setCreationTime (Time t) const { return setFileTimesInternal (0, 0, t.toMilliseconds()); }
519 
520 //==============================================================================
521 bool File::loadFileAsData (MemoryBlock& destBlock) const
522 {
523  if (! existsAsFile())
524  return false;
525 
526  FileInputStream in (*this);
527  return in.openedOk() && getSize() == (int64) in.readIntoMemoryBlock (destBlock);
528 }
529 
531 {
532  if (! existsAsFile())
533  return {};
534 
535  FileInputStream in (*this);
536  return in.openedOk() ? in.readEntireStreamAsString()
537  : String();
538 }
539 
540 void File::readLines (StringArray& destLines) const
541 {
542  destLines.addLines (loadFileAsString());
543 }
544 
545 //==============================================================================
546 Array<File> File::findChildFiles (int whatToLookFor, bool searchRecursively, const String& wildcard) const
547 {
548  Array<File> results;
549  findChildFiles (results, whatToLookFor, searchRecursively, wildcard);
550  return results;
551 }
552 
553 int File::findChildFiles (Array<File>& results, int whatToLookFor, bool searchRecursively, const String& wildcard) const
554 {
555  int total = 0;
556 
557  for (DirectoryIterator di (*this, searchRecursively, wildcard, whatToLookFor); di.next();)
558  {
559  results.add (di.getFile());
560  ++total;
561  }
562 
563  return total;
564 }
565 
566 int File::getNumberOfChildFiles (const int whatToLookFor, const String& wildCardPattern) const
567 {
568  int total = 0;
569 
570  for (DirectoryIterator di (*this, false, wildCardPattern, whatToLookFor); di.next();)
571  ++total;
572 
573  return total;
574 }
575 
577 {
578  if (! isDirectory())
579  return false;
580 
581  DirectoryIterator di (*this, false, "*", findDirectories);
582  return di.next();
583 }
584 
585 //==============================================================================
586 File File::getNonexistentChildFile (const String& suggestedPrefix,
587  const String& suffix,
588  bool putNumbersInBrackets) const
589 {
590  auto f = getChildFile (suggestedPrefix + suffix);
591 
592  if (f.exists())
593  {
594  int number = 1;
595  auto prefix = suggestedPrefix;
596 
597  // remove any bracketed numbers that may already be on the end..
598  if (prefix.trim().endsWithChar (')'))
599  {
600  putNumbersInBrackets = true;
601 
602  auto openBracks = prefix.lastIndexOfChar ('(');
603  auto closeBracks = prefix.lastIndexOfChar (')');
604 
605  if (openBracks > 0
606  && closeBracks > openBracks
607  && prefix.substring (openBracks + 1, closeBracks).containsOnly ("0123456789"))
608  {
609  number = prefix.substring (openBracks + 1, closeBracks).getIntValue();
610  prefix = prefix.substring (0, openBracks);
611  }
612  }
613 
614  do
615  {
616  auto newName = prefix;
617 
618  if (putNumbersInBrackets)
619  {
620  newName << '(' << ++number << ')';
621  }
622  else
623  {
624  if (CharacterFunctions::isDigit (prefix.getLastCharacter()))
625  newName << '_'; // pad with an underscore if the name already ends in a digit
626 
627  newName << ++number;
628  }
629 
630  f = getChildFile (newName + suffix);
631 
632  } while (f.exists());
633  }
634 
635  return f;
636 }
637 
638 File File::getNonexistentSibling (const bool putNumbersInBrackets) const
639 {
640  if (! exists())
641  return *this;
642 
645  putNumbersInBrackets);
646 }
647 
648 //==============================================================================
650 {
651  auto indexOfDot = fullPath.lastIndexOfChar ('.');
652 
653  if (indexOfDot > fullPath.lastIndexOfChar (getSeparatorChar()))
654  return fullPath.substring (indexOfDot);
655 
656  return {};
657 }
658 
659 bool File::hasFileExtension (StringRef possibleSuffix) const
660 {
661  if (possibleSuffix.isEmpty())
662  return fullPath.lastIndexOfChar ('.') <= fullPath.lastIndexOfChar (getSeparatorChar());
663 
664  auto semicolon = possibleSuffix.text.indexOf ((juce_wchar) ';');
665 
666  if (semicolon >= 0)
667  return hasFileExtension (String (possibleSuffix.text).substring (0, semicolon).trimEnd())
668  || hasFileExtension ((possibleSuffix.text + (semicolon + 1)).findEndOfWhitespace());
669 
670  if (fullPath.endsWithIgnoreCase (possibleSuffix))
671  {
672  if (possibleSuffix.text[0] == '.')
673  return true;
674 
675  auto dotPos = fullPath.length() - possibleSuffix.length() - 1;
676 
677  if (dotPos >= 0)
678  return fullPath[dotPos] == '.';
679  }
680 
681  return false;
682 }
683 
685 {
686  if (fullPath.isEmpty())
687  return {};
688 
689  auto filePart = getFileName();
690 
691  auto lastDot = filePart.lastIndexOfChar ('.');
692 
693  if (lastDot >= 0)
694  filePart = filePart.substring (0, lastDot);
695 
696  if (newExtension.isNotEmpty() && newExtension.text[0] != '.')
697  filePart << '.';
698 
699  return getSiblingFile (filePart + newExtension);
700 }
701 
702 //==============================================================================
703 bool File::startAsProcess (const String& parameters) const
704 {
705  return exists() && Process::openDocument (fullPath, parameters);
706 }
707 
708 //==============================================================================
710 {
711  std::unique_ptr<FileInputStream> fin (new FileInputStream (*this));
712 
713  if (fin->openedOk())
714  return fin.release();
715 
716  return nullptr;
717 }
718 
719 FileOutputStream* File::createOutputStream (size_t bufferSize) const
720 {
721  std::unique_ptr<FileOutputStream> out (new FileOutputStream (*this, bufferSize));
722 
723  return out->failedToOpen() ? nullptr
724  : out.release();
725 }
726 
727 //==============================================================================
728 bool File::appendData (const void* const dataToAppend,
729  const size_t numberOfBytes) const
730 {
731  jassert (((ssize_t) numberOfBytes) >= 0);
732 
733  if (numberOfBytes == 0)
734  return true;
735 
736  FileOutputStream out (*this, 8192);
737  return out.openedOk() && out.write (dataToAppend, numberOfBytes);
738 }
739 
740 bool File::replaceWithData (const void* const dataToWrite,
741  const size_t numberOfBytes) const
742 {
743  if (numberOfBytes == 0)
744  return deleteFile();
745 
747  tempFile.getFile().appendData (dataToWrite, numberOfBytes);
748  return tempFile.overwriteTargetFileWithTemporary();
749 }
750 
751 bool File::appendText (const String& text, bool asUnicode, bool writeHeaderBytes, const char* lineFeed) const
752 {
753  FileOutputStream out (*this);
754 
755  if (out.failedToOpen())
756  return false;
757 
758  return out.writeText (text, asUnicode, writeHeaderBytes, lineFeed);
759 }
760 
761 bool File::replaceWithText (const String& textToWrite, bool asUnicode, bool writeHeaderBytes, const char* lineFeed) const
762 {
764  tempFile.getFile().appendText (textToWrite, asUnicode, writeHeaderBytes, lineFeed);
765  return tempFile.overwriteTargetFileWithTemporary();
766 }
767 
768 bool File::hasIdenticalContentTo (const File& other) const
769 {
770  if (other == *this)
771  return true;
772 
773  if (getSize() == other.getSize() && existsAsFile() && other.existsAsFile())
774  {
775  FileInputStream in1 (*this), in2 (other);
776 
777  if (in1.openedOk() && in2.openedOk())
778  {
779  const int bufferSize = 4096;
780  HeapBlock<char> buffer1 (bufferSize), buffer2 (bufferSize);
781 
782  for (;;)
783  {
784  auto num1 = in1.read (buffer1, bufferSize);
785  auto num2 = in2.read (buffer2, bufferSize);
786 
787  if (num1 != num2)
788  break;
789 
790  if (num1 <= 0)
791  return true;
792 
793  if (memcmp (buffer1, buffer2, (size_t) num1) != 0)
794  break;
795  }
796  }
797  }
798 
799  return false;
800 }
801 
802 //==============================================================================
804 {
805  auto s = original;
806  String start;
807 
808  if (s.isNotEmpty() && s[1] == ':')
809  {
810  start = s.substring (0, 2);
811  s = s.substring (2);
812  }
813 
814  return start + s.removeCharacters ("\"#@,;:<>*^|?")
815  .substring (0, 1024);
816 }
817 
819 {
820  auto s = original.removeCharacters ("\"#@,;:<>*^|?\\/");
821 
822  const int maxLength = 128; // only the length of the filename, not the whole path
823  auto len = s.length();
824 
825  if (len > maxLength)
826  {
827  auto lastDot = s.lastIndexOfChar ('.');
828 
829  if (lastDot > jmax (0, len - 12))
830  {
831  s = s.substring (0, maxLength - (len - lastDot))
832  + s.substring (lastDot);
833  }
834  else
835  {
836  s = s.substring (0, maxLength);
837  }
838  }
839 
840  return s;
841 }
842 
843 //==============================================================================
844 static int countNumberOfSeparators (String::CharPointerType s)
845 {
846  int num = 0;
847 
848  for (;;)
849  {
850  auto c = s.getAndAdvance();
851 
852  if (c == 0)
853  break;
854 
855  if (c == File::getSeparatorChar())
856  ++num;
857  }
858 
859  return num;
860 }
861 
863 {
864  if (dir == *this)
865  return ".";
866 
867  auto thisPath = fullPath;
868 
869  while (thisPath.endsWithChar (getSeparatorChar()))
870  thisPath = thisPath.dropLastCharacters (1);
871 
873  : dir.fullPath);
874 
875  int commonBitLength = 0;
876  auto thisPathAfterCommon = thisPath.getCharPointer();
877  auto dirPathAfterCommon = dirPath.getCharPointer();
878 
879  {
880  auto thisPathIter = thisPath.getCharPointer();
881  auto dirPathIter = dirPath.getCharPointer();
882 
883  for (int i = 0;;)
884  {
885  auto c1 = thisPathIter.getAndAdvance();
886  auto c2 = dirPathIter.getAndAdvance();
887 
888  #if NAMES_ARE_CASE_SENSITIVE
889  if (c1 != c2
890  #else
892  #endif
893  || c1 == 0)
894  break;
895 
896  ++i;
897 
898  if (c1 == getSeparatorChar())
899  {
900  thisPathAfterCommon = thisPathIter;
901  dirPathAfterCommon = dirPathIter;
902  commonBitLength = i;
903  }
904  }
905  }
906 
907  // if the only common bit is the root, then just return the full path..
908  if (commonBitLength == 0 || (commonBitLength == 1 && thisPath[1] == getSeparatorChar()))
909  return fullPath;
910 
911  auto numUpDirectoriesNeeded = countNumberOfSeparators (dirPathAfterCommon);
912 
913  if (numUpDirectoriesNeeded == 0)
914  return thisPathAfterCommon;
915 
916  #if JUCE_WINDOWS
917  auto s = String::repeatedString ("..\\", numUpDirectoriesNeeded);
918  #else
919  auto s = String::repeatedString ("../", numUpDirectoriesNeeded);
920  #endif
921  s.appendCharPointer (thisPathAfterCommon);
922  return s;
923 }
924 
925 //==============================================================================
927 {
928  auto tempFile = getSpecialLocation (tempDirectory)
929  .getChildFile ("temp_" + String::toHexString (Random::getSystemRandom().nextInt()))
930  .withFileExtension (fileNameEnding);
931 
932  if (tempFile.exists())
933  return createTempFile (fileNameEnding);
934 
935  return tempFile;
936 }
937 
938 bool File::createSymbolicLink (const File& linkFileToCreate,
939  const String& nativePathOfTarget,
940  bool overwriteExisting)
941 {
942  if (linkFileToCreate.exists())
943  {
944  if (! linkFileToCreate.isSymbolicLink())
945  {
946  // user has specified an existing file / directory as the link
947  // this is bad! the user could end up unintentionally destroying data
948  jassertfalse;
949  return false;
950  }
951 
952  if (overwriteExisting)
953  linkFileToCreate.deleteFile();
954  }
955 
956  #if JUCE_MAC || JUCE_LINUX
957  // one common reason for getting an error here is that the file already exists
958  if (symlink (nativePathOfTarget.toRawUTF8(), linkFileToCreate.getFullPathName().toRawUTF8()) == -1)
959  {
960  jassertfalse;
961  return false;
962  }
963 
964  return true;
965  #elif JUCE_MSVC
966  File targetFile (linkFileToCreate.getSiblingFile (nativePathOfTarget));
967 
968  return CreateSymbolicLink (linkFileToCreate.getFullPathName().toWideCharPointer(),
969  nativePathOfTarget.toWideCharPointer(),
970  targetFile.isDirectory() ? SYMBOLIC_LINK_FLAG_DIRECTORY : 0) != FALSE;
971  #else
972  ignoreUnused (nativePathOfTarget);
973  jassertfalse; // symbolic links not supported on this platform!
974  return false;
975  #endif
976 }
977 
978 bool File::createSymbolicLink (const File& linkFileToCreate, bool overwriteExisting) const
979 {
980  return createSymbolicLink (linkFileToCreate, getFullPathName(), overwriteExisting);
981 }
982 
983 #if ! JUCE_WINDOWS
985 {
986  if (isSymbolicLink())
988 
989  return *this;
990 }
991 #endif
992 
993 //==============================================================================
995  : range (0, file.getSize())
996 {
997  openInternal (file, mode, exclusive);
998 }
999 
1000 MemoryMappedFile::MemoryMappedFile (const File& file, const Range<int64>& fileRange, AccessMode mode, bool exclusive)
1001  : range (fileRange.getIntersectionWith (Range<int64> (0, file.getSize())))
1002 {
1003  openInternal (file, mode, exclusive);
1004 }
1005 
1006 
1007 //==============================================================================
1008 #if JUCE_UNIT_TESTS
1009 
1010 class FileTests : public UnitTest
1011 {
1012 public:
1013  FileTests() : UnitTest ("Files", "Files") {}
1014 
1015  void runTest() override
1016  {
1017  beginTest ("Reading");
1018 
1020  const File temp (File::getSpecialLocation (File::tempDirectory));
1021 
1022  expect (! File().exists());
1023  expect (! File().existsAsFile());
1024  expect (! File().isDirectory());
1025  #if ! JUCE_WINDOWS
1026  expect (File("/").isDirectory());
1027  #endif
1028  expect (home.isDirectory());
1029  expect (home.exists());
1030  expect (! home.existsAsFile());
1031  expect (File::getSpecialLocation (File::userDocumentsDirectory).isDirectory());
1036  expect (home.getVolumeTotalSize() > 1024 * 1024);
1037  expect (home.getBytesFreeOnVolume() > 0);
1038  expect (! home.isHidden());
1039  expect (home.isOnHardDisk());
1040  expect (! home.isOnCDRomDrive());
1041  expect (File::getCurrentWorkingDirectory().exists());
1042  expect (home.setAsCurrentWorkingDirectory());
1043  expect (File::getCurrentWorkingDirectory() == home);
1044 
1045  {
1046  Array<File> roots;
1047  File::findFileSystemRoots (roots);
1048  expect (roots.size() > 0);
1049 
1050  int numRootsExisting = 0;
1051  for (int i = 0; i < roots.size(); ++i)
1052  if (roots[i].exists())
1053  ++numRootsExisting;
1054 
1055  // (on windows, some of the drives may not contain media, so as long as at least one is ok..)
1056  expect (numRootsExisting > 0);
1057  }
1058 
1059  beginTest ("Writing");
1060 
1061  File demoFolder (temp.getChildFile ("JUCE UnitTests Temp Folder.folder"));
1062  expect (demoFolder.deleteRecursively());
1063  expect (demoFolder.createDirectory());
1064  expect (demoFolder.isDirectory());
1065  expect (demoFolder.getParentDirectory() == temp);
1066  expect (temp.isDirectory());
1067  expect (temp.findChildFiles (File::findFilesAndDirectories, false, "*").contains (demoFolder));
1068  expect (temp.findChildFiles (File::findDirectories, true, "*.folder").contains (demoFolder));
1069 
1070  File tempFile (demoFolder.getNonexistentChildFile ("test", ".txt", false));
1071 
1072  expect (tempFile.getFileExtension() == ".txt");
1073  expect (tempFile.hasFileExtension (".txt"));
1074  expect (tempFile.hasFileExtension ("txt"));
1075  expect (tempFile.withFileExtension ("xyz").hasFileExtension (".xyz"));
1076  expect (tempFile.withFileExtension ("xyz").hasFileExtension ("abc;xyz;foo"));
1077  expect (tempFile.withFileExtension ("xyz").hasFileExtension ("xyz;foo"));
1078  expect (! tempFile.withFileExtension ("h").hasFileExtension ("bar;foo;xx"));
1079  expect (tempFile.getSiblingFile ("foo").isAChildOf (temp));
1080  expect (tempFile.hasWriteAccess());
1081 
1082  expect (home.getChildFile (".") == home);
1083  expect (home.getChildFile ("..") == home.getParentDirectory());
1084  expect (home.getChildFile (".xyz").getFileName() == ".xyz");
1085  expect (home.getChildFile ("..xyz").getFileName() == "..xyz");
1086  expect (home.getChildFile ("...xyz").getFileName() == "...xyz");
1087  expect (home.getChildFile ("./xyz") == home.getChildFile ("xyz"));
1088  expect (home.getChildFile ("././xyz") == home.getChildFile ("xyz"));
1089  expect (home.getChildFile ("../xyz") == home.getParentDirectory().getChildFile ("xyz"));
1090  expect (home.getChildFile (".././xyz") == home.getParentDirectory().getChildFile ("xyz"));
1091  expect (home.getChildFile (".././xyz/./abc") == home.getParentDirectory().getChildFile ("xyz/abc"));
1092  expect (home.getChildFile ("./../xyz") == home.getParentDirectory().getChildFile ("xyz"));
1093  expect (home.getChildFile ("a1/a2/a3/./../../a4") == home.getChildFile ("a1/a4"));
1094 
1095  {
1096  FileOutputStream fo (tempFile);
1097  fo.write ("0123456789", 10);
1098  }
1099 
1100  expect (tempFile.exists());
1101  expect (tempFile.getSize() == 10);
1102  expect (std::abs ((int) (tempFile.getLastModificationTime().toMilliseconds() - Time::getCurrentTime().toMilliseconds())) < 3000);
1103  expectEquals (tempFile.loadFileAsString(), String ("0123456789"));
1104  expect (! demoFolder.containsSubDirectories());
1105 
1106  expectEquals (tempFile.getRelativePathFrom (demoFolder.getParentDirectory()), demoFolder.getFileName() + File::getSeparatorString() + tempFile.getFileName());
1107  expectEquals (demoFolder.getParentDirectory().getRelativePathFrom (tempFile), ".." + File::getSeparatorString() + ".." + File::getSeparatorString() + demoFolder.getParentDirectory().getFileName());
1108 
1109  expect (demoFolder.getNumberOfChildFiles (File::findFiles) == 1);
1110  expect (demoFolder.getNumberOfChildFiles (File::findFilesAndDirectories) == 1);
1111  expect (demoFolder.getNumberOfChildFiles (File::findDirectories) == 0);
1112  demoFolder.getNonexistentChildFile ("tempFolder", "", false).createDirectory();
1113  expect (demoFolder.getNumberOfChildFiles (File::findDirectories) == 1);
1114  expect (demoFolder.getNumberOfChildFiles (File::findFilesAndDirectories) == 2);
1115  expect (demoFolder.containsSubDirectories());
1116 
1117  expect (tempFile.hasWriteAccess());
1118  tempFile.setReadOnly (true);
1119  expect (! tempFile.hasWriteAccess());
1120  tempFile.setReadOnly (false);
1121  expect (tempFile.hasWriteAccess());
1122 
1123  Time t (Time::getCurrentTime());
1124  tempFile.setLastModificationTime (t);
1125  Time t2 = tempFile.getLastModificationTime();
1126  expect (std::abs ((int) (t2.toMilliseconds() - t.toMilliseconds())) <= 1000);
1127 
1128  {
1129  MemoryBlock mb;
1130  tempFile.loadFileAsData (mb);
1131  expect (mb.getSize() == 10);
1132  expect (mb[0] == '0');
1133  }
1134 
1135  {
1136  expect (tempFile.getSize() == 10);
1137  FileOutputStream fo (tempFile);
1138  expect (fo.openedOk());
1139 
1140  expect (fo.setPosition (7));
1141  expect (fo.truncate().wasOk());
1142  expect (tempFile.getSize() == 7);
1143  fo.write ("789", 3);
1144  fo.flush();
1145  expect (tempFile.getSize() == 10);
1146  }
1147 
1148  beginTest ("Memory-mapped files");
1149 
1150  {
1151  MemoryMappedFile mmf (tempFile, MemoryMappedFile::readOnly);
1152  expect (mmf.getSize() == 10);
1153  expect (mmf.getData() != nullptr);
1154  expect (memcmp (mmf.getData(), "0123456789", 10) == 0);
1155  }
1156 
1157  {
1158  const File tempFile2 (tempFile.getNonexistentSibling (false));
1159  expect (tempFile2.create());
1160  expect (tempFile2.appendData ("xxxxxxxxxx", 10));
1161 
1162  {
1163  MemoryMappedFile mmf (tempFile2, MemoryMappedFile::readWrite);
1164  expect (mmf.getSize() == 10);
1165  expect (mmf.getData() != nullptr);
1166  memcpy (mmf.getData(), "abcdefghij", 10);
1167  }
1168 
1169  {
1170  MemoryMappedFile mmf (tempFile2, MemoryMappedFile::readWrite);
1171  expect (mmf.getSize() == 10);
1172  expect (mmf.getData() != nullptr);
1173  expect (memcmp (mmf.getData(), "abcdefghij", 10) == 0);
1174  }
1175 
1176  expect (tempFile2.deleteFile());
1177  }
1178 
1179  beginTest ("More writing");
1180 
1181  expect (tempFile.appendData ("abcdefghij", 10));
1182  expect (tempFile.getSize() == 20);
1183  expect (tempFile.replaceWithData ("abcdefghij", 10));
1184  expect (tempFile.getSize() == 10);
1185 
1186  File tempFile2 (tempFile.getNonexistentSibling (false));
1187  expect (tempFile.copyFileTo (tempFile2));
1188  expect (tempFile2.exists());
1189  expect (tempFile2.hasIdenticalContentTo (tempFile));
1190  expect (tempFile.deleteFile());
1191  expect (! tempFile.exists());
1192  expect (tempFile2.moveFileTo (tempFile));
1193  expect (tempFile.exists());
1194  expect (! tempFile2.exists());
1195 
1196  expect (demoFolder.deleteRecursively());
1197  expect (! demoFolder.exists());
1198  }
1199 };
1200 
1201 static FileTests fileUnitTests;
1202 
1203 #endif
1204 
1205 } // namespace juce
juce::File::loadFileAsString
String loadFileAsString() const
Reads a file into memory as a string.
Definition: juce_File.cpp:530
juce::StringArray
A special array for holding a list of strings.
Definition: juce_StringArray.h:38
juce::File::descriptionOfSizeInBytes
static String descriptionOfSizeInBytes(int64 bytes)
Utility function to convert a file size in bytes to a neat string description.
Definition: juce_File.cpp:457
juce::File::getLinkedTarget
File getLinkedTarget() const
If this file is a link or alias, this returns the file that it points to.
Definition: juce_File.cpp:984
juce::String::toRawUTF8
const char * toRawUTF8() const
Returns a pointer to a UTF-8 version of this string.
Definition: juce_String.cpp:2072
juce::File::getFileName
String getFileName() const
Returns the last section of the pathname.
Definition: juce_File.cpp:346
juce::File::getNonexistentSibling
File getNonexistentSibling(bool putNumbersInBrackets=true) const
Chooses a filename for a sibling file to this one that doesn't already exist.
Definition: juce_File.cpp:638
juce::StringRef
A simple class for holding temporary references to a string literal or String.
Definition: juce_StringRef.h:65
juce::File::setLastModificationTime
bool setLastModificationTime(Time newTime) const
Changes the modification time for this file.
Definition: juce_File.cpp:516
juce::DirectoryIterator::next
bool next()
Moves the iterator along to the next file.
Definition: juce_DirectoryIterator.cpp:62
juce::String::containsChar
bool containsChar(juce_wchar character) const noexcept
Tests whether the string contains a particular character.
Definition: juce_String.cpp:1046
juce::TemporaryFile::useHiddenFile
@ useHiddenFile
Indicates that the temporary file should be hidden - i.e.
Definition: juce_TemporaryFile.h:74
juce::File::operator!=
bool operator!=(const File &) const
Compares the pathnames for two files.
Definition: juce_File.cpp:237
juce::File::findDirectories
@ findDirectories
Use this flag to indicate that you want to find directories.
Definition: juce_File.h:553
juce::File::isDirectory
bool isDirectory() const
Checks whether the file is a directory that exists.
juce::HeapBlock< char >
juce::File::hasIdenticalContentTo
bool hasIdenticalContentTo(const File &other) const
Attempts to scan the contents of this file and compare it to another file, returning true if this is ...
Definition: juce_File.cpp:768
juce::File::moveFileTo
bool moveFileTo(const File &targetLocation) const
Moves or renames a file.
Definition: juce_File.cpp:270
juce::String::lastIndexOfChar
int lastIndexOfChar(juce_wchar character) const noexcept
Searches for a character inside this string (working backwards from the end of the string).
Definition: juce_String.cpp:905
juce::File::getParentDirectory
File getParentDirectory() const
Returns the directory that contains this file or directory.
Definition: juce_File.cpp:340
juce::File::isRoot
bool isRoot() const
Checks whether the path of this file represents the root of a file system, irrespective of its existe...
Definition: juce_File.cpp:107
juce::Result
Represents the 'success' or 'failure' of an operation, and holds an associated error message to descr...
Definition: juce_Result.h:60
juce::File::hashCode
int hashCode() const
Returns a 32-bit hash-code that identifies this file.
Definition: juce_File.cpp:378
juce::File::userDocumentsDirectory
@ userDocumentsDirectory
The user's default documents folder.
Definition: juce_File.h:842
juce::File::createTempFile
static File createTempFile(StringRef fileNameEnding)
Returns a temporary file in the system's temp directory.
Definition: juce_File.cpp:926
juce::FileOutputStream::failedToOpen
bool failedToOpen() const noexcept
Returns true if the stream couldn't be opened for some reason.
Definition: juce_FileOutputStream.h:90
juce::File::areFileNamesCaseSensitive
static bool areFileNamesCaseSensitive()
Indicates whether filenames are case-sensitive on the current operating system.
Definition: juce_File.cpp:218
juce::File::replaceWithText
bool replaceWithText(const String &textToWrite, bool asUnicode=false, bool writeUnicodeHeaderBytes=false, const char *lineEndings="\r\n") const
Replaces this file's contents with a given text string.
Definition: juce_File.cpp:761
juce::String::endsWithChar
bool endsWithChar(juce_wchar character) const noexcept
Tests whether the string ends with a particular character.
Definition: juce_String.cpp:1416
juce::File::readLines
void readLines(StringArray &destLines) const
Reads the contents of this file as text and splits it into lines, which are appended to the given Str...
Definition: juce_File.cpp:540
juce::FileOutputStream::getStatus
const Result & getStatus() const noexcept
Returns the status of the file stream.
Definition: juce_FileOutputStream.h:85
juce::FileInputStream::read
int read(void *, int) override
Reads some data from the stream into a memory buffer.
Definition: juce_FileInputStream.cpp:43
juce::File::createOutputStream
FileOutputStream * createOutputStream(size_t bufferSize=0x8000) const
Creates a stream to write to this file.
Definition: juce_File.cpp:719
juce::File::getSeparatorString
static StringRef getSeparatorString()
The system-specific file separator character, as a string.
juce::File::appendData
bool appendData(const void *dataToAppend, size_t numberOfBytes) const
Appends a block of binary data to the end of the file.
Definition: juce_File.cpp:728
juce::File::startAsProcess
bool startAsProcess(const String &parameters=String()) const
Launches the file as a process.
Definition: juce_File.cpp:703
juce::File::getCurrentWorkingDirectory
static File getCurrentWorkingDirectory()
Returns the current working directory.
juce::OutputStream::writeText
virtual bool writeText(const String &text, bool asUTF16, bool writeUTF16ByteOrderMark, const char *lineEndings)
Writes a string of text to the stream.
Definition: juce_OutputStream.cpp:187
juce::File::getFullPathName
const String & getFullPathName() const noexcept
Returns the complete, absolute path of this file.
Definition: juce_File.h:153
juce::Array::add
void add(const ElementType &newElement)
Appends a new element at the end of the array.
Definition: juce_Array.h:375
juce::File::operator==
bool operator==(const File &) const
Compares the pathnames for two files.
Definition: juce_File.cpp:236
juce::TemporaryFile
Manages a temporary file, which will be deleted when this object is deleted.
Definition: juce_TemporaryFile.h:68
juce::File::createDirectory
Result createDirectory() const
Creates a new directory for this filename.
Definition: juce_File.cpp:493
juce::File::isAChildOf
bool isAChildOf(const File &potentialParentDirectory) const
Checks whether a file is somewhere inside a directory.
Definition: juce_File.cpp:362
juce::File::getNonexistentChildFile
File getNonexistentChildFile(const String &prefix, const String &suffix, bool putNumbersInBrackets=true) const
Chooses a filename relative to this one that doesn't already exist.
Definition: juce_File.cpp:586
juce::String::hashCode64
int64 hashCode64() const noexcept
Generates a probably-unique 64-bit hashcode from this string.
Definition: juce_String.cpp:557
juce::File::getSpecialLocation
static File JUCE_CALLTYPE getSpecialLocation(const SpecialLocationType type)
Finds the location of a special type of file or directory, such as a home folder or documents folder.
juce::File::isAbsolutePath
static bool isAbsolutePath(StringRef path)
Returns true if the string seems to be a fully-specified absolute path.
Definition: juce_File.cpp:382
juce::File::getCreationTime
Time getCreationTime() const
Returns the time that this file was created.
Definition: juce_File.cpp:514
juce::Array
Holds a resizable array of primitive or copy-by-value objects.
Definition: juce_Array.h:59
juce::String::toHexString
static String toHexString(IntegerType number)
Returns a string representing this numeric value in hexadecimal.
Definition: juce_String.h:1055
juce::File::setCreationTime
bool setCreationTime(Time newTime) const
Changes the creation date for this file.
Definition: juce_File.cpp:518
juce::File::getFileNameWithoutExtension
String getFileNameWithoutExtension() const
Returns the last part of the filename, without its file extension.
Definition: juce_File.cpp:351
juce::Time::getCurrentTime
static Time JUCE_CALLTYPE getCurrentTime() noexcept
Returns a Time object that is set to the current system time.
Definition: juce_Time.cpp:218
juce::File::create
Result create() const
Creates an empty file if it doesn't already exist.
Definition: juce_File.cpp:472
juce::StringRef::length
int length() const noexcept
Returns the number of characters in the string.
Definition: juce_StringRef.h:109
juce::String::repeatedString
static String repeatedString(StringRef stringToRepeat, int numberOfTimesToRepeat)
Creates a string which is a version of a string repeated and joined together.
Definition: juce_String.cpp:1153
juce::File::createFileWithoutCheckingPath
static File createFileWithoutCheckingPath(const String &absolutePath) noexcept
Creates a file that simply contains this string, without doing the sanity-checking that the normal co...
Definition: juce_File.cpp:31
juce::DirectoryIterator
Searches through the files in a directory, returning each file that is found.
Definition: juce_DirectoryIterator.h:50
juce::StringRef::text
String::CharPointerType text
The text that is referenced.
Definition: juce_StringRef.h:126
juce::File::getSiblingFile
File getSiblingFile(StringRef siblingFileName) const
Returns a file which is in the same directory as this one.
Definition: juce_File.cpp:451
juce::File::findFilesAndDirectories
@ findFilesAndDirectories
Use this flag to indicate that you want to find both files and directories.
Definition: juce_File.h:555
juce::CharPointer_UTF8::indexOf
int indexOf(const CharPointer stringToFind) const noexcept
Returns the character index of a substring, or -1 if it isn't found.
Definition: juce_CharPointer_UTF8.h:435
juce::FileInputStream::openedOk
bool openedOk() const noexcept
Returns true if the stream opened without problems.
Definition: juce_FileInputStream.h:71
juce::File::operator<
bool operator<(const File &) const
Compares the pathnames for two files.
Definition: juce_File.cpp:238
juce::File::operator=
File & operator=(const String &newAbsolutePath)
Sets the file based on an absolute pathname.
Definition: juce_File.cpp:43
juce::FileOutputStream::openedOk
bool openedOk() const noexcept
Returns true if the stream opened without problems.
Definition: juce_FileOutputStream.h:95
juce::String::endsWithIgnoreCase
bool endsWithIgnoreCase(StringRef text) const noexcept
Tests whether the string ends with another string.
Definition: juce_String.cpp:1444
juce::File
Represents a local file or directory.
Definition: juce_File.h:44
juce::MemoryMappedFile::readOnly
@ readOnly
Indicates that the memory can only be read.
Definition: juce_MemoryMappedFile.h:42
juce::File::loadFileAsData
bool loadFileAsData(MemoryBlock &result) const
Loads a file's contents into memory as a block of binary data.
Definition: juce_File.cpp:521
juce::File::setLastAccessTime
bool setLastAccessTime(Time newTime) const
Changes the last-access time for this file.
Definition: juce_File.cpp:517
juce::File::addTrailingSeparator
static String addTrailingSeparator(const String &path)
Adds a separator character to the end of a path if it doesn't already have one.
Definition: juce_File.cpp:207
juce::File::appendText
bool appendText(const String &textToAppend, bool asUnicode=false, bool writeUnicodeHeaderBytes=false, const char *lineEndings="\r\n") const
Appends a string to the end of the file.
Definition: juce_File.cpp:751
juce::String::replaceCharacter
String replaceCharacter(juce_wchar characterToReplace, juce_wchar characterToInsertInstead) const
Returns a string with all occurrences of a character replaced with a different one.
Definition: juce_String.cpp:1350
juce::File::invokedExecutableFile
@ invokedExecutableFile
Returns the file that was invoked to launch this executable.
Definition: juce_File.h:916
juce::Logger::writeToLog
static void JUCE_CALLTYPE writeToLog(const String &message)
Writes a string to the current logger.
Definition: juce_Logger.cpp:40
juce::File::setReadOnly
bool setReadOnly(bool shouldBeReadOnly, bool applyRecursively=false) const
Changes the write-permission of a file or directory.
Definition: juce_File.cpp:242
juce::File::deleteFile
bool deleteFile() const
Deletes a file.
juce::File::File
File()=default
Creates an (invalid) file object.
juce::MemoryMappedFile::MemoryMappedFile
MemoryMappedFile(const File &file, AccessMode mode, bool exclusive=false)
Opens a file and maps it to an area of virtual memory.
Definition: juce_File.cpp:994
juce::File::getNumberOfChildFiles
int getNumberOfChildFiles(int whatToLookFor, const String &wildCardPattern="*") const
Searches inside a directory and counts how many files match a wildcard pattern.
Definition: juce_File.cpp:566
juce::File::operator>
bool operator>(const File &) const
Compares the pathnames for two files.
Definition: juce_File.cpp:239
juce::File::exists
bool exists() const
Checks whether the file actually exists.
juce::Time::toMilliseconds
int64 toMilliseconds() const noexcept
Returns the time as a number of milliseconds.
Definition: juce_Time.h:102
juce::File::containsSubDirectories
bool containsSubDirectories() const
Returns true if this file is a directory that contains one or more subdirectories.
Definition: juce_File.cpp:576
juce::File::getLastModificationTime
Time getLastModificationTime() const
Returns the last modification time of this file.
Definition: juce_File.cpp:512
juce::String::upToFirstOccurrenceOf
String upToFirstOccurrenceOf(StringRef substringToEndWith, bool includeSubStringInResult, bool ignoreCase) const
Returns the start of this string, up to the first occurrence of a substring.
Definition: juce_String.cpp:1591
juce::CharacterFunctions::isDigit
static bool isDigit(char character) noexcept
Checks whether a character is a digit.
Definition: juce_CharacterFunctions.cpp:74
juce::FileInputStream
An input stream that reads from a local file.
Definition: juce_FileInputStream.h:38
juce::File::withFileExtension
File withFileExtension(StringRef newExtension) const
Returns a version of this file with a different file extension.
Definition: juce_File.cpp:684
juce::StringRef::isEmpty
bool isEmpty() const noexcept
Returns true if the string is empty.
Definition: juce_StringRef.h:105
juce::File::hashCode64
int64 hashCode64() const
Returns a 64-bit hash-code that identifies this file.
Definition: juce_File.cpp:379
juce::Time
Holds an absolute date and time.
Definition: juce_Time.h:40
juce::String::trimCharactersAtEnd
String trimCharactersAtEnd(StringRef charactersToTrim) const
Returns a copy of this string, having removed a specified set of characters from its end.
Definition: juce_String.cpp:1717
juce::File::isSymbolicLink
bool isSymbolicLink() const
Returns true if this file is a link or alias that can be followed using getLinkedTarget().
juce::String::length
int length() const noexcept
Returns the number of characters in the string.
Definition: juce_String.cpp:518
juce::File::createInputStream
FileInputStream * createInputStream() const
Creates a stream to read from this file.
Definition: juce_File.cpp:709
juce::InputStream::readEntireStreamAsString
virtual String readEntireStreamAsString()
Tries to read the whole stream and turn it into a string.
Definition: juce_InputStream.cpp:209
juce::File::findFileSystemRoots
static void findFileSystemRoots(Array< File > &results)
Creates a set of files to represent each file root.
juce::String::removeCharacters
String removeCharacters(StringRef charactersToRemove) const
Returns a version of this string with a set of characters removed.
Definition: juce_String.cpp:1763
juce::File::replaceWithData
bool replaceWithData(const void *dataToWrite, size_t numberOfBytes) const
Replaces this file's contents with a given block of data.
Definition: juce_File.cpp:740
juce::String::isEmpty
bool isEmpty() const noexcept
Returns true if the string contains no characters.
Definition: juce_String.h:300
juce::File::tempDirectory
@ tempDirectory
The folder that should be used for temporary files.
Definition: juce_File.h:886
juce::File::copyDirectoryTo
bool copyDirectoryTo(const File &newDirectory) const
Copies a directory.
Definition: juce_File.cpp:308
juce::File::createSymbolicLink
bool createSymbolicLink(const File &linkFileToCreate, bool overwriteExisting) const
Tries to create a symbolic link and returns a boolean to indicate success.
Definition: juce_File.cpp:978
juce::Range< int64 >
juce::File::getLastAccessTime
Time getLastAccessTime() const
Returns the last time this file was accessed.
Definition: juce_File.cpp:513
juce::File::userApplicationDataDirectory
@ userApplicationDataDirectory
The folder in which applications store their persistent user-specific settings.
Definition: juce_File.h:862
juce::File::setExecutePermission
bool setExecutePermission(bool shouldBeExecutable) const
Changes the execute-permissions of a file.
Definition: juce_File.cpp:254
juce::File::createLegalPathName
static String createLegalPathName(const String &pathNameToFix)
Returns a version of a path with any illegal characters removed.
Definition: juce_File.cpp:803
juce::MemoryMappedFile::AccessMode
AccessMode
The read/write flags used when opening a memory mapped file.
Definition: juce_MemoryMappedFile.h:40
juce::Random::getSystemRandom
static Random & getSystemRandom() noexcept
The overhead of creating a new Random object is fairly small, but if you want to avoid it,...
Definition: juce_Random.cpp:71
juce::CharPointer_UTF8
Wraps a pointer to a null-terminated UTF-8 character string, and provides various methods to operate ...
Definition: juce_CharPointer_UTF8.h:38
juce::FileOutputStream::write
bool write(const void *, size_t) override
Writes a block of data to the stream.
Definition: juce_FileOutputStream.cpp:78
juce::UnitTest
This is a base class for classes that perform a unit test.
Definition: juce_UnitTest.h:73
juce::StringRef::isNotEmpty
bool isNotEmpty() const noexcept
Returns true if the string is not empty.
Definition: juce_StringRef.h:107
juce::File::userHomeDirectory
@ userHomeDirectory
The user's home folder.
Definition: juce_File.h:836
juce::File::getFileExtension
String getFileExtension() const
Returns the file's extension.
Definition: juce_File.cpp:649
juce::StringArray::addLines
int addLines(StringRef stringToBreakUp)
Breaks up a string into lines and adds them to this array.
Definition: juce_StringArray.cpp:357
juce::String::isNotEmpty
bool isNotEmpty() const noexcept
Returns true if the string contains at least one character.
Definition: juce_String.h:306
juce::File::createLegalFileName
static String createLegalFileName(const String &fileNameToFix)
Returns a version of a filename with any illegal characters removed.
Definition: juce_File.cpp:818
juce::File::copyFileTo
bool copyFileTo(const File &targetLocation) const
Copies a file.
Definition: juce_File.cpp:287
juce::File::findChildFiles
Array< File > findChildFiles(int whatToLookFor, bool searchRecursively, const String &wildCardPattern="*") const
Searches this directory for files matching a wildcard pattern.
Definition: juce_File.cpp:546
juce::File::getSeparatorChar
static juce_wchar getSeparatorChar()
The system-specific file separator character.
juce::MemoryMappedFile::readWrite
@ readWrite
Indicates that the memory can be read and written to - changes that are made will be flushed back to ...
Definition: juce_MemoryMappedFile.h:43
juce::String
The JUCE String class!
Definition: juce_String.h:42
juce::String::trimEnd
String trimEnd() const
Returns a copy of this string with any whitespace characters removed from the end.
Definition: juce_String.cpp:1693
juce::TemporaryFile::overwriteTargetFileWithTemporary
bool overwriteTargetFileWithTemporary() const
Tries to move the temporary file to overwrite the target file that was specified in the constructor.
Definition: juce_TemporaryFile.cpp:76
juce::File::getRelativePathFrom
String getRelativePathFrom(const File &directoryToBeRelativeTo) const
Creates a relative path that refers to a file relatively to a given directory.
Definition: juce_File.cpp:862
juce::String::substring
String substring(int startIndex, int endIndex) const
Returns a subsection of the string.
Definition: juce_String.cpp:1504
juce::String::hashCode
int hashCode() const noexcept
Generates a probably-unique 32-bit hashcode from this string.
Definition: juce_String.cpp:556
juce::TemporaryFile::getFile
const File & getFile() const noexcept
Returns the temporary file.
Definition: juce_TemporaryFile.h:130
juce::File::hasFileExtension
bool hasFileExtension(StringRef extensionToTest) const
Checks whether the file has a given extension.
Definition: juce_File.cpp:659
juce::Result::ok
static Result ok() noexcept
Creates and returns a 'successful' result.
Definition: juce_Result.h:65
juce::CharPointer_UTF8::getAndAdvance
juce_wchar getAndAdvance() noexcept
Returns the character that this pointer is currently pointing to, and then advances the pointer to po...
Definition: juce_CharPointer_UTF8.h:151
juce::Process::openDocument
static bool JUCE_CALLTYPE openDocument(const String &documentURL, const String &parameters)
Tries to launch the OS's default reader application for a given file or URL.
juce::File::currentApplicationFile
@ currentApplicationFile
Returns this application's location.
Definition: juce_File.h:909
juce::String::fromFirstOccurrenceOf
String fromFirstOccurrenceOf(StringRef substringToStartFrom, bool includeSubStringInResult, bool ignoreCase) const
Returns a section of the string starting from a given substring.
Definition: juce_String.cpp:1571
juce::String::toWideCharPointer
const wchar_t * toWideCharPointer() const
Returns a pointer to a wchar_t version of this string.
Definition: juce_String.cpp:2077
juce::FileOutputStream
An output stream that writes into a local file.
Definition: juce_FileOutputStream.h:38
juce::String::indexOfChar
int indexOfChar(juce_wchar characterToLookFor) const noexcept
Searches for a character inside this string.
Definition: juce_String.cpp:880
juce::CharacterFunctions::toLowerCase
static juce_wchar toLowerCase(juce_wchar character) noexcept
Converts a character to lower-case.
Definition: juce_CharacterFunctions.cpp:36
juce::File::deleteRecursively
bool deleteRecursively(bool followSymlinks=false) const
Deletes a file or directory and all its subdirectories.
Definition: juce_File.cpp:259
juce::File::currentExecutableFile
@ currentExecutableFile
Returns this application's executable file.
Definition: juce_File.h:899
juce::File::getSize
int64 getSize() const
Returns the size of the file in bytes.
juce::String::dropLastCharacters
String dropLastCharacters(int numberToDrop) const
Returns a version of this string with a number of characters removed from the end.
Definition: juce_String.cpp:1561
juce::Result::fail
static Result fail(const String &errorMessage) noexcept
Creates a 'failure' result.
Definition: juce_Result.cpp:65
juce::File::replaceFileIn
bool replaceFileIn(const File &targetLocation) const
Replaces a file.
Definition: juce_File.cpp:293
juce::File::existsAsFile
bool existsAsFile() const
Checks whether the file exists and is a file rather than a directory.
juce::File::getNativeLinkedTarget
String getNativeLinkedTarget() const
This returns the native path that the symbolic link points to.
juce::File::findFiles
@ findFiles
Use this flag to indicate that you want to find files.
Definition: juce_File.h:554
juce::MemoryBlock
A class to hold a resizable block of raw data.
Definition: juce_MemoryBlock.h:36
juce::File::getChildFile
File getChildFile(StringRef relativeOrAbsolutePath) const
Returns a file that represents a relative (or absolute) sub-path of the current one.
Definition: juce_File.cpp:394
juce::InputStream::readIntoMemoryBlock
virtual size_t readIntoMemoryBlock(MemoryBlock &destBlock, ssize_t maxNumBytesToRead=-1)
Reads from the stream and appends the data to a MemoryBlock.
Definition: juce_InputStream.cpp:203