00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "JFile.h"
00022
00023
00024
00025
00026
00027
00028 namespace cmlabs {
00029
00030
00031 bool JFile::appendToAFileASCII(const JString& name, const JString& text) {
00032 return appendToAFileASCII(name, text, text.length());
00033 }
00034
00035 bool JFile::appendToAFileASCII(const JString& name, char* str, int length) {
00036
00037 FILE* file = fopen(name, "a");
00038 if (file == NULL)
00039 return false;
00040
00041 int len = length;
00042 int res = (int)fwrite(str, 1, len, file);
00043
00044 fclose(file);
00045
00046 if ((res <= 0) || (res > len)) {
00047 return false;
00048 }
00049 return true;
00050 }
00051
00052
00053 bool JFile::writeAFileASCII(const JString& name, const JString& text) {
00054 return writeAFileASCII(name, text, text.length());
00055 }
00056
00057 bool JFile::writeAFileASCII(const JString& name, char* str, int length) {
00058
00059 FILE* file = fopen(name, "w");
00060 if (file == NULL)
00061 return false;
00062
00063 int len = length;
00064 int res = (int)fwrite(str, 1, len, file);
00065
00066 fclose(file);
00067
00068 if ((res <= 0) || (res > len)) {
00069 return false;
00070 }
00071 return true;
00072 }
00073
00074 bool JFile::writeAFileBinary(const JString& name, char* str, int length) {
00075
00076 FILE* file = fopen(name, "wb");
00077 if (file == NULL)
00078 return false;
00079
00080 int len = length;
00081 int res = (int)fwrite(str, 1, len, file);
00082
00083 fclose(file);
00084
00085 if ((res <= 0) || (res > len)) {
00086 return false;
00087 }
00088 return true;
00089 }
00090
00091 JString JFile::readAFileASCII(const JString& name) {
00092 int length;
00093 JString content;
00094 char* str = JFile::readAFileASCII(name, length);
00095 if ((str != NULL) && (length > 0))
00096 content = JString(str);
00097 delete [] str;
00098 return content;
00099 }
00100
00101 char* JFile::readAFileASCII(const JString& name, int &length) {
00102 length = 0;
00103
00104 FILE* file = fopen(name, "r");
00105 if (file == NULL)
00106 return NULL;
00107
00108 fseek(file, 0, SEEK_END);
00109 long len = ftell(file);
00110 fseek(file, 0, SEEK_SET);
00111
00112 if (len <= 0) {
00113 fclose(file);
00114 return NULL;
00115 }
00116
00117 char* data = new char[len+1];
00118
00119 int res = (int)fread(data, 1, len, file);
00120
00121 if ((res <= 0) || (res != len)) {
00122 int error = ferror(file);
00123 int eof = feof(file);
00124 if (eof == 0) {
00125 delete [] data;
00126 fclose(file);
00127 return NULL;
00128 }
00129 }
00130
00131 fclose(file);
00132
00133 length = res;
00134 data[length] = 0;
00135
00136 return data;
00137 }
00138
00139 bool JFile::readAFileASCII(const JString& name, char* data, int &length) {
00140 length = 0;
00141
00142 FILE* file = fopen(name, "r");
00143 if (file == NULL)
00144 return false;
00145
00146 fseek(file, 0, SEEK_END);
00147 long len = ftell(file);
00148 fseek(file, 0, SEEK_SET);
00149
00150 if (len <= 0) {
00151 fclose(file);
00152 return false;
00153 }
00154
00155 if (length < len) {
00156 fclose(file);
00157 return false;
00158 }
00159
00160 int res = (int)fread(data, 1, len, file);
00161
00162 if ((res <= 0) || (res > len)) {
00163 fclose(file);
00164 return false;
00165 }
00166
00167 fclose(file);
00168
00169 length = res;
00170 data[length] = 0;
00171
00172 return true;
00173 }
00174
00175 char* JFile::readAFileBinary(const JString& name, int &length) {
00176 length = 0;
00177
00178 FILE* file = fopen(name, "rb");
00179 if (file == NULL)
00180 return NULL;
00181
00182 fseek(file, 0, SEEK_END);
00183 long len = ftell(file);
00184 fseek(file, 0, SEEK_SET);
00185
00186 if (len <= 0) {
00187 fclose(file);
00188 return NULL;
00189 }
00190
00191 char* str = new char[len+1];
00192
00193 int res = (int)fread(str, 1, len, file);
00194
00195 if (res != len) {
00196 delete [] str;
00197 fclose(file);
00198 return NULL;
00199 }
00200
00201 fclose(file);
00202
00203 length = res;
00204 str[len] = 0;
00205
00206 return str;
00207 }
00208
00209 bool JFile::readAFileBinary(const JString& name, char* data, int &length) {
00210 length = 0;
00211
00212 FILE* file = fopen(name, "rb");
00213 if (file == NULL)
00214 return false;
00215
00216 fseek(file, 0, SEEK_END);
00217 long len = ftell(file);
00218 fseek(file, 0, SEEK_SET);
00219
00220 if (len <= 0) {
00221 fclose(file);
00222 return false;
00223 }
00224
00225 if (length < len) {
00226 fclose(file);
00227 return false;
00228 }
00229
00230 int res = (int)fread(data, 1, len, file);
00231
00232 if ((res <= 0) || (res > len)) {
00233 fclose(file);
00234 return false;
00235 }
00236
00237 fclose(file);
00238
00239 length = res;
00240 data[length] = 0;
00241
00242 return true;
00243 }
00244
00245 Collection JFile::getFilesInADir(const JString& name) {
00246 JFile file(name);
00247 return file.getFilesInDir();
00248 }
00249
00250 bool JFile::deleteAFile(const JString& name) {
00251 JFile file(name);
00252 return file.deleteFile();
00253 }
00254
00255 bool JFile::deleteADir(const JString& name, bool recursive) {
00256 JFile file(name);
00257 return file.deleteDir(recursive);
00258 }
00259
00260
00261 unsigned long JFile::getAFileSize(const JString& name) {
00262 JFile file(name);
00263 return file.getSize();
00264 }
00265
00266 bool JFile::doesAFileExist(const JString& name) {
00267 JFile file(name);
00268 return file.exists();
00269 }
00270
00271 bool JFile::doesADirExist(const JString& name) {
00272 JFile file(name);
00273 return file.exists();
00274 }
00275
00276 bool JFile::moveAFile(const JString& from, const JString& to) {
00277 JFile file(from);
00278 return file.move(to);
00279 }
00280
00281 bool JFile::moveADir(const JString& from, const JString& to) {
00282 JFile file(from);
00283 return file.move(to);
00284 }
00285
00286
00287 bool JFile::createADir(const JString& fname) {
00288 #ifdef WIN32
00289 #ifdef WIN32_POCKETPC
00290 JString str = fname;
00291 if (CreateDirectory(str, NULL) == 0) {
00292 if (GetLastError() != ERROR_ALREADY_EXISTS)
00293 return false;
00294 }
00295 return true;
00296 #else
00297 if (CreateDirectory(fname, NULL) == 0) {
00298 if (GetLastError() != ERROR_ALREADY_EXISTS)
00299 return false;
00300 }
00301 return true;
00302 #endif
00303 #else
00304 int res = mkdir(fname, 0755);
00305
00306
00307
00308
00309
00310 return (res == 0);
00311 #endif // WIN32
00312 }
00313
00314 bool JFile::createADir(const JString& fname, bool recursive) {
00315
00316 if ((!recursive) || ((!fname.contains("/")) && (!fname.contains("\\"))) || (fname.startsWith(".")))
00317 return createADir(fname);
00318
00319 Collection coll = fname.split("/");
00320 if (coll.getCount() == 1)
00321 coll = fname.split("\\");
00322 if (coll.getCount() == 1)
00323 return createADir(fname);
00324
00325 JString dname;
00326 JString dpath;
00327
00328 for (int n=0; n<coll.getCount(); n++) {
00329 dname = coll.get(n);
00330 if (dname.length() > 0) {
00331 if (dpath.length() == 0)
00332 dpath = dname;
00333 else
00334 dpath += JString("/") + dname;
00335 if (!createADir(dpath))
00336 return false;
00337 }
00338 }
00339
00340 return true;
00341 }
00342
00343 JString JFile::getPathFromFullName(const JString& fname) {
00344 JString myName = fname;
00345 myName.replace("\\", "/", true);
00346 int pos = myName.lastIndexOf('/');
00347 if (pos < 0)
00348 return "";
00349 else if (pos == 0)
00350 return "/";
00351 else
00352 return myName.substring(0, pos+1);
00353 }
00354
00355 JString JFile::getFileNameFromFullName(const JString& fname) {
00356 JString myName = fname;
00357 myName.replace("\\", "/", true);
00358 int pos = myName.lastIndexOf('/');
00359 if (pos < 0)
00360 return fname;
00361 return myName.substring(pos+1);
00362 }
00363
00364 JString JFile::findDirWithFile(Collection& dirs, const JString& filename) {
00365 for (JString dir = dirs.getFirst(); dir.length() > 0; dir = dirs.getNext()) {
00366 if (JFile::doesAFileExist(dir + "/" + filename))
00367 return dir;
00368 }
00369 return "";
00370 }
00371
00372 JString JFile::findDirWithFileFullPath(Collection& dirs, const JString& filename) {
00373 for (JString dir = dirs.getFirst(); dir.length() > 0; dir = dirs.getNext()) {
00374 if (JFile::doesAFileExist(dir + "/" + filename))
00375 return dir + "/" + filename;
00376 }
00377 return "";
00378 }
00379
00380
00381
00382
00383
00384
00385
00386 JFile::JFile(const JString& filedirname)
00387 {
00388 name = filedirname;
00389 fileptr = NULL;
00390
00391 isEOF = false;
00392
00393 isDirectory = false;
00394 isReadable = false;
00395 isWritable = false;
00396 isExecutable = false;
00397 size = -1;
00398
00399 doesExist = false;
00400 collectFileInfo();
00401
00402
00403 isBinary = -1;
00404
00405 }
00406
00407 JFile::~JFile(void)
00408 {
00409 closeFile();
00410 }
00411
00412 Object* JFile::clone() const {
00413 JFile* f = new JFile(name);
00414 return (Object*) f;
00415 }
00416
00417 bool JFile::createFile(bool asBinary) {
00418 if (fileptr != NULL) {
00419 return false;
00420 }
00421
00422 if (exists())
00423 return false;
00424
00425 if (asBinary) {
00426 fileptr = fopen(name, "w+b");
00427 isBinary = 1;
00428 }
00429 else {
00430 fileptr = fopen(name, "w+");
00431 isBinary = 0;
00432 }
00433
00434 if (fileptr == NULL) {
00435 isBinary = -1;
00436 return false;
00437 }
00438
00439 fseek(fileptr, 0, SEEK_SET);
00440 return true;
00441 }
00442
00443
00444 bool JFile::openFile(bool asBinary) {
00445
00446 if (fileptr != NULL) {
00447 if ((isBinary == -1) || ((isBinary == 0) && (!asBinary)))
00448 return true;
00449 else
00450 return false;
00451 }
00452
00453 if (asBinary) {
00454 fileptr = fopen(name, "r+b");
00455 isBinary = 1;
00456 }
00457 else {
00458 fileptr = fopen(name, "r+");
00459 isBinary = 0;
00460 }
00461
00462 if (fileptr == NULL) {
00463 isBinary = -1;
00464 return false;
00465 }
00466
00467 fseek(fileptr, 0, SEEK_SET);
00468 return true;
00469 }
00470
00471 bool JFile::closeFile() {
00472
00473 if (fileptr == NULL)
00474 return true;
00475
00476 fclose(fileptr);
00477
00478
00479
00480 fileptr = NULL;
00481 return true;
00482 }
00483
00484 bool JFile::deleteFile(bool force) {
00485 return deleteDir(force);
00486 }
00487
00488 bool JFile::deleteDir(bool recursive) {
00489
00490 if (!exists()) return true;
00491 closeFile();
00492
00493
00494 if (isAFile()) {
00495
00496 if (!deleteFile(name)) {
00497 if (!recursive)
00498 return false;
00499 changeAttr(name, true, true);
00500 if (!deleteDir(name))
00501 return false;
00502 }
00503 return true;
00504 }
00505
00506
00507 if (!recursive) {
00508 return (deleteDir(name));
00509 }
00510
00511
00512 Collection coll = this->getFilesInDir();
00513
00514 if (coll.getCount() == 0) {
00515 return (deleteDir(name));
00516 }
00517
00518 JFile file("");
00519 JString fname;
00520 for (int n=0; n<coll.getCount(); n++) {
00521 fname = coll.get(n);
00522 if (fname.length() > 0) {
00523 #ifdef WIN32
00524 file = JFile(name + JString("\\") + fname);
00525 #else
00526 file = JFile(name + JString("/") + fname);
00527 #endif // WIN32
00528 if (!file.deleteDir(true)) {
00529 return false;
00530 }
00531 }
00532 }
00533
00534 return (deleteDir(name));
00535 }
00536
00537
00538 int JFile::getSize() {
00539
00540 if (collectFileInfo())
00541 return size;
00542 else
00543 return -1;
00544
00545
00546
00547
00548
00549
00550
00551 }
00552
00553 bool JFile::collectFileInfo() {
00554
00555 #if defined(_WIN32_WCE)
00556
00557 WIN32_FIND_DATA info;
00558 HANDLE handle = FindFirstFile(name, &info);
00559 if ((handle == NULL) || (handle == INVALID_HANDLE_VALUE)) {
00560 doesExist = false;
00561 size = 0;
00562 return true;
00563 }
00564
00565 BY_HANDLE_FILE_INFORMATION fileinfo;
00566 if (GetFileInformationByHandle(handle, &fileinfo) == 0) {
00567 doesExist = true;
00568 size = 0;
00569 return false;
00570 }
00571
00572 doesExist = true;
00573 isDirectory = (fileinfo.dwFileAttributes == FILE_ATTRIBUTE_DIRECTORY);
00574 isReadable = true;
00575 isWritable = (fileinfo.dwFileAttributes == FILE_ATTRIBUTE_READONLY);
00576 isExecutable = true;
00577
00578 lastAccessTime = JTime(info.ftLastAccessTime);
00579 lastModifyTime = JTime(info.ftLastWriteTime);
00580 creationTime = JTime(info.ftCreationTime);
00581
00582 if (isDirectory)
00583 size = 0;
00584 else
00585 size = fileinfo.nFileSizeLow;
00586
00587 return true;
00588
00589 #else
00590
00591 struct stat statbuf;
00592 int fd, result;
00593 char buffer[] = "A line to output";
00594
00595 doesExist = false;
00596
00597 if ((fd = open(name, O_RDONLY)) == -1) {
00598
00599 DIR* dir = opendir(name);
00600 if (dir == NULL)
00601 return false;
00602 struct dirent* direntry = readdir(dir);
00603
00604 doesExist = true;
00605 size = 0;
00606 isDirectory = true;
00607 lastAccessTime = JTime();
00608 lastModifyTime = JTime();
00609 creationTime = JTime();
00610
00611 isReadable = true;
00612 isWritable = true;
00613 isExecutable = true;
00614
00615 closedir(dir);
00616
00617 return true;
00618 }
00619
00620
00621 result = fstat(fd, &statbuf);
00622
00623
00624 if( result != 0 ) {
00625 close(fd);
00626 return false;
00627 }
00628
00629 close(fd);
00630 doesExist = true;
00631
00632 size = statbuf.st_size;
00633 isDirectory = ((statbuf.st_mode & S_IFDIR) != 0);
00634 lastAccessTime = JTime((long)statbuf.st_atime, 0);
00635 lastModifyTime = JTime((long)statbuf.st_mtime, 0);
00636 creationTime = JTime((long)statbuf.st_ctime, 0);
00637
00638 #ifdef WIN32
00639 isReadable = ((statbuf.st_mode & _S_IREAD) != 0);
00640 isWritable = ((statbuf.st_mode & _S_IWRITE) != 0);
00641 isExecutable = ((statbuf.st_mode & _S_IEXEC) != 0);
00642 #else
00643 isReadable = ((statbuf.st_mode & S_IRUSR) != 0);
00644 isWritable = ((statbuf.st_mode & S_IWUSR) != 0);
00645 isExecutable = ((statbuf.st_mode & S_IXUSR) != 0);
00646 #endif
00647
00648 return true;
00649
00650 #endif
00651 }
00652
00653 Collection JFile::getFilesInDir() {
00654
00655 Collection files;
00656
00657
00658 if (!exists()) {
00659
00660 return files;
00661 }
00662
00663 if (!isADir()) {
00664
00665 return files;
00666 }
00667
00668 DIR* dir = opendir(name);
00669 if (dir == NULL) {
00670
00671 return files;
00672 }
00673
00674 struct dirent* direntry = NULL;
00675 JString fname;
00676
00677
00678 direntry = readdir(dir);
00679 while (direntry != NULL) {
00680 if (direntry->d_name != NULL) {
00681 fname = direntry->d_name;
00682 if ( (fname.length() > 0) && (!fname.equals(".")) && (!fname.equals("..")) )
00683 files.addLast(fname);
00684 }
00685 direntry = readdir(dir);
00686 }
00687 closedir(dir);
00688
00689
00690
00691
00692
00693
00694
00695
00696
00697 return files;
00698 }
00699
00700 bool JFile::isADir() {
00701 if (!exists())
00702 return false;
00703 return isDirectory;
00704 }
00705
00706 bool JFile::isAFile() {
00707 if (!exists())
00708 return false;
00709 return (!isDirectory);
00710 }
00711
00712 JString JFile::readLine() {
00713
00714 if (fileptr == NULL) return "";
00715
00716 JString str;
00717
00718 char ch;
00719 int res;
00720
00721 res = (int)fread(&ch, 1, 1, fileptr);
00722 while (res == 1) {
00723 str += ch;
00724 if (ch == 10) break;
00725 res = (int)fread(&ch, 1, 1, fileptr);
00726 }
00727
00728 return str;
00729 }
00730
00731 bool JFile::isAtEOF() {
00732 return (feof(fileptr) != 0);
00733 }
00734
00735 bool JFile::isInError() {
00736 return (ferror(fileptr) != 0);
00737 }
00738
00739 bool JFile::isValid() {
00740 return exists();
00741 }
00742
00743 bool JFile::exists() {
00744 collectFileInfo();
00745
00746
00747 return doesExist;
00748 }
00749
00750 bool JFile::createDir(bool recursive) {
00751 if (name.length() == 0)
00752 return false;
00753 return createADir(name, recursive);
00754 }
00755
00756 bool JFile::truncate() {
00757
00758 closeFile();
00759 FILE* file = fopen(name, "w+");
00760 if (file == NULL)
00761 return false;
00762 return true;
00763 }
00764
00765 bool JFile::gotoStart() {
00766 if (fileptr == NULL)
00767 return false;
00768 return (fseek(fileptr, 0, SEEK_SET) == 0);
00769 }
00770
00771 bool JFile::gotoEnd() {
00772 if (fileptr == NULL)
00773 return false;
00774 return (fseek(fileptr, 0, SEEK_END) == 0);
00775 }
00776
00777 bool JFile::gotoPos(int pos) {
00778 if (fileptr == NULL)
00779 return false;
00780 return (fseek(fileptr, pos, SEEK_SET) == 0);
00781 }
00782
00783 JString JFile::getFileNameOnly() {
00784
00785 if (name.length() == 0)
00786 return "";
00787
00788 if ((!name.contains("/")) && (!name.contains("\\")))
00789 return name;
00790
00791 Collection coll = name.split("/");
00792 if (coll.getCount() == 1)
00793 return name;
00794 if (coll.getCount() == 1)
00795 return name;
00796
00797 for (int n=coll.getCount()-1; n>=0; n--)
00798 if (coll.get(n).length() > 0)
00799 return coll.get(n);
00800 return "";
00801 }
00802
00803 JString JFile::getDirNameOnly() {
00804 if (name.length() == 0)
00805 return "";
00806
00807 if ((!name.contains("/")) && (!name.contains("\\")))
00808 return name;
00809
00810 Collection coll = name.split("/");
00811 if (coll.getCount() == 1)
00812 return name;
00813 if (coll.getCount() == 1)
00814 return name;
00815
00816 for (int n=coll.getCount()-1; n>=0; n--)
00817 if (coll.get(n).length() > 0)
00818 return coll.get(n);
00819 return "";
00820 }
00821
00822 JString JFile::getFullPathName() {
00823
00824 JString str;
00825 char* fpath;
00826
00827 #ifdef WIN32
00828
00829 #ifdef _WIN32_WCE
00830
00831
00832
00833
00834
00835
00836 return name;
00837 #else
00838 char* partpath = NULL;
00839 int len = 3000;
00840 fpath = new char[len];
00841 if (GetFullPathName(name, len, fpath, &partpath) != 0)
00842 str = fpath;
00843 #endif
00844 #else
00845 fpath = new char[PATH_MAX];
00846 if (realpath(name, fpath) != NULL)
00847 str = fpath;
00848 #endif // WIN32
00849
00850 delete [] fpath;
00851 return str;
00852 }
00853
00854
00855
00856
00857
00858
00859
00860
00861
00862 bool JFile::deleteFile(const JString& fname) {
00863
00864 #ifdef WIN32
00865 #ifdef WIN32_POCKETPC
00866 JString str = fname;
00867 return (DeleteFile(str) != 0);
00868 #else
00869 return (DeleteFile(fname) != 0);
00870 #endif
00871 #else
00872 return (unlink(fname) == 0);
00873 #endif
00874 }
00875
00876 bool JFile::deleteDir(const JString& fname) {
00877
00878 #ifdef WIN32
00879 #ifdef WIN32_POCKETPC
00880 JString str = fname;
00881 return (RemoveDirectory(str) != 0);
00882 #else
00883 return (RemoveDirectory(fname) != 0);
00884 #endif
00885 #else
00886 int res = rmdir(fname);
00887 return (res == 0);
00888 #endif
00889 }
00890
00891 bool JFile::changeAttr(const JString& fname, bool read, bool write) {
00892
00893 #ifdef WIN32
00894
00895 #ifdef WIN32_POCKETPC
00896 JString str = fname;
00897 if (!write)
00898 return (SetFileAttributes(str, FILE_ATTRIBUTE_READONLY) != 0);
00899 else
00900 return (SetFileAttributes(str, FILE_ATTRIBUTE_NORMAL) != 0);
00901 #else
00902 if (!write)
00903 return (SetFileAttributes(fname, FILE_ATTRIBUTE_READONLY) != 0);
00904 else
00905 return (SetFileAttributes(fname, FILE_ATTRIBUTE_NORMAL) != 0);
00906 #endif
00907
00908
00909 #else
00910 if (read && write)
00911 return (chmod(fname,S_IREAD | S_IWRITE) != 0);
00912 else if (read)
00913 return (chmod(fname,S_IREAD) == 0);
00914 else if (write)
00915 return (chmod(fname,S_IWRITE) == 0);
00916 else
00917 return (chmod(fname,0) == 0);
00918 #endif
00919 }
00920
00921
00922 bool JFile::move(const JString& newname) {
00923 #ifdef WIN32
00924 #ifdef WIN32_POCKETPC
00925 JString from = name;
00926 JString to = newname;
00927 return (MoveFile(from, to) != 0);
00928 #else
00929 return (MoveFile(name, newname) != 0);
00930 #endif
00931 #else
00932 return (rename(name, newname) == 0);
00933 #endif
00934 }
00935
00936
00937
00938
00939
00940
00941
00942
00943
00944
00945
00946
00947
00948
00949
00950
00951
00952
00953
00954
00955
00956 bool JFile::lock() {return false;}
00957 bool JFile::unlock() {return false;}
00958 bool JFile::flush() {return false;}
00959
00960
00961
00962 char* JFile::readBinary(int &length) {return NULL;}
00963 JString JFile::readAscii(int &length) {return "";}
00964
00965
00966 bool JFile::writeBinary(char* str, int &length) {return false;}
00967 bool JFile::writeAscii(const JString& str) {return false;}
00968 bool JFile::writeLine(const JString& str) {return false;}
00969
00970 bool JFile::isFileReadable() {return false;}
00971 bool JFile::isFileWritable() {return false;}
00972 bool JFile::isFileExecutable() {return false;}
00973 bool JFile::isFileBinary() {return false;}
00974
00975 JTime JFile::getLastAccessTime() {return lastAccessTime; }
00976 JTime JFile::getLastModifyTime() {return lastModifyTime; }
00977 JTime JFile::getCreationTime() {return creationTime; }
00978
00979
00980
00981
00982
00983
00984 }