Thread overview | |||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|
|
July 02, 2005 std.file.exists() | ||||
---|---|---|---|---|
| ||||
Hi all.
I was looking at the code for std.file.exists(), and I observed a few
things.
1. Std.file.exists() returns an int, but wouldn't the job be made easier
with a bit?
2. It calls a function called GetFileAttributesA or GetFileAttributesW.
These sound like win32 specific functions, and if so should be in a version
block.
3. There seems to be no linux equivelant for these functions, thus I
propose the following.
A. Std.c.linux.linux should have in it the prototype for the function
access, which takes a string as the file name, and a number representing the
octal permition value we want checked, or 0 for just existance.
B. std.file.exists() should use access(toStringz(name), 0) to check for
the existance of the file.
Any comments would be appreciated, especially if I've got this all wrong :).
Ameer
--
---
Life is either tragedy or comedy.
Usually it's your choice. You can whine or you can laugh.
--Animorphs
|
July 02, 2005 Re: std.file.exists() | ||||
---|---|---|---|---|
| ||||
Posted in reply to Ameer Armaly | "Ameer Armaly" <ameer_armaly@hotmail.com> wrote in message news:da6amc$q38$1@digitaldaemon.com... > Hi all. > I was looking at the code for std.file.exists(), and I observed a few > things. > 1. Std.file.exists() returns an int, but wouldn't the job be made easier > with a bit? Why easier? It's common in D to return int since it is (reportedly) faster. > 2. It calls a function called GetFileAttributesA or GetFileAttributesW. These sound like win32 specific functions, and if so should be in a version block. It is. Scroll down for the linux version. > 3. There seems to be no linux equivelant for these functions, thus I > propose the following. > A. Std.c.linux.linux should have in it the prototype for the function > access, which takes a string as the file name, and a number representing > the octal permition value we want checked, or 0 for just existance. > B. std.file.exists() should use access(toStringz(name), 0) to check for > the existance of the file. > Any comments would be appreciated, especially if I've got this all wrong > :). > Ameer > -- > --- > Life is either tragedy or comedy. > Usually it's your choice. You can whine or you can laugh. > --Animorphs > |
July 04, 2005 Re: std.file.exists() | ||||
---|---|---|---|---|
| ||||
Posted in reply to Ben Hinkle | On Sat, 2 Jul 2005, Ben Hinkle wrote: > > "Ameer Armaly" <ameer_armaly@hotmail.com> wrote in message > news:da6amc$q38$1@digitaldaemon.com... >> Hi all. >> I was looking at the code for std.file.exists(), and I observed a few >> things. >> 1. Std.file.exists() returns an int, but wouldn't the job be made easier >> with a bit? > > Why easier? It's common in D to return int since it is (reportedly) faster. > >> 2. It calls a function called GetFileAttributesA or GetFileAttributesW. >> These sound like win32 specific functions, and if so should be in a >> version block. > > It is. Scroll down for the linux version. Ah yes. I see it calls stat() to verify the existance of the file. However, what if we called access instead;for one, it's somewhat simpler since it is designed to do just checks, and more importantly, I've heard a few times on linux-c-programming that stat was pretty slow. This was in a discussion relating to checking for the existance of a directory, and several people said that stat was pretty slow, especially for something as simple as a check. What do you think? >> 3. There seems to be no linux equivelant for these functions, thus I >> propose the following. >> A. Std.c.linux.linux should have in it the prototype for the function >> access, which takes a string as the file name, and a number representing >> the octal permition value we want checked, or 0 for just existance. >> B. std.file.exists() should use access(toStringz(name), 0) to check for >> the existance of the file. >> Any comments would be appreciated, especially if I've got this all wrong >> :). >> Ameer >> -- >> --- >> Life is either tragedy or comedy. >> Usually it's your choice. You can whine or you can laugh. >> --Animorphs >> > > > |
July 04, 2005 Re: std.file.exists() | ||||
---|---|---|---|---|
| ||||
Posted in reply to Ameer Armaly | "Ameer Armaly" <ameer@bellsouth.net> wrote in message news:Pine.LNX.4.61.0507032218380.612@debian... > Ah yes. I see it calls stat() to verify the existance of the file. > However, what if we called access instead;for one, it's somewhat simpler > since it is designed to do just checks, and more importantly, I've heard > a few times on linux-c-programming that stat was pretty slow. This was in > a discussion relating to checking for the existance of a directory, and > several people said that stat was pretty slow, especially for something > as simple as a check. > What do you think? If you want to code and test a patch, that would be great! |
July 04, 2005 Re: std.file.exists() | ||||
---|---|---|---|---|
| ||||
Posted in reply to Walter | Alright here it is. I successfully compiled and tested phobos with these modifications. --- file.d 2005-06-30 16:04:29.000000000 -0400 +++ newfile.d 2005-07-04 12:55:21.000000000 -0400 @@ -1,958 +1,952 @@ - -/* - * Copyright (C) 2001-2004 by Digital Mars, www.digitalmars.com - * Written by Walter Bright, Christopher E. Miller, Andre Fornacon - * - * This software is provided 'as-is', without any express or implied - * warranty. In no event will the authors be held liable for any damages - * arising from the use of this software. - * - * Permission is granted to anyone to use this software for any purpose, - * including commercial applications, and to alter it and redistribute it - * freely, subject to the following restrictions: - * - * o The origin of this software must not be misrepresented; you must not - * claim that you wrote the original software. If you use this software - * in a product, an acknowledgment in the product documentation would be - * appreciated but is not required. - * o Altered source versions must be plainly marked as such, and must not - * be misrepresented as being the original software. - * o This notice may not be removed or altered from any source - * distribution. - */ - -module std.file; - -private import std.c.stdio; -private import std.c.stdlib; -private import std.path; -private import std.string; - -/* =========================== Win32 ======================= */ - -version (Win32) -{ - -private import std.c.windows.windows; -private import std.utf; -private import std.windows.syserror; - -int useWfuncs = 1; - -static this() -{ - // Win 95, 98, ME do not implement the W functions - useWfuncs = (GetVersion() < 0x80000000); -} - -/*********************************** - */ - -class FileException : Exception -{ - - uint errno; // operating system error code - - this(char[] name) - { - this(name, "file I/O"); - } - - this(char[] name, char[] message) - { - super(name ~ ": " ~ message); - } - - this(char[] name, uint errno) - { - this(name, sysErrorString(errno)); - this.errno = errno; - } -} - -/*********************************** - * Basic File operations. - */ - -/******************************************** - * Read a file. - * Returns: - * array of bytes read - */ - -void[] read(char[] name) -{ - DWORD size; - DWORD numread; - HANDLE h; - byte[] buf; - - if (useWfuncs) - { - wchar* namez = std.utf.toUTF16z(name); - h = CreateFileW(namez,GENERIC_READ,FILE_SHARE_READ,null,OPEN_EXISTING, - FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN,cast(HANDLE)null); - } - else - { - char* namez = toMBSz(name); - h = CreateFileA(namez,GENERIC_READ,FILE_SHARE_READ,null,OPEN_EXISTING, - FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN,cast(HANDLE)null); - } - - if (h == INVALID_HANDLE_VALUE) - goto err1; - - size = GetFileSize(h, null); - if (size == INVALID_FILE_SIZE) - goto err2; - - buf = new byte[size]; - - if (ReadFile(h,buf,size,&numread,null) != 1) - goto err2; - - if (numread != size) - goto err2; - - if (!CloseHandle(h)) - goto err; - - return buf; - -err2: - CloseHandle(h); -err: - delete buf; -err1: - throw new FileException(name, GetLastError()); -} - -/********************************************* - * Write a file. - * Returns: - * 0 success - */ - -void write(char[] name, void[] buffer) -{ - HANDLE h; - DWORD numwritten; - - if (useWfuncs) - { - wchar* namez = std.utf.toUTF16z(name); - h = CreateFileW(namez,GENERIC_WRITE,0,null,CREATE_ALWAYS, - FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN,cast(HANDLE)null); - } - else - { - char* namez = toMBSz(name); - h = CreateFileA(namez,GENERIC_WRITE,0,null,CREATE_ALWAYS, - FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN,cast(HANDLE)null); - } - if (h == INVALID_HANDLE_VALUE) - goto err; - - if (WriteFile(h,buffer,buffer.length,&numwritten,null) != 1) - goto err2; - - if (buffer.length != numwritten) - goto err2; - - if (!CloseHandle(h)) - goto err; - return; - -err2: - CloseHandle(h); -err: - throw new FileException(name, GetLastError()); -} - - -/********************************************* - * Append to a file. - */ - -void append(char[] name, void[] buffer) -{ - HANDLE h; - DWORD numwritten; - - if (useWfuncs) - { - wchar* namez = std.utf.toUTF16z(name); - h = CreateFileW(namez,GENERIC_WRITE,0,null,OPEN_ALWAYS, - FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN,cast(HANDLE)null); - } - else - { - char* namez = toMBSz(name); - h = CreateFileA(namez,GENERIC_WRITE,0,null,OPEN_ALWAYS, - FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN,cast(HANDLE)null); - } - if (h == INVALID_HANDLE_VALUE) - goto err; - - SetFilePointer(h, 0, null, FILE_END); - - if (WriteFile(h,buffer,buffer.length,&numwritten,null) != 1) - goto err2; - - if (buffer.length != numwritten) - goto err2; - - if (!CloseHandle(h)) - goto err; - return; - -err2: - CloseHandle(h); -err: - throw new FileException(name, GetLastError()); -} - - -/*************************************************** - * Rename a file. - */ - -void rename(char[] from, char[] to) -{ - BOOL result; - - if (useWfuncs) - result = MoveFileW(std.utf.toUTF16z(from), std.utf.toUTF16z(to)); - else - result = MoveFileA(toMBSz(from), toMBSz(to)); - if (!result) - throw new FileException(to, GetLastError()); -} - - -/*************************************************** - * Delete a file. - */ - -void remove(char[] name) -{ - BOOL result; - - if (useWfuncs) - result = DeleteFileW(std.utf.toUTF16z(name)); - else - result = DeleteFileA(toMBSz(name)); - if (!result) - throw new FileException(name, GetLastError()); -} - - -/*************************************************** - * Get file size. - */ - -ulong getSize(char[] name) -{ - HANDLE findhndl; - uint resulth; - uint resultl; - - if (useWfuncs) - { - WIN32_FIND_DATAW filefindbuf; - - findhndl = FindFirstFileW(std.utf.toUTF16z(name), &filefindbuf); - resulth = filefindbuf.nFileSizeHigh; - resultl = filefindbuf.nFileSizeLow; - } - else - { - WIN32_FIND_DATA filefindbuf; - - findhndl = FindFirstFileA(toMBSz(name), &filefindbuf); - resulth = filefindbuf.nFileSizeHigh; - resultl = filefindbuf.nFileSizeLow; - } - - if (findhndl == cast(HANDLE)-1) - { - throw new FileException(name, GetLastError()); - } - FindClose(findhndl); - return (cast(ulong)resulth << 32) + resultl; -} - -/*************************************************** - * Does file (or directory) exist? - */ - -int exists(char[] name) -{ - uint result; - - if (useWfuncs) - // http://msdn.microsoft.com/library/default.asp?url=/library/en-us/fileio/base/getfileattributes.asp - result = GetFileAttributesW(std.utf.toUTF16z(name)); - else - result = GetFileAttributesA(toMBSz(name)); - - return (result == 0xFFFFFFFF) ? 0 : 1; -} - -/*************************************************** - * Get file attributes. - */ - -uint getAttributes(char[] name) -{ - uint result; - - if (useWfuncs) - result = GetFileAttributesW(std.utf.toUTF16z(name)); - else - result = GetFileAttributesA(toMBSz(name)); - if (result == 0xFFFFFFFF) - { - throw new FileException(name, GetLastError()); - } - return result; -} - -/**************************************************** - * Is name a file? - */ - -int isfile(char[] name) -{ - return (getAttributes(name) & FILE_ATTRIBUTE_DIRECTORY) == 0; -} - -/**************************************************** - * Is name a directory? - */ - -int isdir(char[] name) -{ - return (getAttributes(name) & FILE_ATTRIBUTE_DIRECTORY) != 0; -} - -/**************************************************** - * Change directory. - */ - -void chdir(char[] pathname) -{ BOOL result; - - if (useWfuncs) - result = SetCurrentDirectoryW(std.utf.toUTF16z(pathname)); - else - result = SetCurrentDirectoryA(toMBSz(pathname)); - - if (!result) - { - throw new FileException(pathname, GetLastError()); - } -} - -/**************************************************** - * Make directory. - */ - -void mkdir(char[] pathname) -{ BOOL result; - - if (useWfuncs) - result = CreateDirectoryW(std.utf.toUTF16z(pathname), null); - else - result = CreateDirectoryA(toMBSz(pathname), null); - - if (!result) - { - throw new FileException(pathname, GetLastError()); - } -} - -/**************************************************** - * Remove directory. - */ - -void rmdir(char[] pathname) -{ BOOL result; - - if (useWfuncs) - result = RemoveDirectoryW(std.utf.toUTF16z(pathname)); - else - result = RemoveDirectoryA(toMBSz(pathname)); - - if (!result) - { - throw new FileException(pathname, GetLastError()); - } -} - -/**************************************************** - * Get current directory. - */ - -char[] getcwd() -{ - if (useWfuncs) - { - wchar[] dir; - int len; - wchar c; - - len = GetCurrentDirectoryW(0, &c); - if (!len) - goto Lerr; - dir = new wchar[len]; - len = GetCurrentDirectoryW(len, dir); - if (!len) - goto Lerr; - return std.utf.toUTF8(dir[0 .. len]); // leave off terminating 0 - } - else - { - char[] dir; - int len; - char c; - - len = GetCurrentDirectoryA(0, &c); - if (!len) - goto Lerr; - dir = new char[len]; - len = GetCurrentDirectoryA(len, dir); - if (!len) - goto Lerr; - return dir[0 .. len]; // leave off terminating 0 - } - -Lerr: - throw new FileException("getcwd", GetLastError()); -} - -/*************************************************** - * Return contents of directory. - */ - -char[][] listdir(char[] pathname) -{ - char[][] result; - - bool listing(char[] filename) - { - result ~= filename; - return true; // continue - } - - listdir(pathname, &listing); - return result; -} - -void listdir(char[] pathname, bool delegate(char[] filename) callback) -{ - char[] c; - HANDLE h; - - c = std.path.join(pathname, "*.*"); - if (useWfuncs) - { - WIN32_FIND_DATAW fileinfo; - - h = FindFirstFileW(std.utf.toUTF16z(c), &fileinfo); - if (h != INVALID_HANDLE_VALUE) - { - do - { int clength; - - // Skip "." and ".." - if (std.string.wcscmp(fileinfo.cFileName, ".") == 0 || - std.string.wcscmp(fileinfo.cFileName, "..") == 0) - continue; - - clength = std.string.wcslen(fileinfo.cFileName); - // toUTF8() returns a new buffer - if (!callback(std.utf.toUTF8(fileinfo.cFileName[0 .. clength]))) - break; - } while (FindNextFileW(h,&fileinfo) != FALSE); - FindClose(h); - } - } - else - { - WIN32_FIND_DATA fileinfo; - - h = FindFirstFileA(toMBSz(c), &fileinfo); - if (h != INVALID_HANDLE_VALUE) // should we throw exception if invalid? - { - do - { int clength; - wchar[] wbuf; - int n; - - // Skip "." and ".." - if (std.string.strcmp(fileinfo.cFileName, ".") == 0 || - std.string.strcmp(fileinfo.cFileName, "..") == 0) - continue; - - clength = std.string.strlen(fileinfo.cFileName); - - // Convert cFileName[] to unicode - wbuf.length = MultiByteToWideChar(0,0,fileinfo.cFileName,clength,null,0); - n = MultiByteToWideChar(0,0,fileinfo.cFileName,clength,cast(wchar*)wbuf,wbuf.length); - assert(n == wbuf.length); - // toUTF8() returns a new buffer - if (!callback(std.utf.toUTF8(wbuf))) - break; - } while (FindNextFileA(h,&fileinfo) != FALSE); - FindClose(h); - } - } -} - -/****************************************** - * Since Win 9x does not support the "W" API's, first convert - * to wchar, then convert to multibyte using the current code - * page. - * (Thanks to yaneurao for this) - */ - -char* toMBSz(char[] s) -{ - // Only need to do this if any chars have the high bit set - foreach (char c; s) - { - if (c >= 0x80) - { char[] result; - int i; - wchar* ws = std.utf.toUTF16z(s); - result.length = WideCharToMultiByte(0, 0, ws, -1, null, 0, null, null); - i = WideCharToMultiByte(0, 0, ws, -1, result, result.length, null, null); - assert(i == result.length); - return result; - } - } - return std.string.toStringz(s); -} - - -/*************************************************** - * Copy a file. - */ - -void copy(char[] from, char[] to) -{ - BOOL result; - - if (useWfuncs) - result = CopyFileW(std.utf.toUTF16z(from), std.utf.toUTF16z(to), false); - else - result = CopyFileA(toMBSz(from), toMBSz(to), false); - if (!result) - throw new FileException(to, GetLastError()); -} - - -} - -/* =========================== linux ======================= */ - -version (linux) -{ - -private import std.c.linux.linux; - -extern (C) char* strerror(int); - -/*********************************** - */ - -class FileException : Exception -{ - - uint errno; // operating system error code - - this(char[] name) - { - this(name, "file I/O"); - } - - this(char[] name, char[] message) - { - super(name ~ ": " ~ message); - } - - this(char[] name, uint errno) - { char* s = strerror(errno); - this(name, std.string.toString(s).dup); - this.errno = errno; - } -} - -/******************************************** - * Read a file. - * Returns: - * array of bytes read - */ - -void[] read(char[] name) -{ - uint size; - uint numread; - int fd; - struct_stat statbuf; - byte[] buf; - char *namez; - - namez = toStringz(name); - //printf("file.read('%s')\n",namez); - fd = std.c.linux.linux.open(namez, O_RDONLY); - if (fd == -1) - { - //printf("\topen error, errno = %d\n",getErrno()); - goto err1; - } - - //printf("\tfile opened\n"); - if (std.c.linux.linux.fstat(fd, &statbuf)) - { - //printf("\tfstat error, errno = %d\n",getErrno()); - goto err2; - } - size = statbuf.st_size; - buf = new byte[size]; - - numread = std.c.linux.linux.read(fd, cast(char*)buf, size); - if (numread != size) - { - //printf("\tread error, errno = %d\n",getErrno()); - goto err2; - } - - if (std.c.linux.linux.close(fd) == -1) - { - //printf("\tclose error, errno = %d\n",getErrno()); - goto err; - } - - return buf; - -err2: - std.c.linux.linux.close(fd); -err: - delete buf; - -err1: - throw new FileException(name, getErrno()); -} - -/********************************************* - * Write a file. - * Returns: - * 0 success - */ - -void write(char[] name, void[] buffer) -{ - int fd; - int numwritten; - char *namez; - - namez = toStringz(name); - fd = std.c.linux.linux.open(namez, O_CREAT | O_WRONLY | O_TRUNC, 0660); - if (fd == -1) - goto err; - - numwritten = std.c.linux.linux.write(fd, buffer, buffer.length); - if (buffer.length != numwritten) - goto err2; - - if (std.c.linux.linux.close(fd) == -1) - goto err; - - return; - -err2: - std.c.linux.linux.close(fd); -err: - throw new FileException(name, getErrno()); -} - - -/********************************************* - * Append to a file. - */ - -void append(char[] name, void[] buffer) -{ - int fd; - int numwritten; - char *namez; - - namez = toStringz(name); - fd = std.c.linux.linux.open(namez, O_APPEND | O_WRONLY | O_CREAT, 0660); - if (fd == -1) - goto err; - - numwritten = std.c.linux.linux.write(fd, buffer, buffer.length); - if (buffer.length != numwritten) - goto err2; - - if (std.c.linux.linux.close(fd) == -1) - goto err; - - return; - -err2: - std.c.linux.linux.close(fd); -err: - throw new FileException(name, getErrno()); -} - - -/*************************************************** - * Rename a file. - */ - -void rename(char[] from, char[] to) -{ - char *fromz = toStringz(from); - char *toz = toStringz(to); - - if (std.c.stdio.rename(fromz, toz) == -1) - throw new FileException(to, getErrno()); -} - - -/*************************************************** - * Delete a file. - */ - -void remove(char[] name) -{ - if (std.c.stdio.remove(toStringz(name)) == -1) - throw new FileException(name, getErrno()); -} - - -/*************************************************** - * Get file size. - */ - -ulong getSize(char[] name) -{ - uint size; - int fd; - struct_stat statbuf; - char *namez; - - namez = toStringz(name); - //printf("file.getSize('%s')\n",namez); - fd = std.c.linux.linux.open(namez, O_RDONLY); - if (fd == -1) - { - //printf("\topen error, errno = %d\n",getErrno()); - goto err1; - } - - //printf("\tfile opened\n"); - if (std.c.linux.linux.fstat(fd, &statbuf)) - { - //printf("\tfstat error, errno = %d\n",getErrno()); - goto err2; - } - size = statbuf.st_size; - - if (std.c.linux.linux.close(fd) == -1) - { - //printf("\tclose error, errno = %d\n",getErrno()); - goto err; - } - - return size; - -err2: - std.c.linux.linux.close(fd); -err: -err1: - throw new FileException(name, getErrno()); -} - - -/*************************************************** - * Get file attributes. - */ - -uint getAttributes(char[] name) -{ - struct_stat statbuf; - char *namez; - - namez = toStringz(name); - if (std.c.linux.linux.stat(namez, &statbuf)) - { - throw new FileException(name, getErrno()); - } - - return statbuf.st_mode; -} - -/**************************************************** - * Does file/directory exist? - */ - -int exists(char[] name) -{ - struct_stat statbuf; - char *namez; - - namez = toStringz(name); - if (std.c.linux.linux.stat(namez, &statbuf)) - { - return 0; - } - - return 1; -} - -/**************************************************** - * Is name a file? - */ - -int isfile(char[] name) -{ - return (getAttributes(name) & S_IFMT) == S_IFREG; // regular file -} - -/**************************************************** - * Is name a directory? - */ - -int isdir(char[] name) -{ - return (getAttributes(name) & S_IFMT) == S_IFDIR; -} - -/**************************************************** - * Change directory. - */ - -void chdir(char[] pathname) -{ - if (std.c.linux.linux.chdir(toStringz(pathname))) - { - throw new FileException(pathname, getErrno()); - } -} - -/**************************************************** - * Make directory. - */ - -void mkdir(char[] pathname) -{ - if (std.c.linux.linux.mkdir(toStringz(pathname), 0777)) - { - throw new FileException(pathname, getErrno()); - } -} - -/**************************************************** - * Remove directory. - */ - -void rmdir(char[] pathname) -{ - if (std.c.linux.linux.rmdir(toStringz(pathname))) - { - throw new FileException(pathname, getErrno()); - } -} - -/**************************************************** - * Get current directory. - */ - -char[] getcwd() -{ char* p; - - p = std.c.linux.linux.getcwd(null, 0); - if (!p) - { - throw new FileException("cannot get cwd", getErrno()); - } - - size_t len = std.string.strlen(p); - char[] buf = new char[len]; - buf[] = p[0 .. len]; - std.c.stdlib.free(p); - return buf; -} - -/*************************************************** - * Return contents of directory. - */ - -char[][] listdir(char[] pathname) -{ - char[][] result; - - bool listing(char[] filename) - { - result ~= filename; - return true; // continue - } - - listdir(pathname, &listing); - return result; -} - -void listdir(char[] pathname, bool delegate(char[] filename) callback) -{ - DIR* h; - dirent* fdata; - - h = opendir(toStringz(pathname)); - if (h) - { - while((fdata = readdir(h)) != null) - { - // Skip "." and ".." - if (!std.string.strcmp(fdata.d_name, ".") || - !std.string.strcmp(fdata.d_name, "..")) - continue; - - int len = std.string.strlen(fdata.d_name); - if (!callback(fdata.d_name[0 .. len].dup)) - break; - } - closedir(h); - } - else - { - throw new FileException(pathname, getErrno()); - } -} - -/*************************************************** - * Copy a file. - */ - -void copy(char[] from, char[] to) -{ - void[] buffer; - - /* If the file is very large, this won't work, but - * it's a good start. - * BUG: it should maintain the file timestamps - */ - buffer = read(from); - write(to, buffer); - delete buffer; -} - - - -} - + +/* + * Copyright (C) 2001-2004 by Digital Mars, www.digitalmars.com + * Written by Walter Bright, Christopher E. Miller, Andre Fornacon + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * + * o The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software + * in a product, an acknowledgment in the product documentation would be + * appreciated but is not required. + * o Altered source versions must be plainly marked as such, and must not + * be misrepresented as being the original software. + * o This notice may not be removed or altered from any source + * distribution. + */ + +module std.file; + +private import std.c.stdio; +private import std.c.stdlib; +private import std.path; +private import std.string; + +/* =========================== Win32 ======================= */ + +version (Win32) +{ + +private import std.c.windows.windows; +private import std.utf; +private import std.windows.syserror; + +int useWfuncs = 1; + +static this() +{ + // Win 95, 98, ME do not implement the W functions + useWfuncs = (GetVersion() < 0x80000000); +} + +/*********************************** + */ + +class FileException : Exception +{ + + uint errno; // operating system error code + + this(char[] name) + { + this(name, "file I/O"); + } + + this(char[] name, char[] message) + { + super(name ~ ": " ~ message); + } + + this(char[] name, uint errno) + { + this(name, sysErrorString(errno)); + this.errno = errno; + } +} + +/*********************************** + * Basic File operations. + */ + +/******************************************** + * Read a file. + * Returns: + * array of bytes read + */ + +void[] read(char[] name) +{ + DWORD size; + DWORD numread; + HANDLE h; + byte[] buf; + + if (useWfuncs) + { + wchar* namez = std.utf.toUTF16z(name); + h = CreateFileW(namez,GENERIC_READ,FILE_SHARE_READ,null,OPEN_EXISTING, + FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN,cast(HANDLE)null); + } + else + { + char* namez = toMBSz(name); + h = CreateFileA(namez,GENERIC_READ,FILE_SHARE_READ,null,OPEN_EXISTING, + FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN,cast(HANDLE)null); + } + + if (h == INVALID_HANDLE_VALUE) + goto err1; + + size = GetFileSize(h, null); + if (size == INVALID_FILE_SIZE) + goto err2; + + buf = new byte[size]; + + if (ReadFile(h,buf,size,&numread,null) != 1) + goto err2; + + if (numread != size) + goto err2; + + if (!CloseHandle(h)) + goto err; + + return buf; + +err2: + CloseHandle(h); +err: + delete buf; +err1: + throw new FileException(name, GetLastError()); +} + +/********************************************* + * Write a file. + * Returns: + * 0 success + */ + +void write(char[] name, void[] buffer) +{ + HANDLE h; + DWORD numwritten; + + if (useWfuncs) + { + wchar* namez = std.utf.toUTF16z(name); + h = CreateFileW(namez,GENERIC_WRITE,0,null,CREATE_ALWAYS, + FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN,cast(HANDLE)null); + } + else + { + char* namez = toMBSz(name); + h = CreateFileA(namez,GENERIC_WRITE,0,null,CREATE_ALWAYS, + FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN,cast(HANDLE)null); + } + if (h == INVALID_HANDLE_VALUE) + goto err; + + if (WriteFile(h,buffer,buffer.length,&numwritten,null) != 1) + goto err2; + + if (buffer.length != numwritten) + goto err2; + + if (!CloseHandle(h)) + goto err; + return; + +err2: + CloseHandle(h); +err: + throw new FileException(name, GetLastError()); +} + + +/********************************************* + * Append to a file. + */ + +void append(char[] name, void[] buffer) +{ + HANDLE h; + DWORD numwritten; + + if (useWfuncs) + { + wchar* namez = std.utf.toUTF16z(name); + h = CreateFileW(namez,GENERIC_WRITE,0,null,OPEN_ALWAYS, + FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN,cast(HANDLE)null); + } + else + { + char* namez = toMBSz(name); + h = CreateFileA(namez,GENERIC_WRITE,0,null,OPEN_ALWAYS, + FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN,cast(HANDLE)null); + } + if (h == INVALID_HANDLE_VALUE) + goto err; + + SetFilePointer(h, 0, null, FILE_END); + + if (WriteFile(h,buffer,buffer.length,&numwritten,null) != 1) + goto err2; + + if (buffer.length != numwritten) + goto err2; + + if (!CloseHandle(h)) + goto err; + return; + +err2: + CloseHandle(h); +err: + throw new FileException(name, GetLastError()); +} + + +/*************************************************** + * Rename a file. + */ + +void rename(char[] from, char[] to) +{ + BOOL result; + + if (useWfuncs) + result = MoveFileW(std.utf.toUTF16z(from), std.utf.toUTF16z(to)); + else + result = MoveFileA(toMBSz(from), toMBSz(to)); + if (!result) + throw new FileException(to, GetLastError()); +} + + +/*************************************************** + * Delete a file. + */ + +void remove(char[] name) +{ + BOOL result; + + if (useWfuncs) + result = DeleteFileW(std.utf.toUTF16z(name)); + else + result = DeleteFileA(toMBSz(name)); + if (!result) + throw new FileException(name, GetLastError()); +} + + +/*************************************************** + * Get file size. + */ + +ulong getSize(char[] name) +{ + HANDLE findhndl; + uint resulth; + uint resultl; + + if (useWfuncs) + { + WIN32_FIND_DATAW filefindbuf; + + findhndl = FindFirstFileW(std.utf.toUTF16z(name), &filefindbuf); + resulth = filefindbuf.nFileSizeHigh; + resultl = filefindbuf.nFileSizeLow; + } + else + { + WIN32_FIND_DATA filefindbuf; + + findhndl = FindFirstFileA(toMBSz(name), &filefindbuf); + resulth = filefindbuf.nFileSizeHigh; + resultl = filefindbuf.nFileSizeLow; + } + + if (findhndl == cast(HANDLE)-1) + { + throw new FileException(name, GetLastError()); + } + FindClose(findhndl); + return (cast(ulong)resulth << 32) + resultl; +} + +/*************************************************** + * Does file (or directory) exist? + */ + +int exists(char[] name) +{ + uint result; + + if (useWfuncs) + // http://msdn.microsoft.com/library/default.asp?url=/library/en-us/fileio/base/getfileattributes.asp + result = GetFileAttributesW(std.utf.toUTF16z(name)); + else + result = GetFileAttributesA(toMBSz(name)); + + return (result == 0xFFFFFFFF) ? 0 : 1; +} + +/*************************************************** + * Get file attributes. + */ + +uint getAttributes(char[] name) +{ + uint result; + + if (useWfuncs) + result = GetFileAttributesW(std.utf.toUTF16z(name)); + else + result = GetFileAttributesA(toMBSz(name)); + if (result == 0xFFFFFFFF) + { + throw new FileException(name, GetLastError()); + } + return result; +} + +/**************************************************** + * Is name a file? + */ + +int isfile(char[] name) +{ + return (getAttributes(name) & FILE_ATTRIBUTE_DIRECTORY) == 0; +} + +/**************************************************** + * Is name a directory? + */ + +int isdir(char[] name) +{ + return (getAttributes(name) & FILE_ATTRIBUTE_DIRECTORY) != 0; +} + +/**************************************************** + * Change directory. + */ + +void chdir(char[] pathname) +{ BOOL result; + + if (useWfuncs) + result = SetCurrentDirectoryW(std.utf.toUTF16z(pathname)); + else + result = SetCurrentDirectoryA(toMBSz(pathname)); + + if (!result) + { + throw new FileException(pathname, GetLastError()); + } +} + +/**************************************************** + * Make directory. + */ + +void mkdir(char[] pathname) +{ BOOL result; + + if (useWfuncs) + result = CreateDirectoryW(std.utf.toUTF16z(pathname), null); + else + result = CreateDirectoryA(toMBSz(pathname), null); + + if (!result) + { + throw new FileException(pathname, GetLastError()); + } +} + +/**************************************************** + * Remove directory. + */ + +void rmdir(char[] pathname) +{ BOOL result; + + if (useWfuncs) + result = RemoveDirectoryW(std.utf.toUTF16z(pathname)); + else + result = RemoveDirectoryA(toMBSz(pathname)); + + if (!result) + { + throw new FileException(pathname, GetLastError()); + } +} + +/**************************************************** + * Get current directory. + */ + +char[] getcwd() +{ + if (useWfuncs) + { + wchar[] dir; + int len; + wchar c; + + len = GetCurrentDirectoryW(0, &c); + if (!len) + goto Lerr; + dir = new wchar[len]; + len = GetCurrentDirectoryW(len, dir); + if (!len) + goto Lerr; + return std.utf.toUTF8(dir[0 .. len]); // leave off terminating 0 + } + else + { + char[] dir; + int len; + char c; + + len = GetCurrentDirectoryA(0, &c); + if (!len) + goto Lerr; + dir = new char[len]; + len = GetCurrentDirectoryA(len, dir); + if (!len) + goto Lerr; + return dir[0 .. len]; // leave off terminating 0 + } + +Lerr: + throw new FileException("getcwd", GetLastError()); +} + +/*************************************************** + * Return contents of directory. + */ + +char[][] listdir(char[] pathname) +{ + char[][] result; + + bool listing(char[] filename) + { + result ~= filename; + return true; // continue + } + + listdir(pathname, &listing); + return result; +} + +void listdir(char[] pathname, bool delegate(char[] filename) callback) +{ + char[] c; + HANDLE h; + + c = std.path.join(pathname, "*.*"); + if (useWfuncs) + { + WIN32_FIND_DATAW fileinfo; + + h = FindFirstFileW(std.utf.toUTF16z(c), &fileinfo); + if (h != INVALID_HANDLE_VALUE) + { + do + { int clength; + + // Skip "." and ".." + if (std.string.wcscmp(fileinfo.cFileName, ".") == 0 || + std.string.wcscmp(fileinfo.cFileName, "..") == 0) + continue; + + clength = std.string.wcslen(fileinfo.cFileName); + // toUTF8() returns a new buffer + if (!callback(std.utf.toUTF8(fileinfo.cFileName[0 .. clength]))) + break; + } while (FindNextFileW(h,&fileinfo) != FALSE); + FindClose(h); + } + } + else + { + WIN32_FIND_DATA fileinfo; + + h = FindFirstFileA(toMBSz(c), &fileinfo); + if (h != INVALID_HANDLE_VALUE) // should we throw exception if invalid? + { + do + { int clength; + wchar[] wbuf; + int n; + + // Skip "." and ".." + if (std.string.strcmp(fileinfo.cFileName, ".") == 0 || + std.string.strcmp(fileinfo.cFileName, "..") == 0) + continue; + + clength = std.string.strlen(fileinfo.cFileName); + + // Convert cFileName[] to unicode + wbuf.length = MultiByteToWideChar(0,0,fileinfo.cFileName,clength,null,0); + n = MultiByteToWideChar(0,0,fileinfo.cFileName,clength,cast(wchar*)wbuf,wbuf.length); + assert(n == wbuf.length); + // toUTF8() returns a new buffer + if (!callback(std.utf.toUTF8(wbuf))) + break; + } while (FindNextFileA(h,&fileinfo) != FALSE); + FindClose(h); + } + } +} + +/****************************************** + * Since Win 9x does not support the "W" API's, first convert + * to wchar, then convert to multibyte using the current code + * page. + * (Thanks to yaneurao for this) + */ + +char* toMBSz(char[] s) +{ + // Only need to do this if any chars have the high bit set + foreach (char c; s) + { + if (c >= 0x80) + { char[] result; + int i; + wchar* ws = std.utf.toUTF16z(s); + result.length = WideCharToMultiByte(0, 0, ws, -1, null, 0, null, null); + i = WideCharToMultiByte(0, 0, ws, -1, result, result.length, null, null); + assert(i == result.length); + return result; + } + } + return std.string.toStringz(s); +} + + +/*************************************************** + * Copy a file. + */ + +void copy(char[] from, char[] to) +{ + BOOL result; + + if (useWfuncs) + result = CopyFileW(std.utf.toUTF16z(from), std.utf.toUTF16z(to), false); + else + result = CopyFileA(toMBSz(from), toMBSz(to), false); + if (!result) + throw new FileException(to, GetLastError()); +} + + +} + +/* =========================== linux ======================= */ + +version (linux) +{ + +private import std.c.linux.linux; + +extern (C) char* strerror(int); +extern(C) int access(char *, int); +/*********************************** + */ + +class FileException : Exception +{ + + uint errno; // operating system error code + + this(char[] name) + { + this(name, "file I/O"); + } + + this(char[] name, char[] message) + { + super(name ~ ": " ~ message); + } + + this(char[] name, uint errno) + { char* s = strerror(errno); + this(name, std.string.toString(s).dup); + this.errno = errno; + } +} + +/******************************************** + * Read a file. + * Returns: + * array of bytes read + */ + +void[] read(char[] name) +{ + uint size; + uint numread; + int fd; + struct_stat statbuf; + byte[] buf; + char *namez; + + namez = toStringz(name); + //printf("file.read('%s')\n",namez); + fd = std.c.linux.linux.open(namez, O_RDONLY); + if (fd == -1) + { + //printf("\topen error, errno = %d\n",getErrno()); + goto err1; + } + + //printf("\tfile opened\n"); + if (std.c.linux.linux.fstat(fd, &statbuf)) + { + //printf("\tfstat error, errno = %d\n",getErrno()); + goto err2; + } + size = statbuf.st_size; + buf = new byte[size]; + + numread = std.c.linux.linux.read(fd, cast(char*)buf, size); + if (numread != size) + { + //printf("\tread error, errno = %d\n",getErrno()); + goto err2; + } + + if (std.c.linux.linux.close(fd) == -1) + { + //printf("\tclose error, errno = %d\n",getErrno()); + goto err; + } + + return buf; + +err2: + std.c.linux.linux.close(fd); +err: + delete buf; + +err1: + throw new FileException(name, getErrno()); +} + +/********************************************* + * Write a file. + * Returns: + * 0 success + */ + +void write(char[] name, void[] buffer) +{ + int fd; + int numwritten; + char *namez; + + namez = toStringz(name); + fd = std.c.linux.linux.open(namez, O_CREAT | O_WRONLY | O_TRUNC, 0660); + if (fd == -1) + goto err; + + numwritten = std.c.linux.linux.write(fd, buffer, buffer.length); + if (buffer.length != numwritten) + goto err2; + + if (std.c.linux.linux.close(fd) == -1) + goto err; + + return; + +err2: + std.c.linux.linux.close(fd); +err: + throw new FileException(name, getErrno()); +} + + +/********************************************* + * Append to a file. + */ + +void append(char[] name, void[] buffer) +{ + int fd; + int numwritten; + char *namez; + + namez = toStringz(name); + fd = std.c.linux.linux.open(namez, O_APPEND | O_WRONLY | O_CREAT, 0660); + if (fd == -1) + goto err; + + numwritten = std.c.linux.linux.write(fd, buffer, buffer.length); + if (buffer.length != numwritten) + goto err2; + + if (std.c.linux.linux.close(fd) == -1) + goto err; + + return; + +err2: + std.c.linux.linux.close(fd); +err: + throw new FileException(name, getErrno()); +} + + +/*************************************************** + * Rename a file. + */ + +void rename(char[] from, char[] to) +{ + char *fromz = toStringz(from); + char *toz = toStringz(to); + + if (std.c.stdio.rename(fromz, toz) == -1) + throw new FileException(to, getErrno()); +} + + +/*************************************************** + * Delete a file. + */ + +void remove(char[] name) +{ + if (std.c.stdio.remove(toStringz(name)) == -1) + throw new FileException(name, getErrno()); +} + + +/*************************************************** + * Get file size. + */ + +ulong getSize(char[] name) +{ + uint size; + int fd; + struct_stat statbuf; + char *namez; + + namez = toStringz(name); + //printf("file.getSize('%s')\n",namez); + fd = std.c.linux.linux.open(namez, O_RDONLY); + if (fd == -1) + { + //printf("\topen error, errno = %d\n",getErrno()); + goto err1; + } + + //printf("\tfile opened\n"); + if (std.c.linux.linux.fstat(fd, &statbuf)) + { + //printf("\tfstat error, errno = %d\n",getErrno()); + goto err2; + } + size = statbuf.st_size; + + if (std.c.linux.linux.close(fd) == -1) + { + //printf("\tclose error, errno = %d\n",getErrno()); + goto err; + } + + return size; + +err2: + std.c.linux.linux.close(fd); +err: +err1: + throw new FileException(name, getErrno()); +} + + +/*************************************************** + * Get file attributes. + */ + +uint getAttributes(char[] name) +{ + struct_stat statbuf; + char *namez; + + namez = toStringz(name); + if (std.c.linux.linux.stat(namez, &statbuf)) + { + throw new FileException(name, getErrno()); + } + + return statbuf.st_mode; +} + +/**************************************************** + * Does file/directory exist? + */ + +int exists(char[] name) +{ + if(access(toStringz(name),0)) + return 0; + else + return 1; +} + +/**************************************************** + * Is name a file? + */ + +int isfile(char[] name) +{ + return (getAttributes(name) & S_IFMT) == S_IFREG; // regular file +} + +/**************************************************** + * Is name a directory? + */ + +int isdir(char[] name) +{ + return (getAttributes(name) & S_IFMT) == S_IFDIR; +} + +/**************************************************** + * Change directory. + */ + +void chdir(char[] pathname) +{ + if (std.c.linux.linux.chdir(toStringz(pathname))) + { + throw new FileException(pathname, getErrno()); + } +} + +/**************************************************** + * Make directory. + */ + +void mkdir(char[] pathname) +{ + if (std.c.linux.linux.mkdir(toStringz(pathname), 0777)) + { + throw new FileException(pathname, getErrno()); + } +} + +/**************************************************** + * Remove directory. + */ + +void rmdir(char[] pathname) +{ + if (std.c.linux.linux.rmdir(toStringz(pathname))) + { + throw new FileException(pathname, getErrno()); + } +} + +/**************************************************** + * Get current directory. + */ + +char[] getcwd() +{ char* p; + + p = std.c.linux.linux.getcwd(null, 0); + if (!p) + { + throw new FileException("cannot get cwd", getErrno()); + } + + size_t len = std.string.strlen(p); + char[] buf = new char[len]; + buf[] = p[0 .. len]; + std.c.stdlib.free(p); + return buf; +} + +/*************************************************** + * Return contents of directory. + */ + +char[][] listdir(char[] pathname) +{ + char[][] result; + + bool listing(char[] filename) + { + result ~= filename; + return true; // continue + } + + listdir(pathname, &listing); + return result; +} + +void listdir(char[] pathname, bool delegate(char[] filename) callback) +{ + DIR* h; + dirent* fdata; + + h = opendir(toStringz(pathname)); + if (h) + { + while((fdata = readdir(h)) != null) + { + // Skip "." and ".." + if (!std.string.strcmp(fdata.d_name, ".") || + !std.string.strcmp(fdata.d_name, "..")) + continue; + + int len = std.string.strlen(fdata.d_name); + if (!callback(fdata.d_name[0 .. len].dup)) + break; + } + closedir(h); + } + else + { + throw new FileException(pathname, getErrno()); + } +} + +/*************************************************** + * Copy a file. + */ + +void copy(char[] from, char[] to) +{ + void[] buffer; + + /* If the file is very large, this won't work, but + * it's a good start. + * BUG: it should maintain the file timestamps + */ + buffer = read(from); + write(to, buffer); + delete buffer; +} + + + +} + |
July 04, 2005 Re: std.file.exists() | ||||
---|---|---|---|---|
| ||||
Posted in reply to Ameer Armaly | Is the linux function exists() the only thing changed here? "Ameer Armaly" <ameer@bellsouth.net> wrote in message news:Pine.LNX.4.61.0507041302450.1150@debian... > Alright here it is. I successfully compiled and tested phobos with these modifications. > --- file.d 2005-06-30 16:04:29.000000000 -0400 > +++ newfile.d 2005-07-04 12:55:21.000000000 -0400 > @@ -1,958 +1,952 @@ > - > -/* > - * Copyright (C) 2001-2004 by Digital Mars, www.digitalmars.com > - * Written by Walter Bright, Christopher E. Miller, Andre Fornacon > - * > - * This software is provided 'as-is', without any express or implied > - * warranty. In no event will the authors be held liable for any damages > - * arising from the use of this software. > - * > - * Permission is granted to anyone to use this software for any purpose, > - * including commercial applications, and to alter it and redistribute it > - * freely, subject to the following restrictions: > - * > - * o The origin of this software must not be misrepresented; you must not > - * claim that you wrote the original software. If you use this software > - * in a product, an acknowledgment in the product documentation would be > - * appreciated but is not required. > - * o Altered source versions must be plainly marked as such, and must not > - * be misrepresented as being the original software. > - * o This notice may not be removed or altered from any source > - * distribution. > - */ > - > -module std.file; > - > -private import std.c.stdio; > -private import std.c.stdlib; > -private import std.path; > -private import std.string; > - > -/* =========================== Win32 ======================= */ > - > -version (Win32) > -{ > - > -private import std.c.windows.windows; > -private import std.utf; > -private import std.windows.syserror; > - > -int useWfuncs = 1; > - > -static this() > -{ > - // Win 95, 98, ME do not implement the W functions > - useWfuncs = (GetVersion() < 0x80000000); > -} > - > -/*********************************** > - */ > - > -class FileException : Exception > -{ > - > - uint errno; // operating system error code > - > - this(char[] name) > - { > - this(name, "file I/O"); > - } > - > - this(char[] name, char[] message) > - { > - super(name ~ ": " ~ message); > - } > - > - this(char[] name, uint errno) > - { > - this(name, sysErrorString(errno)); > - this.errno = errno; > - } > -} > - > -/*********************************** > - * Basic File operations. > - */ > - > -/******************************************** > - * Read a file. > - * Returns: > - * array of bytes read > - */ > - > -void[] read(char[] name) > -{ > - DWORD size; > - DWORD numread; > - HANDLE h; > - byte[] buf; > - > - if (useWfuncs) > - { > - wchar* namez = std.utf.toUTF16z(name); > - h = CreateFileW(namez,GENERIC_READ,FILE_SHARE_READ,null,OPEN_EXISTING, > - FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN,cast(HANDLE)null); > - } > - else > - { > - char* namez = toMBSz(name); > - h = CreateFileA(namez,GENERIC_READ,FILE_SHARE_READ,null,OPEN_EXISTING, > - FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN,cast(HANDLE)null); > - } > - > - if (h == INVALID_HANDLE_VALUE) > - goto err1; > - > - size = GetFileSize(h, null); > - if (size == INVALID_FILE_SIZE) > - goto err2; > - > - buf = new byte[size]; > - > - if (ReadFile(h,buf,size,&numread,null) != 1) > - goto err2; > - > - if (numread != size) > - goto err2; > - > - if (!CloseHandle(h)) > - goto err; > - > - return buf; > - > -err2: > - CloseHandle(h); > -err: > - delete buf; > -err1: > - throw new FileException(name, GetLastError()); > -} > - > -/********************************************* > - * Write a file. > - * Returns: > - * 0 success > - */ > - > -void write(char[] name, void[] buffer) > -{ > - HANDLE h; > - DWORD numwritten; > - > - if (useWfuncs) > - { > - wchar* namez = std.utf.toUTF16z(name); > - h = CreateFileW(namez,GENERIC_WRITE,0,null,CREATE_ALWAYS, > - FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN,cast(HANDLE)null); > - } > - else > - { > - char* namez = toMBSz(name); > - h = CreateFileA(namez,GENERIC_WRITE,0,null,CREATE_ALWAYS, > - FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN,cast(HANDLE)null); > - } > - if (h == INVALID_HANDLE_VALUE) > - goto err; > - > - if (WriteFile(h,buffer,buffer.length,&numwritten,null) != 1) > - goto err2; > - > - if (buffer.length != numwritten) > - goto err2; > - > - if (!CloseHandle(h)) > - goto err; > - return; > - > -err2: > - CloseHandle(h); > -err: > - throw new FileException(name, GetLastError()); > -} > - > - > -/********************************************* > - * Append to a file. > - */ > - > -void append(char[] name, void[] buffer) > -{ > - HANDLE h; > - DWORD numwritten; > - > - if (useWfuncs) > - { > - wchar* namez = std.utf.toUTF16z(name); > - h = CreateFileW(namez,GENERIC_WRITE,0,null,OPEN_ALWAYS, > - FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN,cast(HANDLE)null); > - } > - else > - { > - char* namez = toMBSz(name); > - h = CreateFileA(namez,GENERIC_WRITE,0,null,OPEN_ALWAYS, > - FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN,cast(HANDLE)null); > - } > - if (h == INVALID_HANDLE_VALUE) > - goto err; > - > - SetFilePointer(h, 0, null, FILE_END); > - > - if (WriteFile(h,buffer,buffer.length,&numwritten,null) != 1) > - goto err2; > - > - if (buffer.length != numwritten) > - goto err2; > - > - if (!CloseHandle(h)) > - goto err; > - return; > - > -err2: > - CloseHandle(h); > -err: > - throw new FileException(name, GetLastError()); > -} > - > - > -/*************************************************** > - * Rename a file. > - */ > - > -void rename(char[] from, char[] to) > -{ > - BOOL result; > - > - if (useWfuncs) > - result = MoveFileW(std.utf.toUTF16z(from), std.utf.toUTF16z(to)); > - else > - result = MoveFileA(toMBSz(from), toMBSz(to)); > - if (!result) > - throw new FileException(to, GetLastError()); > -} > - > - > -/*************************************************** > - * Delete a file. > - */ > - > -void remove(char[] name) > -{ > - BOOL result; > - > - if (useWfuncs) > - result = DeleteFileW(std.utf.toUTF16z(name)); > - else > - result = DeleteFileA(toMBSz(name)); > - if (!result) > - throw new FileException(name, GetLastError()); > -} > - > - > -/*************************************************** > - * Get file size. > - */ > - > -ulong getSize(char[] name) > -{ > - HANDLE findhndl; > - uint resulth; > - uint resultl; > - > - if (useWfuncs) > - { > - WIN32_FIND_DATAW filefindbuf; > - > - findhndl = FindFirstFileW(std.utf.toUTF16z(name), &filefindbuf); > - resulth = filefindbuf.nFileSizeHigh; > - resultl = filefindbuf.nFileSizeLow; > - } > - else > - { > - WIN32_FIND_DATA filefindbuf; > - > - findhndl = FindFirstFileA(toMBSz(name), &filefindbuf); > - resulth = filefindbuf.nFileSizeHigh; > - resultl = filefindbuf.nFileSizeLow; > - } > - > - if (findhndl == cast(HANDLE)-1) > - { > - throw new FileException(name, GetLastError()); > - } > - FindClose(findhndl); > - return (cast(ulong)resulth << 32) + resultl; > -} > - > -/*************************************************** > - * Does file (or directory) exist? > - */ > - > -int exists(char[] name) > -{ > - uint result; > - > - if (useWfuncs) > - // http://msdn.microsoft.com/library/default.asp?url=/library/en-us/fileio/base/getfileattributes.asp > - result = GetFileAttributesW(std.utf.toUTF16z(name)); > - else > - result = GetFileAttributesA(toMBSz(name)); > - > - return (result == 0xFFFFFFFF) ? 0 : 1; > -} > - > -/*************************************************** > - * Get file attributes. > - */ > - > -uint getAttributes(char[] name) > -{ > - uint result; > - > - if (useWfuncs) > - result = GetFileAttributesW(std.utf.toUTF16z(name)); > - else > - result = GetFileAttributesA(toMBSz(name)); > - if (result == 0xFFFFFFFF) > - { > - throw new FileException(name, GetLastError()); > - } > - return result; > -} > - > -/**************************************************** > - * Is name a file? > - */ > - > -int isfile(char[] name) > -{ > - return (getAttributes(name) & FILE_ATTRIBUTE_DIRECTORY) == 0; > -} > - > -/**************************************************** > - * Is name a directory? > - */ > - > -int isdir(char[] name) > -{ > - return (getAttributes(name) & FILE_ATTRIBUTE_DIRECTORY) != 0; > -} > - > -/**************************************************** > - * Change directory. > - */ > - > -void chdir(char[] pathname) > -{ BOOL result; > - > - if (useWfuncs) > - result = SetCurrentDirectoryW(std.utf.toUTF16z(pathname)); > - else > - result = SetCurrentDirectoryA(toMBSz(pathname)); > - > - if (!result) > - { > - throw new FileException(pathname, GetLastError()); > - } > -} > - > -/**************************************************** > - * Make directory. > - */ > - > -void mkdir(char[] pathname) > -{ BOOL result; > - > - if (useWfuncs) > - result = CreateDirectoryW(std.utf.toUTF16z(pathname), null); > - else > - result = CreateDirectoryA(toMBSz(pathname), null); > - > - if (!result) > - { > - throw new FileException(pathname, GetLastError()); > - } > -} > - > -/**************************************************** > - * Remove directory. > - */ > - > -void rmdir(char[] pathname) > -{ BOOL result; > - > - if (useWfuncs) > - result = RemoveDirectoryW(std.utf.toUTF16z(pathname)); > - else > - result = RemoveDirectoryA(toMBSz(pathname)); > - > - if (!result) > - { > - throw new FileException(pathname, GetLastError()); > - } > -} > - > -/**************************************************** > - * Get current directory. > - */ > - > -char[] getcwd() > -{ > - if (useWfuncs) > - { > - wchar[] dir; > - int len; > - wchar c; > - > - len = GetCurrentDirectoryW(0, &c); > - if (!len) > - goto Lerr; > - dir = new wchar[len]; > - len = GetCurrentDirectoryW(len, dir); > - if (!len) > - goto Lerr; > - return std.utf.toUTF8(dir[0 .. len]); // leave off terminating 0 > - } > - else > - { > - char[] dir; > - int len; > - char c; > - > - len = GetCurrentDirectoryA(0, &c); > - if (!len) > - goto Lerr; > - dir = new char[len]; > - len = GetCurrentDirectoryA(len, dir); > - if (!len) > - goto Lerr; > - return dir[0 .. len]; // leave off terminating 0 > - } > - > -Lerr: > - throw new FileException("getcwd", GetLastError()); > -} > - > -/*************************************************** > - * Return contents of directory. > - */ > - > -char[][] listdir(char[] pathname) > -{ > - char[][] result; > - > - bool listing(char[] filename) > - { > - result ~= filename; > - return true; // continue > - } > - > - listdir(pathname, &listing); > - return result; > -} > - > -void listdir(char[] pathname, bool delegate(char[] filename) callback) > -{ > - char[] c; > - HANDLE h; > - > - c = std.path.join(pathname, "*.*"); > - if (useWfuncs) > - { > - WIN32_FIND_DATAW fileinfo; > - > - h = FindFirstFileW(std.utf.toUTF16z(c), &fileinfo); > - if (h != INVALID_HANDLE_VALUE) > - { > - do > - { int clength; > - > - // Skip "." and ".." > - if (std.string.wcscmp(fileinfo.cFileName, ".") == 0 || > - std.string.wcscmp(fileinfo.cFileName, "..") == 0) > - continue; > - > - clength = std.string.wcslen(fileinfo.cFileName); > - // toUTF8() returns a new buffer > - if (!callback(std.utf.toUTF8(fileinfo.cFileName[0 .. clength]))) > - break; > - } while (FindNextFileW(h,&fileinfo) != FALSE); > - FindClose(h); > - } > - } > - else > - { > - WIN32_FIND_DATA fileinfo; > - > - h = FindFirstFileA(toMBSz(c), &fileinfo); > - if (h != INVALID_HANDLE_VALUE) // should we throw exception if invalid? > - { > - do > - { int clength; > - wchar[] wbuf; > - int n; > - > - // Skip "." and ".." > - if (std.string.strcmp(fileinfo.cFileName, ".") == 0 || > - std.string.strcmp(fileinfo.cFileName, "..") == 0) > - continue; > - > - clength = std.string.strlen(fileinfo.cFileName); > - > - // Convert cFileName[] to unicode > - wbuf.length = MultiByteToWideChar(0,0,fileinfo.cFileName,clength,null,0); > - n = MultiByteToWideChar(0,0,fileinfo.cFileName,clength,cast(wchar*)wbuf,wbuf.len gth); > - assert(n == wbuf.length); > - // toUTF8() returns a new buffer > - if (!callback(std.utf.toUTF8(wbuf))) > - break; > - } while (FindNextFileA(h,&fileinfo) != FALSE); > - FindClose(h); > - } > - } > -} > - > -/****************************************** > - * Since Win 9x does not support the "W" API's, first convert > - * to wchar, then convert to multibyte using the current code > - * page. > - * (Thanks to yaneurao for this) > - */ > - > -char* toMBSz(char[] s) > -{ > - // Only need to do this if any chars have the high bit set > - foreach (char c; s) > - { > - if (c >= 0x80) > - { char[] result; > - int i; > - wchar* ws = std.utf.toUTF16z(s); > - result.length = WideCharToMultiByte(0, 0, ws, -1, null, 0, null, null); > - i = WideCharToMultiByte(0, 0, ws, -1, result, result.length, null, null); > - assert(i == result.length); > - return result; > - } > - } > - return std.string.toStringz(s); > -} > - > - > -/*************************************************** > - * Copy a file. > - */ > - > -void copy(char[] from, char[] to) > -{ > - BOOL result; > - > - if (useWfuncs) > - result = CopyFileW(std.utf.toUTF16z(from), std.utf.toUTF16z(to), false); > - else > - result = CopyFileA(toMBSz(from), toMBSz(to), false); > - if (!result) > - throw new FileException(to, GetLastError()); > -} > - > - > -} > - > -/* =========================== linux ======================= */ > - > -version (linux) > -{ > - > -private import std.c.linux.linux; > - > -extern (C) char* strerror(int); > - > -/*********************************** > - */ > - > -class FileException : Exception > -{ > - > - uint errno; // operating system error code > - > - this(char[] name) > - { > - this(name, "file I/O"); > - } > - > - this(char[] name, char[] message) > - { > - super(name ~ ": " ~ message); > - } > - > - this(char[] name, uint errno) > - { char* s = strerror(errno); > - this(name, std.string.toString(s).dup); > - this.errno = errno; > - } > -} > - > -/******************************************** > - * Read a file. > - * Returns: > - * array of bytes read > - */ > - > -void[] read(char[] name) > -{ > - uint size; > - uint numread; > - int fd; > - struct_stat statbuf; > - byte[] buf; > - char *namez; > - > - namez = toStringz(name); > - //printf("file.read('%s')\n",namez); > - fd = std.c.linux.linux.open(namez, O_RDONLY); > - if (fd == -1) > - { > - //printf("\topen error, errno = %d\n",getErrno()); > - goto err1; > - } > - > - //printf("\tfile opened\n"); > - if (std.c.linux.linux.fstat(fd, &statbuf)) > - { > - //printf("\tfstat error, errno = %d\n",getErrno()); > - goto err2; > - } > - size = statbuf.st_size; > - buf = new byte[size]; > - > - numread = std.c.linux.linux.read(fd, cast(char*)buf, size); > - if (numread != size) > - { > - //printf("\tread error, errno = %d\n",getErrno()); > - goto err2; > - } > - > - if (std.c.linux.linux.close(fd) == -1) > - { > - //printf("\tclose error, errno = %d\n",getErrno()); > - goto err; > - } > - > - return buf; > - > -err2: > - std.c.linux.linux.close(fd); > -err: > - delete buf; > - > -err1: > - throw new FileException(name, getErrno()); > -} > - > -/********************************************* > - * Write a file. > - * Returns: > - * 0 success > - */ > - > -void write(char[] name, void[] buffer) > -{ > - int fd; > - int numwritten; > - char *namez; > - > - namez = toStringz(name); > - fd = std.c.linux.linux.open(namez, O_CREAT | O_WRONLY | O_TRUNC, 0660); > - if (fd == -1) > - goto err; > - > - numwritten = std.c.linux.linux.write(fd, buffer, buffer.length); > - if (buffer.length != numwritten) > - goto err2; > - > - if (std.c.linux.linux.close(fd) == -1) > - goto err; > - > - return; > - > -err2: > - std.c.linux.linux.close(fd); > -err: > - throw new FileException(name, getErrno()); > -} > - > - > -/********************************************* > - * Append to a file. > - */ > - > -void append(char[] name, void[] buffer) > -{ > - int fd; > - int numwritten; > - char *namez; > - > - namez = toStringz(name); > - fd = std.c.linux.linux.open(namez, O_APPEND | O_WRONLY | O_CREAT, 0660); > - if (fd == -1) > - goto err; > - > - numwritten = std.c.linux.linux.write(fd, buffer, buffer.length); > - if (buffer.length != numwritten) > - goto err2; > - > - if (std.c.linux.linux.close(fd) == -1) > - goto err; > - > - return; > - > -err2: > - std.c.linux.linux.close(fd); > -err: > - throw new FileException(name, getErrno()); > -} > - > - > -/*************************************************** > - * Rename a file. > - */ > - > -void rename(char[] from, char[] to) > -{ > - char *fromz = toStringz(from); > - char *toz = toStringz(to); > - > - if (std.c.stdio.rename(fromz, toz) == -1) > - throw new FileException(to, getErrno()); > -} > - > - > -/*************************************************** > - * Delete a file. > - */ > - > -void remove(char[] name) > -{ > - if (std.c.stdio.remove(toStringz(name)) == -1) > - throw new FileException(name, getErrno()); > -} > - > - > -/*************************************************** > - * Get file size. > - */ > - > -ulong getSize(char[] name) > -{ > - uint size; > - int fd; > - struct_stat statbuf; > - char *namez; > - > - namez = toStringz(name); > - //printf("file.getSize('%s')\n",namez); > - fd = std.c.linux.linux.open(namez, O_RDONLY); > - if (fd == -1) > - { > - //printf("\topen error, errno = %d\n",getErrno()); > - goto err1; > - } > - > - //printf("\tfile opened\n"); > - if (std.c.linux.linux.fstat(fd, &statbuf)) > - { > - //printf("\tfstat error, errno = %d\n",getErrno()); > - goto err2; > - } > - size = statbuf.st_size; > - > - if (std.c.linux.linux.close(fd) == -1) > - { > - //printf("\tclose error, errno = %d\n",getErrno()); > - goto err; > - } > - > - return size; > - > -err2: > - std.c.linux.linux.close(fd); > -err: > -err1: > - throw new FileException(name, getErrno()); > -} > - > - > -/*************************************************** > - * Get file attributes. > - */ > - > -uint getAttributes(char[] name) > -{ > - struct_stat statbuf; > - char *namez; > - > - namez = toStringz(name); > - if (std.c.linux.linux.stat(namez, &statbuf)) > - { > - throw new FileException(name, getErrno()); > - } > - > - return statbuf.st_mode; > -} > - > -/**************************************************** > - * Does file/directory exist? > - */ > - > -int exists(char[] name) > -{ > - struct_stat statbuf; > - char *namez; > - > - namez = toStringz(name); > - if (std.c.linux.linux.stat(namez, &statbuf)) > - { > - return 0; > - } > - > - return 1; > -} > - > -/**************************************************** > - * Is name a file? > - */ > - > -int isfile(char[] name) > -{ > - return (getAttributes(name) & S_IFMT) == S_IFREG; // regular file > -} > - > -/**************************************************** > - * Is name a directory? > - */ > - > -int isdir(char[] name) > -{ > - return (getAttributes(name) & S_IFMT) == S_IFDIR; > -} > - > -/**************************************************** > - * Change directory. > - */ > - > -void chdir(char[] pathname) > -{ > - if (std.c.linux.linux.chdir(toStringz(pathname))) > - { > - throw new FileException(pathname, getErrno()); > - } > -} > - > -/**************************************************** > - * Make directory. > - */ > - > -void mkdir(char[] pathname) > -{ > - if (std.c.linux.linux.mkdir(toStringz(pathname), 0777)) > - { > - throw new FileException(pathname, getErrno()); > - } > -} > - > -/**************************************************** > - * Remove directory. > - */ > - > -void rmdir(char[] pathname) > -{ > - if (std.c.linux.linux.rmdir(toStringz(pathname))) > - { > - throw new FileException(pathname, getErrno()); > - } > -} > - > -/**************************************************** > - * Get current directory. > - */ > - > -char[] getcwd() > -{ char* p; > - > - p = std.c.linux.linux.getcwd(null, 0); > - if (!p) > - { > - throw new FileException("cannot get cwd", getErrno()); > - } > - > - size_t len = std.string.strlen(p); > - char[] buf = new char[len]; > - buf[] = p[0 .. len]; > - std.c.stdlib.free(p); > - return buf; > -} > - > -/*************************************************** > - * Return contents of directory. > - */ > - > -char[][] listdir(char[] pathname) > -{ > - char[][] result; > - > - bool listing(char[] filename) > - { > - result ~= filename; > - return true; // continue > - } > - > - listdir(pathname, &listing); > - return result; > -} > - > -void listdir(char[] pathname, bool delegate(char[] filename) callback) > -{ > - DIR* h; > - dirent* fdata; > - > - h = opendir(toStringz(pathname)); > - if (h) > - { > - while((fdata = readdir(h)) != null) > - { > - // Skip "." and ".." > - if (!std.string.strcmp(fdata.d_name, ".") || > - !std.string.strcmp(fdata.d_name, "..")) > - continue; > - > - int len = std.string.strlen(fdata.d_name); > - if (!callback(fdata.d_name[0 .. len].dup)) > - break; > - } > - closedir(h); > - } > - else > - { > - throw new FileException(pathname, getErrno()); > - } > -} > - > -/*************************************************** > - * Copy a file. > - */ > - > -void copy(char[] from, char[] to) > -{ > - void[] buffer; > - > - /* If the file is very large, this won't work, but > - * it's a good start. > - * BUG: it should maintain the file timestamps > - */ > - buffer = read(from); > - write(to, buffer); > - delete buffer; > -} > - > - > - > -} > - > + > +/* > + * Copyright (C) 2001-2004 by Digital Mars, www.digitalmars.com > + * Written by Walter Bright, Christopher E. Miller, Andre Fornacon > + * > + * This software is provided 'as-is', without any express or implied > + * warranty. In no event will the authors be held liable for any damages > + * arising from the use of this software. > + * > + * Permission is granted to anyone to use this software for any purpose, > + * including commercial applications, and to alter it and redistribute it > + * freely, subject to the following restrictions: > + * > + * o The origin of this software must not be misrepresented; you must not > + * claim that you wrote the original software. If you use this software > + * in a product, an acknowledgment in the product documentation would be > + * appreciated but is not required. > + * o Altered source versions must be plainly marked as such, and must not > + * be misrepresented as being the original software. > + * o This notice may not be removed or altered from any source > + * distribution. > + */ > + > +module std.file; > + > +private import std.c.stdio; > +private import std.c.stdlib; > +private import std.path; > +private import std.string; > + > +/* =========================== Win32 ======================= */ > + > +version (Win32) > +{ > + > +private import std.c.windows.windows; > +private import std.utf; > +private import std.windows.syserror; > + > +int useWfuncs = 1; > + > +static this() > +{ > + // Win 95, 98, ME do not implement the W functions > + useWfuncs = (GetVersion() < 0x80000000); > +} > + > +/*********************************** > + */ > + > +class FileException : Exception > +{ > + > + uint errno; // operating system error code > + > + this(char[] name) > + { > + this(name, "file I/O"); > + } > + > + this(char[] name, char[] message) > + { > + super(name ~ ": " ~ message); > + } > + > + this(char[] name, uint errno) > + { > + this(name, sysErrorString(errno)); > + this.errno = errno; > + } > +} > + > +/*********************************** > + * Basic File operations. > + */ > + > +/******************************************** > + * Read a file. > + * Returns: > + * array of bytes read > + */ > + > +void[] read(char[] name) > +{ > + DWORD size; > + DWORD numread; > + HANDLE h; > + byte[] buf; > + > + if (useWfuncs) > + { > + wchar* namez = std.utf.toUTF16z(name); > + h = CreateFileW(namez,GENERIC_READ,FILE_SHARE_READ,null,OPEN_EXISTING, > + FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN,cast(HANDLE)null); > + } > + else > + { > + char* namez = toMBSz(name); > + h = CreateFileA(namez,GENERIC_READ,FILE_SHARE_READ,null,OPEN_EXISTING, > + FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN,cast(HANDLE)null); > + } > + > + if (h == INVALID_HANDLE_VALUE) > + goto err1; > + > + size = GetFileSize(h, null); > + if (size == INVALID_FILE_SIZE) > + goto err2; > + > + buf = new byte[size]; > + > + if (ReadFile(h,buf,size,&numread,null) != 1) > + goto err2; > + > + if (numread != size) > + goto err2; > + > + if (!CloseHandle(h)) > + goto err; > + > + return buf; > + > +err2: > + CloseHandle(h); > +err: > + delete buf; > +err1: > + throw new FileException(name, GetLastError()); > +} > + > +/********************************************* > + * Write a file. > + * Returns: > + * 0 success > + */ > + > +void write(char[] name, void[] buffer) > +{ > + HANDLE h; > + DWORD numwritten; > + > + if (useWfuncs) > + { > + wchar* namez = std.utf.toUTF16z(name); > + h = CreateFileW(namez,GENERIC_WRITE,0,null,CREATE_ALWAYS, > + FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN,cast(HANDLE)null); > + } > + else > + { > + char* namez = toMBSz(name); > + h = CreateFileA(namez,GENERIC_WRITE,0,null,CREATE_ALWAYS, > + FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN,cast(HANDLE)null); > + } > + if (h == INVALID_HANDLE_VALUE) > + goto err; > + > + if (WriteFile(h,buffer,buffer.length,&numwritten,null) != 1) > + goto err2; > + > + if (buffer.length != numwritten) > + goto err2; > + > + if (!CloseHandle(h)) > + goto err; > + return; > + > +err2: > + CloseHandle(h); > +err: > + throw new FileException(name, GetLastError()); > +} > + > + > +/********************************************* > + * Append to a file. > + */ > + > +void append(char[] name, void[] buffer) > +{ > + HANDLE h; > + DWORD numwritten; > + > + if (useWfuncs) > + { > + wchar* namez = std.utf.toUTF16z(name); > + h = CreateFileW(namez,GENERIC_WRITE,0,null,OPEN_ALWAYS, > + FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN,cast(HANDLE)null); > + } > + else > + { > + char* namez = toMBSz(name); > + h = CreateFileA(namez,GENERIC_WRITE,0,null,OPEN_ALWAYS, > + FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN,cast(HANDLE)null); > + } > + if (h == INVALID_HANDLE_VALUE) > + goto err; > + > + SetFilePointer(h, 0, null, FILE_END); > + > + if (WriteFile(h,buffer,buffer.length,&numwritten,null) != 1) > + goto err2; > + > + if (buffer.length != numwritten) > + goto err2; > + > + if (!CloseHandle(h)) > + goto err; > + return; > + > +err2: > + CloseHandle(h); > +err: > + throw new FileException(name, GetLastError()); > +} > + > + > +/*************************************************** > + * Rename a file. > + */ > + > +void rename(char[] from, char[] to) > +{ > + BOOL result; > + > + if (useWfuncs) > + result = MoveFileW(std.utf.toUTF16z(from), std.utf.toUTF16z(to)); > + else > + result = MoveFileA(toMBSz(from), toMBSz(to)); > + if (!result) > + throw new FileException(to, GetLastError()); > +} > + > + > +/*************************************************** > + * Delete a file. > + */ > + > +void remove(char[] name) > +{ > + BOOL result; > + > + if (useWfuncs) > + result = DeleteFileW(std.utf.toUTF16z(name)); > + else > + result = DeleteFileA(toMBSz(name)); > + if (!result) > + throw new FileException(name, GetLastError()); > +} > + > + > +/*************************************************** > + * Get file size. > + */ > + > +ulong getSize(char[] name) > +{ > + HANDLE findhndl; > + uint resulth; > + uint resultl; > + > + if (useWfuncs) > + { > + WIN32_FIND_DATAW filefindbuf; > + > + findhndl = FindFirstFileW(std.utf.toUTF16z(name), &filefindbuf); > + resulth = filefindbuf.nFileSizeHigh; > + resultl = filefindbuf.nFileSizeLow; > + } > + else > + { > + WIN32_FIND_DATA filefindbuf; > + > + findhndl = FindFirstFileA(toMBSz(name), &filefindbuf); > + resulth = filefindbuf.nFileSizeHigh; > + resultl = filefindbuf.nFileSizeLow; > + } > + > + if (findhndl == cast(HANDLE)-1) > + { > + throw new FileException(name, GetLastError()); > + } > + FindClose(findhndl); > + return (cast(ulong)resulth << 32) + resultl; > +} > + > +/*************************************************** > + * Does file (or directory) exist? > + */ > + > +int exists(char[] name) > +{ > + uint result; > + > + if (useWfuncs) > + // http://msdn.microsoft.com/library/default.asp?url=/library/en-us/fileio/base/getfileattributes.asp > + result = GetFileAttributesW(std.utf.toUTF16z(name)); > + else > + result = GetFileAttributesA(toMBSz(name)); > + > + return (result == 0xFFFFFFFF) ? 0 : 1; > +} > + > +/*************************************************** > + * Get file attributes. > + */ > + > +uint getAttributes(char[] name) > +{ > + uint result; > + > + if (useWfuncs) > + result = GetFileAttributesW(std.utf.toUTF16z(name)); > + else > + result = GetFileAttributesA(toMBSz(name)); > + if (result == 0xFFFFFFFF) > + { > + throw new FileException(name, GetLastError()); > + } > + return result; > +} > + > +/**************************************************** > + * Is name a file? > + */ > + > +int isfile(char[] name) > +{ > + return (getAttributes(name) & FILE_ATTRIBUTE_DIRECTORY) == 0; > +} > + > +/**************************************************** > + * Is name a directory? > + */ > + > +int isdir(char[] name) > +{ > + return (getAttributes(name) & FILE_ATTRIBUTE_DIRECTORY) != 0; > +} > + > +/**************************************************** > + * Change directory. > + */ > + > +void chdir(char[] pathname) > +{ BOOL result; > + > + if (useWfuncs) > + result = SetCurrentDirectoryW(std.utf.toUTF16z(pathname)); > + else > + result = SetCurrentDirectoryA(toMBSz(pathname)); > + > + if (!result) > + { > + throw new FileException(pathname, GetLastError()); > + } > +} > + > +/**************************************************** > + * Make directory. > + */ > + > +void mkdir(char[] pathname) > +{ BOOL result; > + > + if (useWfuncs) > + result = CreateDirectoryW(std.utf.toUTF16z(pathname), null); > + else > + result = CreateDirectoryA(toMBSz(pathname), null); > + > + if (!result) > + { > + throw new FileException(pathname, GetLastError()); > + } > +} > + > +/**************************************************** > + * Remove directory. > + */ > + > +void rmdir(char[] pathname) > +{ BOOL result; > + > + if (useWfuncs) > + result = RemoveDirectoryW(std.utf.toUTF16z(pathname)); > + else > + result = RemoveDirectoryA(toMBSz(pathname)); > + > + if (!result) > + { > + throw new FileException(pathname, GetLastError()); > + } > +} > + > +/**************************************************** > + * Get current directory. > + */ > + > +char[] getcwd() > +{ > + if (useWfuncs) > + { > + wchar[] dir; > + int len; > + wchar c; > + > + len = GetCurrentDirectoryW(0, &c); > + if (!len) > + goto Lerr; > + dir = new wchar[len]; > + len = GetCurrentDirectoryW(len, dir); > + if (!len) > + goto Lerr; > + return std.utf.toUTF8(dir[0 .. len]); // leave off terminating 0 > + } > + else > + { > + char[] dir; > + int len; > + char c; > + > + len = GetCurrentDirectoryA(0, &c); > + if (!len) > + goto Lerr; > + dir = new char[len]; > + len = GetCurrentDirectoryA(len, dir); > + if (!len) > + goto Lerr; > + return dir[0 .. len]; // leave off terminating 0 > + } > + > +Lerr: > + throw new FileException("getcwd", GetLastError()); > +} > + > +/*************************************************** > + * Return contents of directory. > + */ > + > +char[][] listdir(char[] pathname) > +{ > + char[][] result; > + > + bool listing(char[] filename) > + { > + result ~= filename; > + return true; // continue > + } > + > + listdir(pathname, &listing); > + return result; > +} > + > +void listdir(char[] pathname, bool delegate(char[] filename) callback) > +{ > + char[] c; > + HANDLE h; > + > + c = std.path.join(pathname, "*.*"); > + if (useWfuncs) > + { > + WIN32_FIND_DATAW fileinfo; > + > + h = FindFirstFileW(std.utf.toUTF16z(c), &fileinfo); > + if (h != INVALID_HANDLE_VALUE) > + { > + do > + { int clength; > + > + // Skip "." and ".." > + if (std.string.wcscmp(fileinfo.cFileName, ".") == 0 || > + std.string.wcscmp(fileinfo.cFileName, "..") == 0) > + continue; > + > + clength = std.string.wcslen(fileinfo.cFileName); > + // toUTF8() returns a new buffer > + if (!callback(std.utf.toUTF8(fileinfo.cFileName[0 .. clength]))) > + break; > + } while (FindNextFileW(h,&fileinfo) != FALSE); > + FindClose(h); > + } > + } > + else > + { > + WIN32_FIND_DATA fileinfo; > + > + h = FindFirstFileA(toMBSz(c), &fileinfo); > + if (h != INVALID_HANDLE_VALUE) // should we throw exception if invalid? > + { > + do > + { int clength; > + wchar[] wbuf; > + int n; > + > + // Skip "." and ".." > + if (std.string.strcmp(fileinfo.cFileName, ".") == 0 || > + std.string.strcmp(fileinfo.cFileName, "..") == 0) > + continue; > + > + clength = std.string.strlen(fileinfo.cFileName); > + > + // Convert cFileName[] to unicode > + wbuf.length = MultiByteToWideChar(0,0,fileinfo.cFileName,clength,null,0); > + n = MultiByteToWideChar(0,0,fileinfo.cFileName,clength,cast(wchar*)wbuf,wbuf.len gth); > + assert(n == wbuf.length); > + // toUTF8() returns a new buffer > + if (!callback(std.utf.toUTF8(wbuf))) > + break; > + } while (FindNextFileA(h,&fileinfo) != FALSE); > + FindClose(h); > + } > + } > +} > + > +/****************************************** > + * Since Win 9x does not support the "W" API's, first convert > + * to wchar, then convert to multibyte using the current code > + * page. > + * (Thanks to yaneurao for this) > + */ > + > +char* toMBSz(char[] s) > +{ > + // Only need to do this if any chars have the high bit set > + foreach (char c; s) > + { > + if (c >= 0x80) > + { char[] result; > + int i; > + wchar* ws = std.utf.toUTF16z(s); > + result.length = WideCharToMultiByte(0, 0, ws, -1, null, 0, null, null); > + i = WideCharToMultiByte(0, 0, ws, -1, result, result.length, null, null); > + assert(i == result.length); > + return result; > + } > + } > + return std.string.toStringz(s); > +} > + > + > +/*************************************************** > + * Copy a file. > + */ > + > +void copy(char[] from, char[] to) > +{ > + BOOL result; > + > + if (useWfuncs) > + result = CopyFileW(std.utf.toUTF16z(from), std.utf.toUTF16z(to), false); > + else > + result = CopyFileA(toMBSz(from), toMBSz(to), false); > + if (!result) > + throw new FileException(to, GetLastError()); > +} > + > + > +} > + > +/* =========================== linux ======================= */ > + > +version (linux) > +{ > + > +private import std.c.linux.linux; > + > +extern (C) char* strerror(int); > +extern(C) int access(char *, int); > +/*********************************** > + */ > + > +class FileException : Exception > +{ > + > + uint errno; // operating system error code > + > + this(char[] name) > + { > + this(name, "file I/O"); > + } > + > + this(char[] name, char[] message) > + { > + super(name ~ ": " ~ message); > + } > + > + this(char[] name, uint errno) > + { char* s = strerror(errno); > + this(name, std.string.toString(s).dup); > + this.errno = errno; > + } > +} > + > +/******************************************** > + * Read a file. > + * Returns: > + * array of bytes read > + */ > + > +void[] read(char[] name) > +{ > + uint size; > + uint numread; > + int fd; > + struct_stat statbuf; > + byte[] buf; > + char *namez; > + > + namez = toStringz(name); > + //printf("file.read('%s')\n",namez); > + fd = std.c.linux.linux.open(namez, O_RDONLY); > + if (fd == -1) > + { > + //printf("\topen error, errno = %d\n",getErrno()); > + goto err1; > + } > + > + //printf("\tfile opened\n"); > + if (std.c.linux.linux.fstat(fd, &statbuf)) > + { > + //printf("\tfstat error, errno = %d\n",getErrno()); > + goto err2; > + } > + size = statbuf.st_size; > + buf = new byte[size]; > + > + numread = std.c.linux.linux.read(fd, cast(char*)buf, size); > + if (numread != size) > + { > + //printf("\tread error, errno = %d\n",getErrno()); > + goto err2; > + } > + > + if (std.c.linux.linux.close(fd) == -1) > + { > + //printf("\tclose error, errno = %d\n",getErrno()); > + goto err; > + } > + > + return buf; > + > +err2: > + std.c.linux.linux.close(fd); > +err: > + delete buf; > + > +err1: > + throw new FileException(name, getErrno()); > +} > + > +/********************************************* > + * Write a file. > + * Returns: > + * 0 success > + */ > + > +void write(char[] name, void[] buffer) > +{ > + int fd; > + int numwritten; > + char *namez; > + > + namez = toStringz(name); > + fd = std.c.linux.linux.open(namez, O_CREAT | O_WRONLY | O_TRUNC, 0660); > + if (fd == -1) > + goto err; > + > + numwritten = std.c.linux.linux.write(fd, buffer, buffer.length); > + if (buffer.length != numwritten) > + goto err2; > + > + if (std.c.linux.linux.close(fd) == -1) > + goto err; > + > + return; > + > +err2: > + std.c.linux.linux.close(fd); > +err: > + throw new FileException(name, getErrno()); > +} > + > + > +/********************************************* > + * Append to a file. > + */ > + > +void append(char[] name, void[] buffer) > +{ > + int fd; > + int numwritten; > + char *namez; > + > + namez = toStringz(name); > + fd = std.c.linux.linux.open(namez, O_APPEND | O_WRONLY | O_CREAT, 0660); > + if (fd == -1) > + goto err; > + > + numwritten = std.c.linux.linux.write(fd, buffer, buffer.length); > + if (buffer.length != numwritten) > + goto err2; > + > + if (std.c.linux.linux.close(fd) == -1) > + goto err; > + > + return; > + > +err2: > + std.c.linux.linux.close(fd); > +err: > + throw new FileException(name, getErrno()); > +} > + > + > +/*************************************************** > + * Rename a file. > + */ > + > +void rename(char[] from, char[] to) > +{ > + char *fromz = toStringz(from); > + char *toz = toStringz(to); > + > + if (std.c.stdio.rename(fromz, toz) == -1) > + throw new FileException(to, getErrno()); > +} > + > + > +/*************************************************** > + * Delete a file. > + */ > + > +void remove(char[] name) > +{ > + if (std.c.stdio.remove(toStringz(name)) == -1) > + throw new FileException(name, getErrno()); > +} > + > + > +/*************************************************** > + * Get file size. > + */ > + > +ulong getSize(char[] name) > +{ > + uint size; > + int fd; > + struct_stat statbuf; > + char *namez; > + > + namez = toStringz(name); > + //printf("file.getSize('%s')\n",namez); > + fd = std.c.linux.linux.open(namez, O_RDONLY); > + if (fd == -1) > + { > + //printf("\topen error, errno = %d\n",getErrno()); > + goto err1; > + } > + > + //printf("\tfile opened\n"); > + if (std.c.linux.linux.fstat(fd, &statbuf)) > + { > + //printf("\tfstat error, errno = %d\n",getErrno()); > + goto err2; > + } > + size = statbuf.st_size; > + > + if (std.c.linux.linux.close(fd) == -1) > + { > + //printf("\tclose error, errno = %d\n",getErrno()); > + goto err; > + } > + > + return size; > + > +err2: > + std.c.linux.linux.close(fd); > +err: > +err1: > + throw new FileException(name, getErrno()); > +} > + > + > +/*************************************************** > + * Get file attributes. > + */ > + > +uint getAttributes(char[] name) > +{ > + struct_stat statbuf; > + char *namez; > + > + namez = toStringz(name); > + if (std.c.linux.linux.stat(namez, &statbuf)) > + { > + throw new FileException(name, getErrno()); > + } > + > + return statbuf.st_mode; > +} > + > +/**************************************************** > + * Does file/directory exist? > + */ > + > +int exists(char[] name) > +{ > + if(access(toStringz(name),0)) > + return 0; > + else > + return 1; > +} > + > +/**************************************************** > + * Is name a file? > + */ > + > +int isfile(char[] name) > +{ > + return (getAttributes(name) & S_IFMT) == S_IFREG; // regular file > +} > + > +/**************************************************** > + * Is name a directory? > + */ > + > +int isdir(char[] name) > +{ > + return (getAttributes(name) & S_IFMT) == S_IFDIR; > +} > + > +/**************************************************** > + * Change directory. > + */ > + > +void chdir(char[] pathname) > +{ > + if (std.c.linux.linux.chdir(toStringz(pathname))) > + { > + throw new FileException(pathname, getErrno()); > + } > +} > + > +/**************************************************** > + * Make directory. > + */ > + > +void mkdir(char[] pathname) > +{ > + if (std.c.linux.linux.mkdir(toStringz(pathname), 0777)) > + { > + throw new FileException(pathname, getErrno()); > + } > +} > + > +/**************************************************** > + * Remove directory. > + */ > + > +void rmdir(char[] pathname) > +{ > + if (std.c.linux.linux.rmdir(toStringz(pathname))) > + { > + throw new FileException(pathname, getErrno()); > + } > +} > + > +/**************************************************** > + * Get current directory. > + */ > + > +char[] getcwd() > +{ char* p; > + > + p = std.c.linux.linux.getcwd(null, 0); > + if (!p) > + { > + throw new FileException("cannot get cwd", getErrno()); > + } > + > + size_t len = std.string.strlen(p); > + char[] buf = new char[len]; > + buf[] = p[0 .. len]; > + std.c.stdlib.free(p); > + return buf; > +} > + > +/*************************************************** > + * Return contents of directory. > + */ > + > +char[][] listdir(char[] pathname) > +{ > + char[][] result; > + > + bool listing(char[] filename) > + { > + result ~= filename; > + return true; // continue > + } > + > + listdir(pathname, &listing); > + return result; > +} > + > +void listdir(char[] pathname, bool delegate(char[] filename) callback) > +{ > + DIR* h; > + dirent* fdata; > + > + h = opendir(toStringz(pathname)); > + if (h) > + { > + while((fdata = readdir(h)) != null) > + { > + // Skip "." and ".." > + if (!std.string.strcmp(fdata.d_name, ".") || > + !std.string.strcmp(fdata.d_name, "..")) > + continue; > + > + int len = std.string.strlen(fdata.d_name); > + if (!callback(fdata.d_name[0 .. len].dup)) > + break; > + } > + closedir(h); > + } > + else > + { > + throw new FileException(pathname, getErrno()); > + } > +} > + > +/*************************************************** > + * Copy a file. > + */ > + > +void copy(char[] from, char[] to) > +{ > + void[] buffer; > + > + /* If the file is very large, this won't work, but > + * it's a good start. > + * BUG: it should maintain the file timestamps > + */ > + buffer = read(from); > + write(to, buffer); > + delete buffer; > +} > + > + > + > +} > + > |
July 04, 2005 Re: std.file.exists() | ||||
---|---|---|---|---|
| ||||
Posted in reply to Walter | On Mon, 4 Jul 2005, Walter wrote: > Is the linux function exists() the only thing changed here? > Yes. > "Ameer Armaly" <ameer@bellsouth.net> wrote in message > news:Pine.LNX.4.61.0507041302450.1150@debian... >> Alright here it is. I successfully compiled and tested phobos with these >> modifications. >> --- file.d 2005-06-30 16:04:29.000000000 -0400 >> +++ newfile.d 2005-07-04 12:55:21.000000000 -0400 >> @@ -1,958 +1,952 @@ >> - >> -/* >> - * Copyright (C) 2001-2004 by Digital Mars, www.digitalmars.com >> - * Written by Walter Bright, Christopher E. Miller, Andre Fornacon >> - * >> - * This software is provided 'as-is', without any express or implied >> - * warranty. In no event will the authors be held liable for any damages >> - * arising from the use of this software. >> - * >> - * Permission is granted to anyone to use this software for any purpose, >> - * including commercial applications, and to alter it and redistribute > it >> - * freely, subject to the following restrictions: >> - * >> - * o The origin of this software must not be misrepresented; you must > not >> - * claim that you wrote the original software. If you use this > software >> - * in a product, an acknowledgment in the product documentation would > be >> - * appreciated but is not required. >> - * o Altered source versions must be plainly marked as such, and must > not >> - * be misrepresented as being the original software. >> - * o This notice may not be removed or altered from any source >> - * distribution. >> - */ >> - >> -module std.file; >> - >> -private import std.c.stdio; >> -private import std.c.stdlib; >> -private import std.path; >> -private import std.string; >> - >> -/* =========================== Win32 ======================= */ >> - >> -version (Win32) >> -{ >> - >> -private import std.c.windows.windows; >> -private import std.utf; >> -private import std.windows.syserror; >> - >> -int useWfuncs = 1; >> - >> -static this() >> -{ >> - // Win 95, 98, ME do not implement the W functions >> - useWfuncs = (GetVersion() < 0x80000000); >> -} >> - >> -/*********************************** >> - */ >> - >> -class FileException : Exception >> -{ >> - >> - uint errno; // operating system error code >> - >> - this(char[] name) >> - { >> - this(name, "file I/O"); >> - } >> - >> - this(char[] name, char[] message) >> - { >> - super(name ~ ": " ~ message); >> - } >> - >> - this(char[] name, uint errno) >> - { >> - this(name, sysErrorString(errno)); >> - this.errno = errno; >> - } >> -} >> - >> -/*********************************** >> - * Basic File operations. >> - */ >> - >> -/******************************************** >> - * Read a file. >> - * Returns: >> - * array of bytes read >> - */ >> - >> -void[] read(char[] name) >> -{ >> - DWORD size; >> - DWORD numread; >> - HANDLE h; >> - byte[] buf; >> - >> - if (useWfuncs) >> - { >> - wchar* namez = std.utf.toUTF16z(name); >> - h = CreateFileW(namez,GENERIC_READ,FILE_SHARE_READ,null,OPEN_EXISTING, >> - FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN,cast(HANDLE)null); >> - } >> - else >> - { >> - char* namez = toMBSz(name); >> - h = CreateFileA(namez,GENERIC_READ,FILE_SHARE_READ,null,OPEN_EXISTING, >> - FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN,cast(HANDLE)null); >> - } >> - >> - if (h == INVALID_HANDLE_VALUE) >> - goto err1; >> - >> - size = GetFileSize(h, null); >> - if (size == INVALID_FILE_SIZE) >> - goto err2; >> - >> - buf = new byte[size]; >> - >> - if (ReadFile(h,buf,size,&numread,null) != 1) >> - goto err2; >> - >> - if (numread != size) >> - goto err2; >> - >> - if (!CloseHandle(h)) >> - goto err; >> - >> - return buf; >> - >> -err2: >> - CloseHandle(h); >> -err: >> - delete buf; >> -err1: >> - throw new FileException(name, GetLastError()); >> -} >> - >> -/********************************************* >> - * Write a file. >> - * Returns: >> - * 0 success >> - */ >> - >> -void write(char[] name, void[] buffer) >> -{ >> - HANDLE h; >> - DWORD numwritten; >> - >> - if (useWfuncs) >> - { >> - wchar* namez = std.utf.toUTF16z(name); >> - h = CreateFileW(namez,GENERIC_WRITE,0,null,CREATE_ALWAYS, >> - FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN,cast(HANDLE)null); >> - } >> - else >> - { >> - char* namez = toMBSz(name); >> - h = CreateFileA(namez,GENERIC_WRITE,0,null,CREATE_ALWAYS, >> - FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN,cast(HANDLE)null); >> - } >> - if (h == INVALID_HANDLE_VALUE) >> - goto err; >> - >> - if (WriteFile(h,buffer,buffer.length,&numwritten,null) != 1) >> - goto err2; >> - >> - if (buffer.length != numwritten) >> - goto err2; >> - >> - if (!CloseHandle(h)) >> - goto err; >> - return; >> - >> -err2: >> - CloseHandle(h); >> -err: >> - throw new FileException(name, GetLastError()); >> -} >> - >> - >> -/********************************************* >> - * Append to a file. >> - */ >> - >> -void append(char[] name, void[] buffer) >> -{ >> - HANDLE h; >> - DWORD numwritten; >> - >> - if (useWfuncs) >> - { >> - wchar* namez = std.utf.toUTF16z(name); >> - h = CreateFileW(namez,GENERIC_WRITE,0,null,OPEN_ALWAYS, >> - FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN,cast(HANDLE)null); >> - } >> - else >> - { >> - char* namez = toMBSz(name); >> - h = CreateFileA(namez,GENERIC_WRITE,0,null,OPEN_ALWAYS, >> - FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN,cast(HANDLE)null); >> - } >> - if (h == INVALID_HANDLE_VALUE) >> - goto err; >> - >> - SetFilePointer(h, 0, null, FILE_END); >> - >> - if (WriteFile(h,buffer,buffer.length,&numwritten,null) != 1) >> - goto err2; >> - >> - if (buffer.length != numwritten) >> - goto err2; >> - >> - if (!CloseHandle(h)) >> - goto err; >> - return; >> - >> -err2: >> - CloseHandle(h); >> -err: >> - throw new FileException(name, GetLastError()); >> -} >> - >> - >> -/*************************************************** >> - * Rename a file. >> - */ >> - >> -void rename(char[] from, char[] to) >> -{ >> - BOOL result; >> - >> - if (useWfuncs) >> - result = MoveFileW(std.utf.toUTF16z(from), std.utf.toUTF16z(to)); >> - else >> - result = MoveFileA(toMBSz(from), toMBSz(to)); >> - if (!result) >> - throw new FileException(to, GetLastError()); >> -} >> - >> - >> -/*************************************************** >> - * Delete a file. >> - */ >> - >> -void remove(char[] name) >> -{ >> - BOOL result; >> - >> - if (useWfuncs) >> - result = DeleteFileW(std.utf.toUTF16z(name)); >> - else >> - result = DeleteFileA(toMBSz(name)); >> - if (!result) >> - throw new FileException(name, GetLastError()); >> -} >> - >> - >> -/*************************************************** >> - * Get file size. >> - */ >> - >> -ulong getSize(char[] name) >> -{ >> - HANDLE findhndl; >> - uint resulth; >> - uint resultl; >> - >> - if (useWfuncs) >> - { >> - WIN32_FIND_DATAW filefindbuf; >> - >> - findhndl = FindFirstFileW(std.utf.toUTF16z(name), &filefindbuf); >> - resulth = filefindbuf.nFileSizeHigh; >> - resultl = filefindbuf.nFileSizeLow; >> - } >> - else >> - { >> - WIN32_FIND_DATA filefindbuf; >> - >> - findhndl = FindFirstFileA(toMBSz(name), &filefindbuf); >> - resulth = filefindbuf.nFileSizeHigh; >> - resultl = filefindbuf.nFileSizeLow; >> - } >> - >> - if (findhndl == cast(HANDLE)-1) >> - { >> - throw new FileException(name, GetLastError()); >> - } >> - FindClose(findhndl); >> - return (cast(ulong)resulth << 32) + resultl; >> -} >> - >> -/*************************************************** >> - * Does file (or directory) exist? >> - */ >> - >> -int exists(char[] name) >> -{ >> - uint result; >> - >> - if (useWfuncs) >> - // > http://msdn.microsoft.com/library/default.asp?url=/library/en-us/fileio/base/getfileattributes.asp >> - result = GetFileAttributesW(std.utf.toUTF16z(name)); >> - else >> - result = GetFileAttributesA(toMBSz(name)); >> - >> - return (result == 0xFFFFFFFF) ? 0 : 1; >> -} >> - >> -/*************************************************** >> - * Get file attributes. >> - */ >> - >> -uint getAttributes(char[] name) >> -{ >> - uint result; >> - >> - if (useWfuncs) >> - result = GetFileAttributesW(std.utf.toUTF16z(name)); >> - else >> - result = GetFileAttributesA(toMBSz(name)); >> - if (result == 0xFFFFFFFF) >> - { >> - throw new FileException(name, GetLastError()); >> - } >> - return result; >> -} >> - >> -/**************************************************** >> - * Is name a file? >> - */ >> - >> -int isfile(char[] name) >> -{ >> - return (getAttributes(name) & FILE_ATTRIBUTE_DIRECTORY) == 0; >> -} >> - >> -/**************************************************** >> - * Is name a directory? >> - */ >> - >> -int isdir(char[] name) >> -{ >> - return (getAttributes(name) & FILE_ATTRIBUTE_DIRECTORY) != 0; >> -} >> - >> -/**************************************************** >> - * Change directory. >> - */ >> - >> -void chdir(char[] pathname) >> -{ BOOL result; >> - >> - if (useWfuncs) >> - result = SetCurrentDirectoryW(std.utf.toUTF16z(pathname)); >> - else >> - result = SetCurrentDirectoryA(toMBSz(pathname)); >> - >> - if (!result) >> - { >> - throw new FileException(pathname, GetLastError()); >> - } >> -} >> - >> -/**************************************************** >> - * Make directory. >> - */ >> - >> -void mkdir(char[] pathname) >> -{ BOOL result; >> - >> - if (useWfuncs) >> - result = CreateDirectoryW(std.utf.toUTF16z(pathname), null); >> - else >> - result = CreateDirectoryA(toMBSz(pathname), null); >> - >> - if (!result) >> - { >> - throw new FileException(pathname, GetLastError()); >> - } >> -} >> - >> -/**************************************************** >> - * Remove directory. >> - */ >> - >> -void rmdir(char[] pathname) >> -{ BOOL result; >> - >> - if (useWfuncs) >> - result = RemoveDirectoryW(std.utf.toUTF16z(pathname)); >> - else >> - result = RemoveDirectoryA(toMBSz(pathname)); >> - >> - if (!result) >> - { >> - throw new FileException(pathname, GetLastError()); >> - } >> -} >> - >> -/**************************************************** >> - * Get current directory. >> - */ >> - >> -char[] getcwd() >> -{ >> - if (useWfuncs) >> - { >> - wchar[] dir; >> - int len; >> - wchar c; >> - >> - len = GetCurrentDirectoryW(0, &c); >> - if (!len) >> - goto Lerr; >> - dir = new wchar[len]; >> - len = GetCurrentDirectoryW(len, dir); >> - if (!len) >> - goto Lerr; >> - return std.utf.toUTF8(dir[0 .. len]); // leave off terminating 0 >> - } >> - else >> - { >> - char[] dir; >> - int len; >> - char c; >> - >> - len = GetCurrentDirectoryA(0, &c); >> - if (!len) >> - goto Lerr; >> - dir = new char[len]; >> - len = GetCurrentDirectoryA(len, dir); >> - if (!len) >> - goto Lerr; >> - return dir[0 .. len]; // leave off terminating 0 >> - } >> - >> -Lerr: >> - throw new FileException("getcwd", GetLastError()); >> -} >> - >> -/*************************************************** >> - * Return contents of directory. >> - */ >> - >> -char[][] listdir(char[] pathname) >> -{ >> - char[][] result; >> - >> - bool listing(char[] filename) >> - { >> - result ~= filename; >> - return true; // continue >> - } >> - >> - listdir(pathname, &listing); >> - return result; >> -} >> - >> -void listdir(char[] pathname, bool delegate(char[] filename) callback) >> -{ >> - char[] c; >> - HANDLE h; >> - >> - c = std.path.join(pathname, "*.*"); >> - if (useWfuncs) >> - { >> - WIN32_FIND_DATAW fileinfo; >> - >> - h = FindFirstFileW(std.utf.toUTF16z(c), &fileinfo); >> - if (h != INVALID_HANDLE_VALUE) >> - { >> - do >> - { int clength; >> - >> - // Skip "." and ".." >> - if (std.string.wcscmp(fileinfo.cFileName, ".") == 0 || >> - std.string.wcscmp(fileinfo.cFileName, "..") == 0) >> - continue; >> - >> - clength = std.string.wcslen(fileinfo.cFileName); >> - // toUTF8() returns a new buffer >> - if (!callback(std.utf.toUTF8(fileinfo.cFileName[0 .. clength]))) >> - break; >> - } while (FindNextFileW(h,&fileinfo) != FALSE); >> - FindClose(h); >> - } >> - } >> - else >> - { >> - WIN32_FIND_DATA fileinfo; >> - >> - h = FindFirstFileA(toMBSz(c), &fileinfo); >> - if (h != INVALID_HANDLE_VALUE) // should we throw exception if invalid? >> - { >> - do >> - { int clength; >> - wchar[] wbuf; >> - int n; >> - >> - // Skip "." and ".." >> - if (std.string.strcmp(fileinfo.cFileName, ".") == 0 || >> - std.string.strcmp(fileinfo.cFileName, "..") == 0) >> - continue; >> - >> - clength = std.string.strlen(fileinfo.cFileName); >> - >> - // Convert cFileName[] to unicode >> - wbuf.length = > MultiByteToWideChar(0,0,fileinfo.cFileName,clength,null,0); >> - n = > MultiByteToWideChar(0,0,fileinfo.cFileName,clength,cast(wchar*)wbuf,wbuf.len > gth); >> - assert(n == wbuf.length); >> - // toUTF8() returns a new buffer >> - if (!callback(std.utf.toUTF8(wbuf))) >> - break; >> - } while (FindNextFileA(h,&fileinfo) != FALSE); >> - FindClose(h); >> - } >> - } >> -} >> - >> -/****************************************** >> - * Since Win 9x does not support the "W" API's, first convert >> - * to wchar, then convert to multibyte using the current code >> - * page. >> - * (Thanks to yaneurao for this) >> - */ >> - >> -char* toMBSz(char[] s) >> -{ >> - // Only need to do this if any chars have the high bit set >> - foreach (char c; s) >> - { >> - if (c >= 0x80) >> - { char[] result; >> - int i; >> - wchar* ws = std.utf.toUTF16z(s); >> - result.length = WideCharToMultiByte(0, 0, ws, -1, null, 0, null, > null); >> - i = WideCharToMultiByte(0, 0, ws, -1, result, result.length, null, > null); >> - assert(i == result.length); >> - return result; >> - } >> - } >> - return std.string.toStringz(s); >> -} >> - >> - >> -/*************************************************** >> - * Copy a file. >> - */ >> - >> -void copy(char[] from, char[] to) >> -{ >> - BOOL result; >> - >> - if (useWfuncs) >> - result = CopyFileW(std.utf.toUTF16z(from), std.utf.toUTF16z(to), false); >> - else >> - result = CopyFileA(toMBSz(from), toMBSz(to), false); >> - if (!result) >> - throw new FileException(to, GetLastError()); >> -} >> - >> - >> -} >> - >> -/* =========================== linux ======================= */ >> - >> -version (linux) >> -{ >> - >> -private import std.c.linux.linux; >> - >> -extern (C) char* strerror(int); >> - >> -/*********************************** >> - */ >> - >> -class FileException : Exception >> -{ >> - >> - uint errno; // operating system error code >> - >> - this(char[] name) >> - { >> - this(name, "file I/O"); >> - } >> - >> - this(char[] name, char[] message) >> - { >> - super(name ~ ": " ~ message); >> - } >> - >> - this(char[] name, uint errno) >> - { char* s = strerror(errno); >> - this(name, std.string.toString(s).dup); >> - this.errno = errno; >> - } >> -} >> - >> -/******************************************** >> - * Read a file. >> - * Returns: >> - * array of bytes read >> - */ >> - >> -void[] read(char[] name) >> -{ >> - uint size; >> - uint numread; >> - int fd; >> - struct_stat statbuf; >> - byte[] buf; >> - char *namez; >> - >> - namez = toStringz(name); >> - //printf("file.read('%s')\n",namez); >> - fd = std.c.linux.linux.open(namez, O_RDONLY); >> - if (fd == -1) >> - { >> - //printf("\topen error, errno = %d\n",getErrno()); >> - goto err1; >> - } >> - >> - //printf("\tfile opened\n"); >> - if (std.c.linux.linux.fstat(fd, &statbuf)) >> - { >> - //printf("\tfstat error, errno = %d\n",getErrno()); >> - goto err2; >> - } >> - size = statbuf.st_size; >> - buf = new byte[size]; >> - >> - numread = std.c.linux.linux.read(fd, cast(char*)buf, size); >> - if (numread != size) >> - { >> - //printf("\tread error, errno = %d\n",getErrno()); >> - goto err2; >> - } >> - >> - if (std.c.linux.linux.close(fd) == -1) >> - { >> - //printf("\tclose error, errno = %d\n",getErrno()); >> - goto err; >> - } >> - >> - return buf; >> - >> -err2: >> - std.c.linux.linux.close(fd); >> -err: >> - delete buf; >> - >> -err1: >> - throw new FileException(name, getErrno()); >> -} >> - >> -/********************************************* >> - * Write a file. >> - * Returns: >> - * 0 success >> - */ >> - >> -void write(char[] name, void[] buffer) >> -{ >> - int fd; >> - int numwritten; >> - char *namez; >> - >> - namez = toStringz(name); >> - fd = std.c.linux.linux.open(namez, O_CREAT | O_WRONLY | O_TRUNC, > 0660); >> - if (fd == -1) >> - goto err; >> - >> - numwritten = std.c.linux.linux.write(fd, buffer, buffer.length); >> - if (buffer.length != numwritten) >> - goto err2; >> - >> - if (std.c.linux.linux.close(fd) == -1) >> - goto err; >> - >> - return; >> - >> -err2: >> - std.c.linux.linux.close(fd); >> -err: >> - throw new FileException(name, getErrno()); >> -} >> - >> - >> -/********************************************* >> - * Append to a file. >> - */ >> - >> -void append(char[] name, void[] buffer) >> -{ >> - int fd; >> - int numwritten; >> - char *namez; >> - >> - namez = toStringz(name); >> - fd = std.c.linux.linux.open(namez, O_APPEND | O_WRONLY | O_CREAT, > 0660); >> - if (fd == -1) >> - goto err; >> - >> - numwritten = std.c.linux.linux.write(fd, buffer, buffer.length); >> - if (buffer.length != numwritten) >> - goto err2; >> - >> - if (std.c.linux.linux.close(fd) == -1) >> - goto err; >> - >> - return; >> - >> -err2: >> - std.c.linux.linux.close(fd); >> -err: >> - throw new FileException(name, getErrno()); >> -} >> - >> - >> -/*************************************************** >> - * Rename a file. >> - */ >> - >> -void rename(char[] from, char[] to) >> -{ >> - char *fromz = toStringz(from); >> - char *toz = toStringz(to); >> - >> - if (std.c.stdio.rename(fromz, toz) == -1) >> - throw new FileException(to, getErrno()); >> -} >> - >> - >> -/*************************************************** >> - * Delete a file. >> - */ >> - >> -void remove(char[] name) >> -{ >> - if (std.c.stdio.remove(toStringz(name)) == -1) >> - throw new FileException(name, getErrno()); >> -} >> - >> - >> -/*************************************************** >> - * Get file size. >> - */ >> - >> -ulong getSize(char[] name) >> -{ >> - uint size; >> - int fd; >> - struct_stat statbuf; >> - char *namez; >> - >> - namez = toStringz(name); >> - //printf("file.getSize('%s')\n",namez); >> - fd = std.c.linux.linux.open(namez, O_RDONLY); >> - if (fd == -1) >> - { >> - //printf("\topen error, errno = %d\n",getErrno()); >> - goto err1; >> - } >> - >> - //printf("\tfile opened\n"); >> - if (std.c.linux.linux.fstat(fd, &statbuf)) >> - { >> - //printf("\tfstat error, errno = %d\n",getErrno()); >> - goto err2; >> - } >> - size = statbuf.st_size; >> - >> - if (std.c.linux.linux.close(fd) == -1) >> - { >> - //printf("\tclose error, errno = %d\n",getErrno()); >> - goto err; >> - } >> - >> - return size; >> - >> -err2: >> - std.c.linux.linux.close(fd); >> -err: >> -err1: >> - throw new FileException(name, getErrno()); >> -} >> - >> - >> -/*************************************************** >> - * Get file attributes. >> - */ >> - >> -uint getAttributes(char[] name) >> -{ >> - struct_stat statbuf; >> - char *namez; >> - >> - namez = toStringz(name); >> - if (std.c.linux.linux.stat(namez, &statbuf)) >> - { >> - throw new FileException(name, getErrno()); >> - } >> - >> - return statbuf.st_mode; >> -} >> - >> -/**************************************************** >> - * Does file/directory exist? >> - */ >> - >> -int exists(char[] name) >> -{ >> - struct_stat statbuf; >> - char *namez; >> - >> - namez = toStringz(name); >> - if (std.c.linux.linux.stat(namez, &statbuf)) >> - { >> - return 0; >> - } >> - >> - return 1; >> -} >> - >> -/**************************************************** >> - * Is name a file? >> - */ >> - >> -int isfile(char[] name) >> -{ >> - return (getAttributes(name) & S_IFMT) == S_IFREG; // regular file >> -} >> - >> -/**************************************************** >> - * Is name a directory? >> - */ >> - >> -int isdir(char[] name) >> -{ >> - return (getAttributes(name) & S_IFMT) == S_IFDIR; >> -} >> - >> -/**************************************************** >> - * Change directory. >> - */ >> - >> -void chdir(char[] pathname) >> -{ >> - if (std.c.linux.linux.chdir(toStringz(pathname))) >> - { >> - throw new FileException(pathname, getErrno()); >> - } >> -} >> - >> -/**************************************************** >> - * Make directory. >> - */ >> - >> -void mkdir(char[] pathname) >> -{ >> - if (std.c.linux.linux.mkdir(toStringz(pathname), 0777)) >> - { >> - throw new FileException(pathname, getErrno()); >> - } >> -} >> - >> -/**************************************************** >> - * Remove directory. >> - */ >> - >> -void rmdir(char[] pathname) >> -{ >> - if (std.c.linux.linux.rmdir(toStringz(pathname))) >> - { >> - throw new FileException(pathname, getErrno()); >> - } >> -} >> - >> -/**************************************************** >> - * Get current directory. >> - */ >> - >> -char[] getcwd() >> -{ char* p; >> - >> - p = std.c.linux.linux.getcwd(null, 0); >> - if (!p) >> - { >> - throw new FileException("cannot get cwd", getErrno()); >> - } >> - >> - size_t len = std.string.strlen(p); >> - char[] buf = new char[len]; >> - buf[] = p[0 .. len]; >> - std.c.stdlib.free(p); >> - return buf; >> -} >> - >> -/*************************************************** >> - * Return contents of directory. >> - */ >> - >> -char[][] listdir(char[] pathname) >> -{ >> - char[][] result; >> - >> - bool listing(char[] filename) >> - { >> - result ~= filename; >> - return true; // continue >> - } >> - >> - listdir(pathname, &listing); >> - return result; >> -} >> - >> -void listdir(char[] pathname, bool delegate(char[] filename) callback) >> -{ >> - DIR* h; >> - dirent* fdata; >> - >> - h = opendir(toStringz(pathname)); >> - if (h) >> - { >> - while((fdata = readdir(h)) != null) >> - { >> - // Skip "." and ".." >> - if (!std.string.strcmp(fdata.d_name, ".") || >> - !std.string.strcmp(fdata.d_name, "..")) >> - continue; >> - >> - int len = std.string.strlen(fdata.d_name); >> - if (!callback(fdata.d_name[0 .. len].dup)) >> - break; >> - } >> - closedir(h); >> - } >> - else >> - { >> - throw new FileException(pathname, getErrno()); >> - } >> -} >> - >> -/*************************************************** >> - * Copy a file. >> - */ >> - >> -void copy(char[] from, char[] to) >> -{ >> - void[] buffer; >> - >> - /* If the file is very large, this won't work, but >> - * it's a good start. >> - * BUG: it should maintain the file timestamps >> - */ >> - buffer = read(from); >> - write(to, buffer); >> - delete buffer; >> -} >> - >> - >> - >> -} >> - >> + >> +/* >> + * Copyright (C) 2001-2004 by Digital Mars, www.digitalmars.com >> + * Written by Walter Bright, Christopher E. Miller, Andre Fornacon >> + * >> + * This software is provided 'as-is', without any express or implied >> + * warranty. In no event will the authors be held liable for any damages >> + * arising from the use of this software. >> + * >> + * Permission is granted to anyone to use this software for any purpose, >> + * including commercial applications, and to alter it and redistribute > it >> + * freely, subject to the following restrictions: >> + * >> + * o The origin of this software must not be misrepresented; you must > not >> + * claim that you wrote the original software. If you use this > software >> + * in a product, an acknowledgment in the product documentation would > be >> + * appreciated but is not required. >> + * o Altered source versions must be plainly marked as such, and must > not >> + * be misrepresented as being the original software. >> + * o This notice may not be removed or altered from any source >> + * distribution. >> + */ >> + >> +module std.file; >> + >> +private import std.c.stdio; >> +private import std.c.stdlib; >> +private import std.path; >> +private import std.string; >> + >> +/* =========================== Win32 ======================= */ >> + >> +version (Win32) >> +{ >> + >> +private import std.c.windows.windows; >> +private import std.utf; >> +private import std.windows.syserror; >> + >> +int useWfuncs = 1; >> + >> +static this() >> +{ >> + // Win 95, 98, ME do not implement the W functions >> + useWfuncs = (GetVersion() < 0x80000000); >> +} >> + >> +/*********************************** >> + */ >> + >> +class FileException : Exception >> +{ >> + >> + uint errno; // operating system error code >> + >> + this(char[] name) >> + { >> + this(name, "file I/O"); >> + } >> + >> + this(char[] name, char[] message) >> + { >> + super(name ~ ": " ~ message); >> + } >> + >> + this(char[] name, uint errno) >> + { >> + this(name, sysErrorString(errno)); >> + this.errno = errno; >> + } >> +} >> + >> +/*********************************** >> + * Basic File operations. >> + */ >> + >> +/******************************************** >> + * Read a file. >> + * Returns: >> + * array of bytes read >> + */ >> + >> +void[] read(char[] name) >> +{ >> + DWORD size; >> + DWORD numread; >> + HANDLE h; >> + byte[] buf; >> + >> + if (useWfuncs) >> + { >> + wchar* namez = std.utf.toUTF16z(name); >> + h = CreateFileW(namez,GENERIC_READ,FILE_SHARE_READ,null,OPEN_EXISTING, >> + FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN,cast(HANDLE)null); >> + } >> + else >> + { >> + char* namez = toMBSz(name); >> + h = CreateFileA(namez,GENERIC_READ,FILE_SHARE_READ,null,OPEN_EXISTING, >> + FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN,cast(HANDLE)null); >> + } >> + >> + if (h == INVALID_HANDLE_VALUE) >> + goto err1; >> + >> + size = GetFileSize(h, null); >> + if (size == INVALID_FILE_SIZE) >> + goto err2; >> + >> + buf = new byte[size]; >> + >> + if (ReadFile(h,buf,size,&numread,null) != 1) >> + goto err2; >> + >> + if (numread != size) >> + goto err2; >> + >> + if (!CloseHandle(h)) >> + goto err; >> + >> + return buf; >> + >> +err2: >> + CloseHandle(h); >> +err: >> + delete buf; >> +err1: >> + throw new FileException(name, GetLastError()); >> +} >> + >> +/********************************************* >> + * Write a file. >> + * Returns: >> + * 0 success >> + */ >> + >> +void write(char[] name, void[] buffer) >> +{ >> + HANDLE h; >> + DWORD numwritten; >> + >> + if (useWfuncs) >> + { >> + wchar* namez = std.utf.toUTF16z(name); >> + h = CreateFileW(namez,GENERIC_WRITE,0,null,CREATE_ALWAYS, >> + FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN,cast(HANDLE)null); >> + } >> + else >> + { >> + char* namez = toMBSz(name); >> + h = CreateFileA(namez,GENERIC_WRITE,0,null,CREATE_ALWAYS, >> + FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN,cast(HANDLE)null); >> + } >> + if (h == INVALID_HANDLE_VALUE) >> + goto err; >> + >> + if (WriteFile(h,buffer,buffer.length,&numwritten,null) != 1) >> + goto err2; >> + >> + if (buffer.length != numwritten) >> + goto err2; >> + >> + if (!CloseHandle(h)) >> + goto err; >> + return; >> + >> +err2: >> + CloseHandle(h); >> +err: >> + throw new FileException(name, GetLastError()); >> +} >> + >> + >> +/********************************************* >> + * Append to a file. >> + */ >> + >> +void append(char[] name, void[] buffer) >> +{ >> + HANDLE h; >> + DWORD numwritten; >> + >> + if (useWfuncs) >> + { >> + wchar* namez = std.utf.toUTF16z(name); >> + h = CreateFileW(namez,GENERIC_WRITE,0,null,OPEN_ALWAYS, >> + FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN,cast(HANDLE)null); >> + } >> + else >> + { >> + char* namez = toMBSz(name); >> + h = CreateFileA(namez,GENERIC_WRITE,0,null,OPEN_ALWAYS, >> + FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN,cast(HANDLE)null); >> + } >> + if (h == INVALID_HANDLE_VALUE) >> + goto err; >> + >> + SetFilePointer(h, 0, null, FILE_END); >> + >> + if (WriteFile(h,buffer,buffer.length,&numwritten,null) != 1) >> + goto err2; >> + >> + if (buffer.length != numwritten) >> + goto err2; >> + >> + if (!CloseHandle(h)) >> + goto err; >> + return; >> + >> +err2: >> + CloseHandle(h); >> +err: >> + throw new FileException(name, GetLastError()); >> +} >> + >> + >> +/*************************************************** >> + * Rename a file. >> + */ >> + >> +void rename(char[] from, char[] to) >> +{ >> + BOOL result; >> + >> + if (useWfuncs) >> + result = MoveFileW(std.utf.toUTF16z(from), std.utf.toUTF16z(to)); >> + else >> + result = MoveFileA(toMBSz(from), toMBSz(to)); >> + if (!result) >> + throw new FileException(to, GetLastError()); >> +} >> + >> + >> +/*************************************************** >> + * Delete a file. >> + */ >> + >> +void remove(char[] name) >> +{ >> + BOOL result; >> + >> + if (useWfuncs) >> + result = DeleteFileW(std.utf.toUTF16z(name)); >> + else >> + result = DeleteFileA(toMBSz(name)); >> + if (!result) >> + throw new FileException(name, GetLastError()); >> +} >> + >> + >> +/*************************************************** >> + * Get file size. >> + */ >> + >> +ulong getSize(char[] name) >> +{ >> + HANDLE findhndl; >> + uint resulth; >> + uint resultl; >> + >> + if (useWfuncs) >> + { >> + WIN32_FIND_DATAW filefindbuf; >> + >> + findhndl = FindFirstFileW(std.utf.toUTF16z(name), &filefindbuf); >> + resulth = filefindbuf.nFileSizeHigh; >> + resultl = filefindbuf.nFileSizeLow; >> + } >> + else >> + { >> + WIN32_FIND_DATA filefindbuf; >> + >> + findhndl = FindFirstFileA(toMBSz(name), &filefindbuf); >> + resulth = filefindbuf.nFileSizeHigh; >> + resultl = filefindbuf.nFileSizeLow; >> + } >> + >> + if (findhndl == cast(HANDLE)-1) >> + { >> + throw new FileException(name, GetLastError()); >> + } >> + FindClose(findhndl); >> + return (cast(ulong)resulth << 32) + resultl; >> +} >> + >> +/*************************************************** >> + * Does file (or directory) exist? >> + */ >> + >> +int exists(char[] name) >> +{ >> + uint result; >> + >> + if (useWfuncs) >> + // > http://msdn.microsoft.com/library/default.asp?url=/library/en-us/fileio/base/getfileattributes.asp >> + result = GetFileAttributesW(std.utf.toUTF16z(name)); >> + else >> + result = GetFileAttributesA(toMBSz(name)); >> + >> + return (result == 0xFFFFFFFF) ? 0 : 1; >> +} >> + >> +/*************************************************** >> + * Get file attributes. >> + */ >> + >> +uint getAttributes(char[] name) >> +{ >> + uint result; >> + >> + if (useWfuncs) >> + result = GetFileAttributesW(std.utf.toUTF16z(name)); >> + else >> + result = GetFileAttributesA(toMBSz(name)); >> + if (result == 0xFFFFFFFF) >> + { >> + throw new FileException(name, GetLastError()); >> + } >> + return result; >> +} >> + >> +/**************************************************** >> + * Is name a file? >> + */ >> + >> +int isfile(char[] name) >> +{ >> + return (getAttributes(name) & FILE_ATTRIBUTE_DIRECTORY) == 0; >> +} >> + >> +/**************************************************** >> + * Is name a directory? >> + */ >> + >> +int isdir(char[] name) >> +{ >> + return (getAttributes(name) & FILE_ATTRIBUTE_DIRECTORY) != 0; >> +} >> + >> +/**************************************************** >> + * Change directory. >> + */ >> + >> +void chdir(char[] pathname) >> +{ BOOL result; >> + >> + if (useWfuncs) >> + result = SetCurrentDirectoryW(std.utf.toUTF16z(pathname)); >> + else >> + result = SetCurrentDirectoryA(toMBSz(pathname)); >> + >> + if (!result) >> + { >> + throw new FileException(pathname, GetLastError()); >> + } >> +} >> + >> +/**************************************************** >> + * Make directory. >> + */ >> + >> +void mkdir(char[] pathname) >> +{ BOOL result; >> + >> + if (useWfuncs) >> + result = CreateDirectoryW(std.utf.toUTF16z(pathname), null); >> + else >> + result = CreateDirectoryA(toMBSz(pathname), null); >> + >> + if (!result) >> + { >> + throw new FileException(pathname, GetLastError()); >> + } >> +} >> + >> +/**************************************************** >> + * Remove directory. >> + */ >> + >> +void rmdir(char[] pathname) >> +{ BOOL result; >> + >> + if (useWfuncs) >> + result = RemoveDirectoryW(std.utf.toUTF16z(pathname)); >> + else >> + result = RemoveDirectoryA(toMBSz(pathname)); >> + >> + if (!result) >> + { >> + throw new FileException(pathname, GetLastError()); >> + } >> +} >> + >> +/**************************************************** >> + * Get current directory. >> + */ >> + >> +char[] getcwd() >> +{ >> + if (useWfuncs) >> + { >> + wchar[] dir; >> + int len; >> + wchar c; >> + >> + len = GetCurrentDirectoryW(0, &c); >> + if (!len) >> + goto Lerr; >> + dir = new wchar[len]; >> + len = GetCurrentDirectoryW(len, dir); >> + if (!len) >> + goto Lerr; >> + return std.utf.toUTF8(dir[0 .. len]); // leave off terminating 0 >> + } >> + else >> + { >> + char[] dir; >> + int len; >> + char c; >> + >> + len = GetCurrentDirectoryA(0, &c); >> + if (!len) >> + goto Lerr; >> + dir = new char[len]; >> + len = GetCurrentDirectoryA(len, dir); >> + if (!len) >> + goto Lerr; >> + return dir[0 .. len]; // leave off terminating 0 >> + } >> + >> +Lerr: >> + throw new FileException("getcwd", GetLastError()); >> +} >> + >> +/*************************************************** >> + * Return contents of directory. >> + */ >> + >> +char[][] listdir(char[] pathname) >> +{ >> + char[][] result; >> + >> + bool listing(char[] filename) >> + { >> + result ~= filename; >> + return true; // continue >> + } >> + >> + listdir(pathname, &listing); >> + return result; >> +} >> + >> +void listdir(char[] pathname, bool delegate(char[] filename) callback) >> +{ >> + char[] c; >> + HANDLE h; >> + >> + c = std.path.join(pathname, "*.*"); >> + if (useWfuncs) >> + { >> + WIN32_FIND_DATAW fileinfo; >> + >> + h = FindFirstFileW(std.utf.toUTF16z(c), &fileinfo); >> + if (h != INVALID_HANDLE_VALUE) >> + { >> + do >> + { int clength; >> + >> + // Skip "." and ".." >> + if (std.string.wcscmp(fileinfo.cFileName, ".") == 0 || >> + std.string.wcscmp(fileinfo.cFileName, "..") == 0) >> + continue; >> + >> + clength = std.string.wcslen(fileinfo.cFileName); >> + // toUTF8() returns a new buffer >> + if (!callback(std.utf.toUTF8(fileinfo.cFileName[0 .. clength]))) >> + break; >> + } while (FindNextFileW(h,&fileinfo) != FALSE); >> + FindClose(h); >> + } >> + } >> + else >> + { >> + WIN32_FIND_DATA fileinfo; >> + >> + h = FindFirstFileA(toMBSz(c), &fileinfo); >> + if (h != INVALID_HANDLE_VALUE) // should we throw exception if invalid? >> + { >> + do >> + { int clength; >> + wchar[] wbuf; >> + int n; >> + >> + // Skip "." and ".." >> + if (std.string.strcmp(fileinfo.cFileName, ".") == 0 || >> + std.string.strcmp(fileinfo.cFileName, "..") == 0) >> + continue; >> + >> + clength = std.string.strlen(fileinfo.cFileName); >> + >> + // Convert cFileName[] to unicode >> + wbuf.length = > MultiByteToWideChar(0,0,fileinfo.cFileName,clength,null,0); >> + n = > MultiByteToWideChar(0,0,fileinfo.cFileName,clength,cast(wchar*)wbuf,wbuf.len > gth); >> + assert(n == wbuf.length); >> + // toUTF8() returns a new buffer >> + if (!callback(std.utf.toUTF8(wbuf))) >> + break; >> + } while (FindNextFileA(h,&fileinfo) != FALSE); >> + FindClose(h); >> + } >> + } >> +} >> + >> +/****************************************** >> + * Since Win 9x does not support the "W" API's, first convert >> + * to wchar, then convert to multibyte using the current code >> + * page. >> + * (Thanks to yaneurao for this) >> + */ >> + >> +char* toMBSz(char[] s) >> +{ >> + // Only need to do this if any chars have the high bit set >> + foreach (char c; s) >> + { >> + if (c >= 0x80) >> + { char[] result; >> + int i; >> + wchar* ws = std.utf.toUTF16z(s); >> + result.length = WideCharToMultiByte(0, 0, ws, -1, null, 0, null, > null); >> + i = WideCharToMultiByte(0, 0, ws, -1, result, result.length, null, > null); >> + assert(i == result.length); >> + return result; >> + } >> + } >> + return std.string.toStringz(s); >> +} >> + >> + >> +/*************************************************** >> + * Copy a file. >> + */ >> + >> +void copy(char[] from, char[] to) >> +{ >> + BOOL result; >> + >> + if (useWfuncs) >> + result = CopyFileW(std.utf.toUTF16z(from), std.utf.toUTF16z(to), false); >> + else >> + result = CopyFileA(toMBSz(from), toMBSz(to), false); >> + if (!result) >> + throw new FileException(to, GetLastError()); >> +} >> + >> + >> +} >> + >> +/* =========================== linux ======================= */ >> + >> +version (linux) >> +{ >> + >> +private import std.c.linux.linux; >> + >> +extern (C) char* strerror(int); >> +extern(C) int access(char *, int); >> +/*********************************** >> + */ >> + >> +class FileException : Exception >> +{ >> + >> + uint errno; // operating system error code >> + >> + this(char[] name) >> + { >> + this(name, "file I/O"); >> + } >> + >> + this(char[] name, char[] message) >> + { >> + super(name ~ ": " ~ message); >> + } >> + >> + this(char[] name, uint errno) >> + { char* s = strerror(errno); >> + this(name, std.string.toString(s).dup); >> + this.errno = errno; >> + } >> +} >> + >> +/******************************************** >> + * Read a file. >> + * Returns: >> + * array of bytes read >> + */ >> + >> +void[] read(char[] name) >> +{ >> + uint size; >> + uint numread; >> + int fd; >> + struct_stat statbuf; >> + byte[] buf; >> + char *namez; >> + >> + namez = toStringz(name); >> + //printf("file.read('%s')\n",namez); >> + fd = std.c.linux.linux.open(namez, O_RDONLY); >> + if (fd == -1) >> + { >> + //printf("\topen error, errno = %d\n",getErrno()); >> + goto err1; >> + } >> + >> + //printf("\tfile opened\n"); >> + if (std.c.linux.linux.fstat(fd, &statbuf)) >> + { >> + //printf("\tfstat error, errno = %d\n",getErrno()); >> + goto err2; >> + } >> + size = statbuf.st_size; >> + buf = new byte[size]; >> + >> + numread = std.c.linux.linux.read(fd, cast(char*)buf, size); >> + if (numread != size) >> + { >> + //printf("\tread error, errno = %d\n",getErrno()); >> + goto err2; >> + } >> + >> + if (std.c.linux.linux.close(fd) == -1) >> + { >> + //printf("\tclose error, errno = %d\n",getErrno()); >> + goto err; >> + } >> + >> + return buf; >> + >> +err2: >> + std.c.linux.linux.close(fd); >> +err: >> + delete buf; >> + >> +err1: >> + throw new FileException(name, getErrno()); >> +} >> + >> +/********************************************* >> + * Write a file. >> + * Returns: >> + * 0 success >> + */ >> + >> +void write(char[] name, void[] buffer) >> +{ >> + int fd; >> + int numwritten; >> + char *namez; >> + >> + namez = toStringz(name); >> + fd = std.c.linux.linux.open(namez, O_CREAT | O_WRONLY | O_TRUNC, > 0660); >> + if (fd == -1) >> + goto err; >> + >> + numwritten = std.c.linux.linux.write(fd, buffer, buffer.length); >> + if (buffer.length != numwritten) >> + goto err2; >> + >> + if (std.c.linux.linux.close(fd) == -1) >> + goto err; >> + >> + return; >> + >> +err2: >> + std.c.linux.linux.close(fd); >> +err: >> + throw new FileException(name, getErrno()); >> +} >> + >> + >> +/********************************************* >> + * Append to a file. >> + */ >> + >> +void append(char[] name, void[] buffer) >> +{ >> + int fd; >> + int numwritten; >> + char *namez; >> + >> + namez = toStringz(name); >> + fd = std.c.linux.linux.open(namez, O_APPEND | O_WRONLY | O_CREAT, > 0660); >> + if (fd == -1) >> + goto err; >> + >> + numwritten = std.c.linux.linux.write(fd, buffer, buffer.length); >> + if (buffer.length != numwritten) >> + goto err2; >> + >> + if (std.c.linux.linux.close(fd) == -1) >> + goto err; >> + >> + return; >> + >> +err2: >> + std.c.linux.linux.close(fd); >> +err: >> + throw new FileException(name, getErrno()); >> +} >> + >> + >> +/*************************************************** >> + * Rename a file. >> + */ >> + >> +void rename(char[] from, char[] to) >> +{ >> + char *fromz = toStringz(from); >> + char *toz = toStringz(to); >> + >> + if (std.c.stdio.rename(fromz, toz) == -1) >> + throw new FileException(to, getErrno()); >> +} >> + >> + >> +/*************************************************** >> + * Delete a file. >> + */ >> + >> +void remove(char[] name) >> +{ >> + if (std.c.stdio.remove(toStringz(name)) == -1) >> + throw new FileException(name, getErrno()); >> +} >> + >> + >> +/*************************************************** >> + * Get file size. >> + */ >> + >> +ulong getSize(char[] name) >> +{ >> + uint size; >> + int fd; >> + struct_stat statbuf; >> + char *namez; >> + >> + namez = toStringz(name); >> + //printf("file.getSize('%s')\n",namez); >> + fd = std.c.linux.linux.open(namez, O_RDONLY); >> + if (fd == -1) >> + { >> + //printf("\topen error, errno = %d\n",getErrno()); >> + goto err1; >> + } >> + >> + //printf("\tfile opened\n"); >> + if (std.c.linux.linux.fstat(fd, &statbuf)) >> + { >> + //printf("\tfstat error, errno = %d\n",getErrno()); >> + goto err2; >> + } >> + size = statbuf.st_size; >> + >> + if (std.c.linux.linux.close(fd) == -1) >> + { >> + //printf("\tclose error, errno = %d\n",getErrno()); >> + goto err; >> + } >> + >> + return size; >> + >> +err2: >> + std.c.linux.linux.close(fd); >> +err: >> +err1: >> + throw new FileException(name, getErrno()); >> +} >> + >> + >> +/*************************************************** >> + * Get file attributes. >> + */ >> + >> +uint getAttributes(char[] name) >> +{ >> + struct_stat statbuf; >> + char *namez; >> + >> + namez = toStringz(name); >> + if (std.c.linux.linux.stat(namez, &statbuf)) >> + { >> + throw new FileException(name, getErrno()); >> + } >> + >> + return statbuf.st_mode; >> +} >> + >> +/**************************************************** >> + * Does file/directory exist? >> + */ >> + >> +int exists(char[] name) >> +{ >> + if(access(toStringz(name),0)) >> + return 0; >> + else >> + return 1; >> +} >> + >> +/**************************************************** >> + * Is name a file? >> + */ >> + >> +int isfile(char[] name) >> +{ >> + return (getAttributes(name) & S_IFMT) == S_IFREG; // regular file >> +} >> + >> +/**************************************************** >> + * Is name a directory? >> + */ >> + >> +int isdir(char[] name) >> +{ >> + return (getAttributes(name) & S_IFMT) == S_IFDIR; >> +} >> + >> +/**************************************************** >> + * Change directory. >> + */ >> + >> +void chdir(char[] pathname) >> +{ >> + if (std.c.linux.linux.chdir(toStringz(pathname))) >> + { >> + throw new FileException(pathname, getErrno()); >> + } >> +} >> + >> +/**************************************************** >> + * Make directory. >> + */ >> + >> +void mkdir(char[] pathname) >> +{ >> + if (std.c.linux.linux.mkdir(toStringz(pathname), 0777)) >> + { >> + throw new FileException(pathname, getErrno()); >> + } >> +} >> + >> +/**************************************************** >> + * Remove directory. >> + */ >> + >> +void rmdir(char[] pathname) >> +{ >> + if (std.c.linux.linux.rmdir(toStringz(pathname))) >> + { >> + throw new FileException(pathname, getErrno()); >> + } >> +} >> + >> +/**************************************************** >> + * Get current directory. >> + */ >> + >> +char[] getcwd() >> +{ char* p; >> + >> + p = std.c.linux.linux.getcwd(null, 0); >> + if (!p) >> + { >> + throw new FileException("cannot get cwd", getErrno()); >> + } >> + >> + size_t len = std.string.strlen(p); >> + char[] buf = new char[len]; >> + buf[] = p[0 .. len]; >> + std.c.stdlib.free(p); >> + return buf; >> +} >> + >> +/*************************************************** >> + * Return contents of directory. >> + */ >> + >> +char[][] listdir(char[] pathname) >> +{ >> + char[][] result; >> + >> + bool listing(char[] filename) >> + { >> + result ~= filename; >> + return true; // continue >> + } >> + >> + listdir(pathname, &listing); >> + return result; >> +} >> + >> +void listdir(char[] pathname, bool delegate(char[] filename) callback) >> +{ >> + DIR* h; >> + dirent* fdata; >> + >> + h = opendir(toStringz(pathname)); >> + if (h) >> + { >> + while((fdata = readdir(h)) != null) >> + { >> + // Skip "." and ".." >> + if (!std.string.strcmp(fdata.d_name, ".") || >> + !std.string.strcmp(fdata.d_name, "..")) >> + continue; >> + >> + int len = std.string.strlen(fdata.d_name); >> + if (!callback(fdata.d_name[0 .. len].dup)) >> + break; >> + } >> + closedir(h); >> + } >> + else >> + { >> + throw new FileException(pathname, getErrno()); >> + } >> +} >> + >> +/*************************************************** >> + * Copy a file. >> + */ >> + >> +void copy(char[] from, char[] to) >> +{ >> + void[] buffer; >> + >> + /* If the file is very large, this won't work, but >> + * it's a good start. >> + * BUG: it should maintain the file timestamps >> + */ >> + buffer = read(from); >> + write(to, buffer); >> + delete buffer; >> +} >> + >> + >> + >> +} >> + >> > > > |
July 07, 2005 Re: std.file.exists() | ||||
---|---|---|---|---|
| ||||
Posted in reply to Ameer Armaly | Congratulations, you've defeated the purpose of the patch/diff utility :). In article <Pine.LNX.4.61.0507041524470.1082@debian>, Ameer Armaly says... > > > >On Mon, 4 Jul 2005, Walter wrote: > >> Is the linux function exists() the only thing changed here? >> >Yes. >> "Ameer Armaly" <ameer@bellsouth.net> wrote in message news:Pine.LNX.4.61.0507041302450.1150@debian... >>> Alright here it is. I successfully compiled and tested phobos with these modifications. >>> --- file.d 2005-06-30 16:04:29.000000000 -0400 >>> +++ newfile.d 2005-07-04 12:55:21.000000000 -0400 >>> @@ -1,958 +1,952 @@ >>> - >>> -/* >>> - * Copyright (C) 2001-2004 by Digital Mars, www.digitalmars.com >>> - * Written by Walter Bright, Christopher E. Miller, Andre Fornacon >>> - * >>> - * This software is provided 'as-is', without any express or implied >>> - * warranty. In no event will the authors be held liable for any damages >>> - * arising from the use of this software. >>> - * >>> - * Permission is granted to anyone to use this software for any purpose, >>> - * including commercial applications, and to alter it and redistribute >> it >>> - * freely, subject to the following restrictions: >>> - * >>> - * o The origin of this software must not be misrepresented; you must >> not >>> - * claim that you wrote the original software. If you use this >> software >>> - * in a product, an acknowledgment in the product documentation would >> be >>> - * appreciated but is not required. >>> - * o Altered source versions must be plainly marked as such, and must >> not >>> - * be misrepresented as being the original software. >>> - * o This notice may not be removed or altered from any source >>> - * distribution. >>> - */ >>> - >>> -module std.file; >>> - >>> -private import std.c.stdio; >>> -private import std.c.stdlib; >>> -private import std.path; >>> -private import std.string; >>> - >>> -/* =========================== Win32 ======================= */ >>> - >>> -version (Win32) >>> -{ >>> - >>> -private import std.c.windows.windows; >>> -private import std.utf; >>> -private import std.windows.syserror; >>> - >>> -int useWfuncs = 1; >>> - >>> -static this() >>> -{ >>> - // Win 95, 98, ME do not implement the W functions >>> - useWfuncs = (GetVersion() < 0x80000000); >>> -} >>> - >>> -/*********************************** >>> - */ >>> - >>> -class FileException : Exception >>> -{ >>> - >>> - uint errno; // operating system error code >>> - >>> - this(char[] name) >>> - { >>> - this(name, "file I/O"); >>> - } >>> - >>> - this(char[] name, char[] message) >>> - { >>> - super(name ~ ": " ~ message); >>> - } >>> - >>> - this(char[] name, uint errno) >>> - { >>> - this(name, sysErrorString(errno)); >>> - this.errno = errno; >>> - } >>> -} >>> - >>> -/*********************************** >>> - * Basic File operations. >>> - */ >>> - >>> -/******************************************** >>> - * Read a file. >>> - * Returns: >>> - * array of bytes read >>> - */ >>> - >>> -void[] read(char[] name) >>> -{ >>> - DWORD size; >>> - DWORD numread; >>> - HANDLE h; >>> - byte[] buf; >>> - >>> - if (useWfuncs) >>> - { >>> - wchar* namez = std.utf.toUTF16z(name); >>> - h = CreateFileW(namez,GENERIC_READ,FILE_SHARE_READ,null,OPEN_EXISTING, >>> - FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN,cast(HANDLE)null); >>> - } >>> - else >>> - { >>> - char* namez = toMBSz(name); >>> - h = CreateFileA(namez,GENERIC_READ,FILE_SHARE_READ,null,OPEN_EXISTING, >>> - FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN,cast(HANDLE)null); >>> - } >>> - >>> - if (h == INVALID_HANDLE_VALUE) >>> - goto err1; >>> - >>> - size = GetFileSize(h, null); >>> - if (size == INVALID_FILE_SIZE) >>> - goto err2; >>> - >>> - buf = new byte[size]; >>> - >>> - if (ReadFile(h,buf,size,&numread,null) != 1) >>> - goto err2; >>> - >>> - if (numread != size) >>> - goto err2; >>> - >>> - if (!CloseHandle(h)) >>> - goto err; >>> - >>> - return buf; >>> - >>> -err2: >>> - CloseHandle(h); >>> -err: >>> - delete buf; >>> -err1: >>> - throw new FileException(name, GetLastError()); >>> -} >>> - >>> -/********************************************* >>> - * Write a file. >>> - * Returns: >>> - * 0 success >>> - */ >>> - >>> -void write(char[] name, void[] buffer) >>> -{ >>> - HANDLE h; >>> - DWORD numwritten; >>> - >>> - if (useWfuncs) >>> - { >>> - wchar* namez = std.utf.toUTF16z(name); >>> - h = CreateFileW(namez,GENERIC_WRITE,0,null,CREATE_ALWAYS, >>> - FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN,cast(HANDLE)null); >>> - } >>> - else >>> - { >>> - char* namez = toMBSz(name); >>> - h = CreateFileA(namez,GENERIC_WRITE,0,null,CREATE_ALWAYS, >>> - FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN,cast(HANDLE)null); >>> - } >>> - if (h == INVALID_HANDLE_VALUE) >>> - goto err; >>> - >>> - if (WriteFile(h,buffer,buffer.length,&numwritten,null) != 1) >>> - goto err2; >>> - >>> - if (buffer.length != numwritten) >>> - goto err2; >>> - >>> - if (!CloseHandle(h)) >>> - goto err; >>> - return; >>> - >>> -err2: >>> - CloseHandle(h); >>> -err: >>> - throw new FileException(name, GetLastError()); >>> -} >>> - >>> - >>> -/********************************************* >>> - * Append to a file. >>> - */ >>> - >>> -void append(char[] name, void[] buffer) >>> -{ >>> - HANDLE h; >>> - DWORD numwritten; >>> - >>> - if (useWfuncs) >>> - { >>> - wchar* namez = std.utf.toUTF16z(name); >>> - h = CreateFileW(namez,GENERIC_WRITE,0,null,OPEN_ALWAYS, >>> - FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN,cast(HANDLE)null); >>> - } >>> - else >>> - { >>> - char* namez = toMBSz(name); >>> - h = CreateFileA(namez,GENERIC_WRITE,0,null,OPEN_ALWAYS, >>> - FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN,cast(HANDLE)null); >>> - } >>> - if (h == INVALID_HANDLE_VALUE) >>> - goto err; >>> - >>> - SetFilePointer(h, 0, null, FILE_END); >>> - >>> - if (WriteFile(h,buffer,buffer.length,&numwritten,null) != 1) >>> - goto err2; >>> - >>> - if (buffer.length != numwritten) >>> - goto err2; >>> - >>> - if (!CloseHandle(h)) >>> - goto err; >>> - return; >>> - >>> -err2: >>> - CloseHandle(h); >>> -err: >>> - throw new FileException(name, GetLastError()); >>> -} >>> - >>> - >>> -/*************************************************** >>> - * Rename a file. >>> - */ >>> - >>> -void rename(char[] from, char[] to) >>> -{ >>> - BOOL result; >>> - >>> - if (useWfuncs) >>> - result = MoveFileW(std.utf.toUTF16z(from), std.utf.toUTF16z(to)); >>> - else >>> - result = MoveFileA(toMBSz(from), toMBSz(to)); >>> - if (!result) >>> - throw new FileException(to, GetLastError()); >>> -} >>> - >>> - >>> -/*************************************************** >>> - * Delete a file. >>> - */ >>> - >>> -void remove(char[] name) >>> -{ >>> - BOOL result; >>> - >>> - if (useWfuncs) >>> - result = DeleteFileW(std.utf.toUTF16z(name)); >>> - else >>> - result = DeleteFileA(toMBSz(name)); >>> - if (!result) >>> - throw new FileException(name, GetLastError()); >>> -} >>> - >>> - >>> -/*************************************************** >>> - * Get file size. >>> - */ >>> - >>> -ulong getSize(char[] name) >>> -{ >>> - HANDLE findhndl; >>> - uint resulth; >>> - uint resultl; >>> - >>> - if (useWfuncs) >>> - { >>> - WIN32_FIND_DATAW filefindbuf; >>> - >>> - findhndl = FindFirstFileW(std.utf.toUTF16z(name), &filefindbuf); >>> - resulth = filefindbuf.nFileSizeHigh; >>> - resultl = filefindbuf.nFileSizeLow; >>> - } >>> - else >>> - { >>> - WIN32_FIND_DATA filefindbuf; >>> - >>> - findhndl = FindFirstFileA(toMBSz(name), &filefindbuf); >>> - resulth = filefindbuf.nFileSizeHigh; >>> - resultl = filefindbuf.nFileSizeLow; >>> - } >>> - >>> - if (findhndl == cast(HANDLE)-1) >>> - { >>> - throw new FileException(name, GetLastError()); >>> - } >>> - FindClose(findhndl); >>> - return (cast(ulong)resulth << 32) + resultl; >>> -} >>> - >>> -/*************************************************** >>> - * Does file (or directory) exist? >>> - */ >>> - >>> -int exists(char[] name) >>> -{ >>> - uint result; >>> - >>> - if (useWfuncs) >>> - // >> http://msdn.microsoft.com/library/default.asp?url=/library/en-us/fileio/base/getfileattributes.asp >>> - result = GetFileAttributesW(std.utf.toUTF16z(name)); >>> - else >>> - result = GetFileAttributesA(toMBSz(name)); >>> - >>> - return (result == 0xFFFFFFFF) ? 0 : 1; >>> -} >>> - >>> -/*************************************************** >>> - * Get file attributes. >>> - */ >>> - >>> -uint getAttributes(char[] name) >>> -{ >>> - uint result; >>> - >>> - if (useWfuncs) >>> - result = GetFileAttributesW(std.utf.toUTF16z(name)); >>> - else >>> - result = GetFileAttributesA(toMBSz(name)); >>> - if (result == 0xFFFFFFFF) >>> - { >>> - throw new FileException(name, GetLastError()); >>> - } >>> - return result; >>> -} >>> - >>> -/**************************************************** >>> - * Is name a file? >>> - */ >>> - >>> -int isfile(char[] name) >>> -{ >>> - return (getAttributes(name) & FILE_ATTRIBUTE_DIRECTORY) == 0; >>> -} >>> - >>> -/**************************************************** >>> - * Is name a directory? >>> - */ >>> - >>> -int isdir(char[] name) >>> -{ >>> - return (getAttributes(name) & FILE_ATTRIBUTE_DIRECTORY) != 0; >>> -} >>> - >>> -/**************************************************** >>> - * Change directory. >>> - */ >>> - >>> -void chdir(char[] pathname) >>> -{ BOOL result; >>> - >>> - if (useWfuncs) >>> - result = SetCurrentDirectoryW(std.utf.toUTF16z(pathname)); >>> - else >>> - result = SetCurrentDirectoryA(toMBSz(pathname)); >>> - >>> - if (!result) >>> - { >>> - throw new FileException(pathname, GetLastError()); >>> - } >>> -} >>> - >>> -/**************************************************** >>> - * Make directory. >>> - */ >>> - >>> -void mkdir(char[] pathname) >>> -{ BOOL result; >>> - >>> - if (useWfuncs) >>> - result = CreateDirectoryW(std.utf.toUTF16z(pathname), null); >>> - else >>> - result = CreateDirectoryA(toMBSz(pathname), null); >>> - >>> - if (!result) >>> - { >>> - throw new FileException(pathname, GetLastError()); >>> - } >>> -} >>> - >>> -/**************************************************** >>> - * Remove directory. >>> - */ >>> - >>> -void rmdir(char[] pathname) >>> -{ BOOL result; >>> - >>> - if (useWfuncs) >>> - result = RemoveDirectoryW(std.utf.toUTF16z(pathname)); >>> - else >>> - result = RemoveDirectoryA(toMBSz(pathname)); >>> - >>> - if (!result) >>> - { >>> - throw new FileException(pathname, GetLastError()); >>> - } >>> -} >>> - >>> -/**************************************************** >>> - * Get current directory. >>> - */ >>> - >>> -char[] getcwd() >>> -{ >>> - if (useWfuncs) >>> - { >>> - wchar[] dir; >>> - int len; >>> - wchar c; >>> - >>> - len = GetCurrentDirectoryW(0, &c); >>> - if (!len) >>> - goto Lerr; >>> - dir = new wchar[len]; >>> - len = GetCurrentDirectoryW(len, dir); >>> - if (!len) >>> - goto Lerr; >>> - return std.utf.toUTF8(dir[0 .. len]); // leave off terminating 0 >>> - } >>> - else >>> - { >>> - char[] dir; >>> - int len; >>> - char c; >>> - >>> - len = GetCurrentDirectoryA(0, &c); >>> - if (!len) >>> - goto Lerr; >>> - dir = new char[len]; >>> - len = GetCurrentDirectoryA(len, dir); >>> - if (!len) >>> - goto Lerr; >>> - return dir[0 .. len]; // leave off terminating 0 >>> - } >>> - >>> -Lerr: >>> - throw new FileException("getcwd", GetLastError()); >>> -} >>> - >>> -/*************************************************** >>> - * Return contents of directory. >>> - */ >>> - >>> -char[][] listdir(char[] pathname) >>> -{ >>> - char[][] result; >>> - >>> - bool listing(char[] filename) >>> - { >>> - result ~= filename; >>> - return true; // continue >>> - } >>> - >>> - listdir(pathname, &listing); >>> - return result; >>> -} >>> - >>> -void listdir(char[] pathname, bool delegate(char[] filename) callback) >>> -{ >>> - char[] c; >>> - HANDLE h; >>> - >>> - c = std.path.join(pathname, "*.*"); >>> - if (useWfuncs) >>> - { >>> - WIN32_FIND_DATAW fileinfo; >>> - >>> - h = FindFirstFileW(std.utf.toUTF16z(c), &fileinfo); >>> - if (h != INVALID_HANDLE_VALUE) >>> - { >>> - do >>> - { int clength; >>> - >>> - // Skip "." and ".." >>> - if (std.string.wcscmp(fileinfo.cFileName, ".") == 0 || >>> - std.string.wcscmp(fileinfo.cFileName, "..") == 0) >>> - continue; >>> - >>> - clength = std.string.wcslen(fileinfo.cFileName); >>> - // toUTF8() returns a new buffer >>> - if (!callback(std.utf.toUTF8(fileinfo.cFileName[0 .. clength]))) >>> - break; >>> - } while (FindNextFileW(h,&fileinfo) != FALSE); >>> - FindClose(h); >>> - } >>> - } >>> - else >>> - { >>> - WIN32_FIND_DATA fileinfo; >>> - >>> - h = FindFirstFileA(toMBSz(c), &fileinfo); >>> - if (h != INVALID_HANDLE_VALUE) // should we throw exception if invalid? >>> - { >>> - do >>> - { int clength; >>> - wchar[] wbuf; >>> - int n; >>> - >>> - // Skip "." and ".." >>> - if (std.string.strcmp(fileinfo.cFileName, ".") == 0 || >>> - std.string.strcmp(fileinfo.cFileName, "..") == 0) >>> - continue; >>> - >>> - clength = std.string.strlen(fileinfo.cFileName); >>> - >>> - // Convert cFileName[] to unicode >>> - wbuf.length = >> MultiByteToWideChar(0,0,fileinfo.cFileName,clength,null,0); >>> - n = >> MultiByteToWideChar(0,0,fileinfo.cFileName,clength,cast(wchar*)wbuf,wbuf.len >> gth); >>> - assert(n == wbuf.length); >>> - // toUTF8() returns a new buffer >>> - if (!callback(std.utf.toUTF8(wbuf))) >>> - break; >>> - } while (FindNextFileA(h,&fileinfo) != FALSE); >>> - FindClose(h); >>> - } >>> - } >>> -} >>> - >>> -/****************************************** >>> - * Since Win 9x does not support the "W" API's, first convert >>> - * to wchar, then convert to multibyte using the current code >>> - * page. >>> - * (Thanks to yaneurao for this) >>> - */ >>> - >>> -char* toMBSz(char[] s) >>> -{ >>> - // Only need to do this if any chars have the high bit set >>> - foreach (char c; s) >>> - { >>> - if (c >= 0x80) >>> - { char[] result; >>> - int i; >>> - wchar* ws = std.utf.toUTF16z(s); >>> - result.length = WideCharToMultiByte(0, 0, ws, -1, null, 0, null, >> null); >>> - i = WideCharToMultiByte(0, 0, ws, -1, result, result.length, null, >> null); >>> - assert(i == result.length); >>> - return result; >>> - } >>> - } >>> - return std.string.toStringz(s); >>> -} >>> - >>> - >>> -/*************************************************** >>> - * Copy a file. >>> - */ >>> - >>> -void copy(char[] from, char[] to) >>> -{ >>> - BOOL result; >>> - >>> - if (useWfuncs) >>> - result = CopyFileW(std.utf.toUTF16z(from), std.utf.toUTF16z(to), false); >>> - else >>> - result = CopyFileA(toMBSz(from), toMBSz(to), false); >>> - if (!result) >>> - throw new FileException(to, GetLastError()); >>> -} >>> - >>> - >>> -} >>> - >>> -/* =========================== linux ======================= */ >>> - >>> -version (linux) >>> -{ >>> - >>> -private import std.c.linux.linux; >>> - >>> -extern (C) char* strerror(int); >>> - >>> -/*********************************** >>> - */ >>> - >>> -class FileException : Exception >>> -{ >>> - >>> - uint errno; // operating system error code >>> - >>> - this(char[] name) >>> - { >>> - this(name, "file I/O"); >>> - } >>> - >>> - this(char[] name, char[] message) >>> - { >>> - super(name ~ ": " ~ message); >>> - } >>> - >>> - this(char[] name, uint errno) >>> - { char* s = strerror(errno); >>> - this(name, std.string.toString(s).dup); >>> - this.errno = errno; >>> - } >>> -} >>> - >>> -/******************************************** >>> - * Read a file. >>> - * Returns: >>> - * array of bytes read >>> - */ >>> - >>> -void[] read(char[] name) >>> -{ >>> - uint size; >>> - uint numread; >>> - int fd; >>> - struct_stat statbuf; >>> - byte[] buf; >>> - char *namez; >>> - >>> - namez = toStringz(name); >>> - //printf("file.read('%s')\n",namez); >>> - fd = std.c.linux.linux.open(namez, O_RDONLY); >>> - if (fd == -1) >>> - { >>> - //printf("\topen error, errno = %d\n",getErrno()); >>> - goto err1; >>> - } >>> - >>> - //printf("\tfile opened\n"); >>> - if (std.c.linux.linux.fstat(fd, &statbuf)) >>> - { >>> - //printf("\tfstat error, errno = %d\n",getErrno()); >>> - goto err2; >>> - } >>> - size = statbuf.st_size; >>> - buf = new byte[size]; >>> - >>> - numread = std.c.linux.linux.read(fd, cast(char*)buf, size); >>> - if (numread != size) >>> - { >>> - //printf("\tread error, errno = %d\n",getErrno()); >>> - goto err2; >>> - } >>> - >>> - if (std.c.linux.linux.close(fd) == -1) >>> - { >>> - //printf("\tclose error, errno = %d\n",getErrno()); >>> - goto err; >>> - } >>> - >>> - return buf; >>> - >>> -err2: >>> - std.c.linux.linux.close(fd); >>> -err: >>> - delete buf; >>> - >>> -err1: >>> - throw new FileException(name, getErrno()); >>> -} >>> - >>> -/********************************************* >>> - * Write a file. >>> - * Returns: >>> - * 0 success >>> - */ >>> - >>> -void write(char[] name, void[] buffer) >>> -{ >>> - int fd; >>> - int numwritten; >>> - char *namez; >>> - >>> - namez = toStringz(name); >>> - fd = std.c.linux.linux.open(namez, O_CREAT | O_WRONLY | O_TRUNC, >> 0660); >>> - if (fd == -1) >>> - goto err; >>> - >>> - numwritten = std.c.linux.linux.write(fd, buffer, buffer.length); >>> - if (buffer.length != numwritten) >>> - goto err2; >>> - >>> - if (std.c.linux.linux.close(fd) == -1) >>> - goto err; >>> - >>> - return; >>> - >>> -err2: >>> - std.c.linux.linux.close(fd); >>> -err: >>> - throw new FileException(name, getErrno()); >>> -} >>> - >>> - >>> -/********************************************* >>> - * Append to a file. >>> - */ >>> - >>> -void append(char[] name, void[] buffer) >>> -{ >>> - int fd; >>> - int numwritten; >>> - char *namez; >>> - >>> - namez = toStringz(name); >>> - fd = std.c.linux.linux.open(namez, O_APPEND | O_WRONLY | O_CREAT, >> 0660); >>> - if (fd == -1) >>> - goto err; >>> - >>> - numwritten = std.c.linux.linux.write(fd, buffer, buffer.length); >>> - if (buffer.length != numwritten) >>> - goto err2; >>> - >>> - if (std.c.linux.linux.close(fd) == -1) >>> - goto err; >>> - >>> - return; >>> - >>> -err2: >>> - std.c.linux.linux.close(fd); >>> -err: >>> - throw new FileException(name, getErrno()); >>> -} >>> - >>> - >>> -/*************************************************** >>> - * Rename a file. >>> - */ >>> - >>> -void rename(char[] from, char[] to) >>> -{ >>> - char *fromz = toStringz(from); >>> - char *toz = toStringz(to); >>> - >>> - if (std.c.stdio.rename(fromz, toz) == -1) >>> - throw new FileException(to, getErrno()); >>> -} >>> - >>> - >>> -/*************************************************** >>> - * Delete a file. >>> - */ >>> - >>> -void remove(char[] name) >>> -{ >>> - if (std.c.stdio.remove(toStringz(name)) == -1) >>> - throw new FileException(name, getErrno()); >>> -} >>> - >>> - >>> -/*************************************************** >>> - * Get file size. >>> - */ >>> - >>> -ulong getSize(char[] name) >>> -{ >>> - uint size; >>> - int fd; >>> - struct_stat statbuf; >>> - char *namez; >>> - >>> - namez = toStringz(name); >>> - //printf("file.getSize('%s')\n",namez); >>> - fd = std.c.linux.linux.open(namez, O_RDONLY); >>> - if (fd == -1) >>> - { >>> - //printf("\topen error, errno = %d\n",getErrno()); >>> - goto err1; >>> - } >>> - >>> - //printf("\tfile opened\n"); >>> - if (std.c.linux.linux.fstat(fd, &statbuf)) >>> - { >>> - //printf("\tfstat error, errno = %d\n",getErrno()); >>> - goto err2; >>> - } >>> - size = statbuf.st_size; >>> - >>> - if (std.c.linux.linux.close(fd) == -1) >>> - { >>> - //printf("\tclose error, errno = %d\n",getErrno()); >>> - goto err; >>> - } >>> - >>> - return size; >>> - >>> -err2: >>> - std.c.linux.linux.close(fd); >>> -err: >>> -err1: >>> - throw new FileException(name, getErrno()); >>> -} >>> - >>> - >>> -/*************************************************** >>> - * Get file attributes. >>> - */ >>> - >>> -uint getAttributes(char[] name) >>> -{ >>> - struct_stat statbuf; >>> - char *namez; >>> - >>> - namez = toStringz(name); >>> - if (std.c.linux.linux.stat(namez, &statbuf)) >>> - { >>> - throw new FileException(name, getErrno()); >>> - } >>> - >>> - return statbuf.st_mode; >>> -} >>> - >>> -/**************************************************** >>> - * Does file/directory exist? >>> - */ >>> - >>> -int exists(char[] name) >>> -{ >>> - struct_stat statbuf; >>> - char *namez; >>> - >>> - namez = toStringz(name); >>> - if (std.c.linux.linux.stat(namez, &statbuf)) >>> - { >>> - return 0; >>> - } >>> - >>> - return 1; >>> -} >>> - >>> -/**************************************************** >>> - * Is name a file? >>> - */ >>> - >>> -int isfile(char[] name) >>> -{ >>> - return (getAttributes(name) & S_IFMT) == S_IFREG; // regular file >>> -} >>> - >>> -/**************************************************** >>> - * Is name a directory? >>> - */ >>> - >>> -int isdir(char[] name) >>> -{ >>> - return (getAttributes(name) & S_IFMT) == S_IFDIR; >>> -} >>> - >>> -/**************************************************** >>> - * Change directory. >>> - */ >>> - >>> -void chdir(char[] pathname) >>> -{ >>> - if (std.c.linux.linux.chdir(toStringz(pathname))) >>> - { >>> - throw new FileException(pathname, getErrno()); >>> - } >>> -} >>> - >>> -/**************************************************** >>> - * Make directory. >>> - */ >>> - >>> -void mkdir(char[] pathname) >>> -{ >>> - if (std.c.linux.linux.mkdir(toStringz(pathname), 0777)) >>> - { >>> - throw new FileException(pathname, getErrno()); >>> - } >>> -} >>> - >>> -/**************************************************** >>> - * Remove directory. >>> - */ >>> - >>> -void rmdir(char[] pathname) >>> -{ >>> - if (std.c.linux.linux.rmdir(toStringz(pathname))) >>> - { >>> - throw new FileException(pathname, getErrno()); >>> - } >>> -} >>> - >>> -/**************************************************** >>> - * Get current directory. >>> - */ >>> - >>> -char[] getcwd() >>> -{ char* p; >>> - >>> - p = std.c.linux.linux.getcwd(null, 0); >>> - if (!p) >>> - { >>> - throw new FileException("cannot get cwd", getErrno()); >>> - } >>> - >>> - size_t len = std.string.strlen(p); >>> - char[] buf = new char[len]; >>> - buf[] = p[0 .. len]; >>> - std.c.stdlib.free(p); >>> - return buf; >>> -} >>> - >>> -/*************************************************** >>> - * Return contents of directory. >>> - */ >>> - >>> -char[][] listdir(char[] pathname) >>> -{ >>> - char[][] result; >>> - >>> - bool listing(char[] filename) >>> - { >>> - result ~= filename; >>> - return true; // continue >>> - } >>> - >>> - listdir(pathname, &listing); >>> - return result; >>> -} >>> - >>> -void listdir(char[] pathname, bool delegate(char[] filename) callback) >>> -{ >>> - DIR* h; >>> - dirent* fdata; >>> - >>> - h = opendir(toStringz(pathname)); >>> - if (h) >>> - { >>> - while((fdata = readdir(h)) != null) >>> - { >>> - // Skip "." and ".." >>> - if (!std.string.strcmp(fdata.d_name, ".") || >>> - !std.string.strcmp(fdata.d_name, "..")) >>> - continue; >>> - >>> - int len = std.string.strlen(fdata.d_name); >>> - if (!callback(fdata.d_name[0 .. len].dup)) >>> - break; >>> - } >>> - closedir(h); >>> - } >>> - else >>> - { >>> - throw new FileException(pathname, getErrno()); >>> - } >>> -} >>> - >>> -/*************************************************** >>> - * Copy a file. >>> - */ >>> - >>> -void copy(char[] from, char[] to) >>> -{ >>> - void[] buffer; >>> - >>> - /* If the file is very large, this won't work, but >>> - * it's a good start. >>> - * BUG: it should maintain the file timestamps >>> - */ >>> - buffer = read(from); >>> - write(to, buffer); >>> - delete buffer; >>> -} >>> - >>> - >>> - >>> -} >>> - >>> + >>> +/* >>> + * Copyright (C) 2001-2004 by Digital Mars, www.digitalmars.com >>> + * Written by Walter Bright, Christopher E. Miller, Andre Fornacon >>> + * >>> + * This software is provided 'as-is', without any express or implied >>> + * warranty. In no event will the authors be held liable for any damages >>> + * arising from the use of this software. >>> + * >>> + * Permission is granted to anyone to use this software for any purpose, >>> + * including commercial applications, and to alter it and redistribute >> it >>> + * freely, subject to the following restrictions: >>> + * >>> + * o The origin of this software must not be misrepresented; you must >> not >>> + * claim that you wrote the original software. If you use this >> software >>> + * in a product, an acknowledgment in the product documentation would >> be >>> + * appreciated but is not required. >>> + * o Altered source versions must be plainly marked as such, and must >> not >>> + * be misrepresented as being the original software. >>> + * o This notice may not be removed or altered from any source >>> + * distribution. >>> + */ >>> + >>> +module std.file; >>> + >>> +private import std.c.stdio; >>> +private import std.c.stdlib; >>> +private import std.path; >>> +private import std.string; >>> + >>> +/* =========================== Win32 ======================= */ >>> + >>> +version (Win32) >>> +{ >>> + >>> +private import std.c.windows.windows; >>> +private import std.utf; >>> +private import std.windows.syserror; >>> + >>> +int useWfuncs = 1; >>> + >>> +static this() >>> +{ >>> + // Win 95, 98, ME do not implement the W functions >>> + useWfuncs = (GetVersion() < 0x80000000); >>> +} >>> + >>> +/*********************************** >>> + */ >>> + >>> +class FileException : Exception >>> +{ >>> + >>> + uint errno; // operating system error code >>> + >>> + this(char[] name) >>> + { >>> + this(name, "file I/O"); >>> + } >>> + >>> + this(char[] name, char[] message) >>> + { >>> + super(name ~ ": " ~ message); >>> + } >>> + >>> + this(char[] name, uint errno) >>> + { >>> + this(name, sysErrorString(errno)); >>> + this.errno = errno; >>> + } >>> +} >>> + >>> +/*********************************** >>> + * Basic File operations. >>> + */ >>> + >>> +/******************************************** >>> + * Read a file. >>> + * Returns: >>> + * array of bytes read >>> + */ >>> + >>> +void[] read(char[] name) >>> +{ >>> + DWORD size; >>> + DWORD numread; >>> + HANDLE h; >>> + byte[] buf; >>> + >>> + if (useWfuncs) >>> + { >>> + wchar* namez = std.utf.toUTF16z(name); >>> + h = CreateFileW(namez,GENERIC_READ,FILE_SHARE_READ,null,OPEN_EXISTING, >>> + FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN,cast(HANDLE)null); >>> + } >>> + else >>> + { >>> + char* namez = toMBSz(name); >>> + h = CreateFileA(namez,GENERIC_READ,FILE_SHARE_READ,null,OPEN_EXISTING, >>> + FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN,cast(HANDLE)null); >>> + } >>> + >>> + if (h == INVALID_HANDLE_VALUE) >>> + goto err1; >>> + >>> + size = GetFileSize(h, null); >>> + if (size == INVALID_FILE_SIZE) >>> + goto err2; >>> + >>> + buf = new byte[size]; >>> + >>> + if (ReadFile(h,buf,size,&numread,null) != 1) >>> + goto err2; >>> + >>> + if (numread != size) >>> + goto err2; >>> + >>> + if (!CloseHandle(h)) >>> + goto err; >>> + >>> + return buf; >>> + >>> +err2: >>> + CloseHandle(h); >>> +err: >>> + delete buf; >>> +err1: >>> + throw new FileException(name, GetLastError()); >>> +} >>> + >>> +/********************************************* >>> + * Write a file. >>> + * Returns: >>> + * 0 success >>> + */ >>> + >>> +void write(char[] name, void[] buffer) >>> +{ >>> + HANDLE h; >>> + DWORD numwritten; >>> + >>> + if (useWfuncs) >>> + { >>> + wchar* namez = std.utf.toUTF16z(name); >>> + h = CreateFileW(namez,GENERIC_WRITE,0,null,CREATE_ALWAYS, >>> + FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN,cast(HANDLE)null); >>> + } >>> + else >>> + { >>> + char* namez = toMBSz(name); >>> + h = CreateFileA(namez,GENERIC_WRITE,0,null,CREATE_ALWAYS, >>> + FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN,cast(HANDLE)null); >>> + } >>> + if (h == INVALID_HANDLE_VALUE) >>> + goto err; >>> + >>> + if (WriteFile(h,buffer,buffer.length,&numwritten,null) != 1) >>> + goto err2; >>> + >>> + if (buffer.length != numwritten) >>> + goto err2; >>> + >>> + if (!CloseHandle(h)) >>> + goto err; >>> + return; >>> + >>> +err2: >>> + CloseHandle(h); >>> +err: >>> + throw new FileException(name, GetLastError()); >>> +} >>> + >>> + >>> +/********************************************* >>> + * Append to a file. >>> + */ >>> + >>> +void append(char[] name, void[] buffer) >>> +{ >>> + HANDLE h; >>> + DWORD numwritten; >>> + >>> + if (useWfuncs) >>> + { >>> + wchar* namez = std.utf.toUTF16z(name); >>> + h = CreateFileW(namez,GENERIC_WRITE,0,null,OPEN_ALWAYS, >>> + FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN,cast(HANDLE)null); >>> + } >>> + else >>> + { >>> + char* namez = toMBSz(name); >>> + h = CreateFileA(namez,GENERIC_WRITE,0,null,OPEN_ALWAYS, >>> + FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN,cast(HANDLE)null); >>> + } >>> + if (h == INVALID_HANDLE_VALUE) >>> + goto err; >>> + >>> + SetFilePointer(h, 0, null, FILE_END); >>> + >>> + if (WriteFile(h,buffer,buffer.length,&numwritten,null) != 1) >>> + goto err2; >>> + >>> + if (buffer.length != numwritten) >>> + goto err2; >>> + >>> + if (!CloseHandle(h)) >>> + goto err; >>> + return; >>> + >>> +err2: >>> + CloseHandle(h); >>> +err: >>> + throw new FileException(name, GetLastError()); >>> +} >>> + >>> + >>> +/*************************************************** >>> + * Rename a file. >>> + */ >>> + >>> +void rename(char[] from, char[] to) >>> +{ >>> + BOOL result; >>> + >>> + if (useWfuncs) >>> + result = MoveFileW(std.utf.toUTF16z(from), std.utf.toUTF16z(to)); >>> + else >>> + result = MoveFileA(toMBSz(from), toMBSz(to)); >>> + if (!result) >>> + throw new FileException(to, GetLastError()); >>> +} >>> + >>> + >>> +/*************************************************** >>> + * Delete a file. >>> + */ >>> + >>> +void remove(char[] name) >>> +{ >>> + BOOL result; >>> + >>> + if (useWfuncs) >>> + result = DeleteFileW(std.utf.toUTF16z(name)); >>> + else >>> + result = DeleteFileA(toMBSz(name)); >>> + if (!result) >>> + throw new FileException(name, GetLastError()); >>> +} >>> + >>> + >>> +/*************************************************** >>> + * Get file size. >>> + */ >>> + >>> +ulong getSize(char[] name) >>> +{ >>> + HANDLE findhndl; >>> + uint resulth; >>> + uint resultl; >>> + >>> + if (useWfuncs) >>> + { >>> + WIN32_FIND_DATAW filefindbuf; >>> + >>> + findhndl = FindFirstFileW(std.utf.toUTF16z(name), &filefindbuf); >>> + resulth = filefindbuf.nFileSizeHigh; >>> + resultl = filefindbuf.nFileSizeLow; >>> + } >>> + else >>> + { >>> + WIN32_FIND_DATA filefindbuf; >>> + >>> + findhndl = FindFirstFileA(toMBSz(name), &filefindbuf); >>> + resulth = filefindbuf.nFileSizeHigh; >>> + resultl = filefindbuf.nFileSizeLow; >>> + } >>> + >>> + if (findhndl == cast(HANDLE)-1) >>> + { >>> + throw new FileException(name, GetLastError()); >>> + } >>> + FindClose(findhndl); >>> + return (cast(ulong)resulth << 32) + resultl; >>> +} >>> + >>> +/*************************************************** >>> + * Does file (or directory) exist? >>> + */ >>> + >>> +int exists(char[] name) >>> +{ >>> + uint result; >>> + >>> + if (useWfuncs) >>> + // >> http://msdn.microsoft.com/library/default.asp?url=/library/en-us/fileio/base/getfileattributes.asp >>> + result = GetFileAttributesW(std.utf.toUTF16z(name)); >>> + else >>> + result = GetFileAttributesA(toMBSz(name)); >>> + >>> + return (result == 0xFFFFFFFF) ? 0 : 1; >>> +} >>> + >>> +/*************************************************** >>> + * Get file attributes. >>> + */ >>> + >>> +uint getAttributes(char[] name) >>> +{ >>> + uint result; >>> + >>> + if (useWfuncs) >>> + result = GetFileAttributesW(std.utf.toUTF16z(name)); >>> + else >>> + result = GetFileAttributesA(toMBSz(name)); >>> + if (result == 0xFFFFFFFF) >>> + { >>> + throw new FileException(name, GetLastError()); >>> + } >>> + return result; >>> +} >>> + >>> +/**************************************************** >>> + * Is name a file? >>> + */ >>> + >>> +int isfile(char[] name) >>> +{ >>> + return (getAttributes(name) & FILE_ATTRIBUTE_DIRECTORY) == 0; >>> +} >>> + >>> +/**************************************************** >>> + * Is name a directory? >>> + */ >>> + >>> +int isdir(char[] name) >>> +{ >>> + return (getAttributes(name) & FILE_ATTRIBUTE_DIRECTORY) != 0; >>> +} >>> + >>> +/**************************************************** >>> + * Change directory. >>> + */ >>> + >>> +void chdir(char[] pathname) >>> +{ BOOL result; >>> + >>> + if (useWfuncs) >>> + result = SetCurrentDirectoryW(std.utf.toUTF16z(pathname)); >>> + else >>> + result = SetCurrentDirectoryA(toMBSz(pathname)); >>> + >>> + if (!result) >>> + { >>> + throw new FileException(pathname, GetLastError()); >>> + } >>> +} >>> + >>> +/**************************************************** >>> + * Make directory. >>> + */ >>> + >>> +void mkdir(char[] pathname) >>> +{ BOOL result; >>> + >>> + if (useWfuncs) >>> + result = CreateDirectoryW(std.utf.toUTF16z(pathname), null); >>> + else >>> + result = CreateDirectoryA(toMBSz(pathname), null); >>> + >>> + if (!result) >>> + { >>> + throw new FileException(pathname, GetLastError()); >>> + } >>> +} >>> + >>> +/**************************************************** >>> + * Remove directory. >>> + */ >>> + >>> +void rmdir(char[] pathname) >>> +{ BOOL result; >>> + >>> + if (useWfuncs) >>> + result = RemoveDirectoryW(std.utf.toUTF16z(pathname)); >>> + else >>> + result = RemoveDirectoryA(toMBSz(pathname)); >>> + >>> + if (!result) >>> + { >>> + throw new FileException(pathname, GetLastError()); >>> + } >>> +} >>> + >>> +/**************************************************** >>> + * Get current directory. >>> + */ >>> + >>> +char[] getcwd() >>> +{ >>> + if (useWfuncs) >>> + { >>> + wchar[] dir; >>> + int len; >>> + wchar c; >>> + >>> + len = GetCurrentDirectoryW(0, &c); >>> + if (!len) >>> + goto Lerr; >>> + dir = new wchar[len]; >>> + len = GetCurrentDirectoryW(len, dir); >>> + if (!len) >>> + goto Lerr; >>> + return std.utf.toUTF8(dir[0 .. len]); // leave off terminating 0 >>> + } >>> + else >>> + { >>> + char[] dir; >>> + int len; >>> + char c; >>> + >>> + len = GetCurrentDirectoryA(0, &c); >>> + if (!len) >>> + goto Lerr; >>> + dir = new char[len]; >>> + len = GetCurrentDirectoryA(len, dir); >>> + if (!len) >>> + goto Lerr; >>> + return dir[0 .. len]; // leave off terminating 0 >>> + } >>> + >>> +Lerr: >>> + throw new FileException("getcwd", GetLastError()); >>> +} >>> + >>> +/*************************************************** >>> + * Return contents of directory. >>> + */ >>> + >>> +char[][] listdir(char[] pathname) >>> +{ >>> + char[][] result; >>> + >>> + bool listing(char[] filename) >>> + { >>> + result ~= filename; >>> + return true; // continue >>> + } >>> + >>> + listdir(pathname, &listing); >>> + return result; >>> +} >>> + >>> +void listdir(char[] pathname, bool delegate(char[] filename) callback) >>> +{ >>> + char[] c; >>> + HANDLE h; >>> + >>> + c = std.path.join(pathname, "*.*"); >>> + if (useWfuncs) >>> + { >>> + WIN32_FIND_DATAW fileinfo; >>> + >>> + h = FindFirstFileW(std.utf.toUTF16z(c), &fileinfo); >>> + if (h != INVALID_HANDLE_VALUE) >>> + { >>> + do >>> + { int clength; >>> + >>> + // Skip "." and ".." >>> + if (std.string.wcscmp(fileinfo.cFileName, ".") == 0 || >>> + std.string.wcscmp(fileinfo.cFileName, "..") == 0) >>> + continue; >>> + >>> + clength = std.string.wcslen(fileinfo.cFileName); >>> + // toUTF8() returns a new buffer >>> + if (!callback(std.utf.toUTF8(fileinfo.cFileName[0 .. clength]))) >>> + break; >>> + } while (FindNextFileW(h,&fileinfo) != FALSE); >>> + FindClose(h); >>> + } >>> + } >>> + else >>> + { >>> + WIN32_FIND_DATA fileinfo; >>> + >>> + h = FindFirstFileA(toMBSz(c), &fileinfo); >>> + if (h != INVALID_HANDLE_VALUE) // should we throw exception if invalid? >>> + { >>> + do >>> + { int clength; >>> + wchar[] wbuf; >>> + int n; >>> + >>> + // Skip "." and ".." >>> + if (std.string.strcmp(fileinfo.cFileName, ".") == 0 || >>> + std.string.strcmp(fileinfo.cFileName, "..") == 0) >>> + continue; >>> + >>> + clength = std.string.strlen(fileinfo.cFileName); >>> + >>> + // Convert cFileName[] to unicode >>> + wbuf.length = >> MultiByteToWideChar(0,0,fileinfo.cFileName,clength,null,0); >>> + n = >> MultiByteToWideChar(0,0,fileinfo.cFileName,clength,cast(wchar*)wbuf,wbuf.len >> gth); >>> + assert(n == wbuf.length); >>> + // toUTF8() returns a new buffer >>> + if (!callback(std.utf.toUTF8(wbuf))) >>> + break; >>> + } while (FindNextFileA(h,&fileinfo) != FALSE); >>> + FindClose(h); >>> + } >>> + } >>> +} >>> + >>> +/****************************************** >>> + * Since Win 9x does not support the "W" API's, first convert >>> + * to wchar, then convert to multibyte using the current code >>> + * page. >>> + * (Thanks to yaneurao for this) >>> + */ >>> + >>> +char* toMBSz(char[] s) >>> +{ >>> + // Only need to do this if any chars have the high bit set >>> + foreach (char c; s) >>> + { >>> + if (c >= 0x80) >>> + { char[] result; >>> + int i; >>> + wchar* ws = std.utf.toUTF16z(s); >>> + result.length = WideCharToMultiByte(0, 0, ws, -1, null, 0, null, >> null); >>> + i = WideCharToMultiByte(0, 0, ws, -1, result, result.length, null, >> null); >>> + assert(i == result.length); >>> + return result; >>> + } >>> + } >>> + return std.string.toStringz(s); >>> +} >>> + >>> + >>> +/*************************************************** >>> + * Copy a file. >>> + */ >>> + >>> +void copy(char[] from, char[] to) >>> +{ >>> + BOOL result; >>> + >>> + if (useWfuncs) >>> + result = CopyFileW(std.utf.toUTF16z(from), std.utf.toUTF16z(to), false); >>> + else >>> + result = CopyFileA(toMBSz(from), toMBSz(to), false); >>> + if (!result) >>> + throw new FileException(to, GetLastError()); >>> +} >>> + >>> + >>> +} >>> + >>> +/* =========================== linux ======================= */ >>> + >>> +version (linux) >>> +{ >>> + >>> +private import std.c.linux.linux; >>> + >>> +extern (C) char* strerror(int); >>> +extern(C) int access(char *, int); >>> +/*********************************** >>> + */ >>> + >>> +class FileException : Exception >>> +{ >>> + >>> + uint errno; // operating system error code >>> + >>> + this(char[] name) >>> + { >>> + this(name, "file I/O"); >>> + } >>> + >>> + this(char[] name, char[] message) >>> + { >>> + super(name ~ ": " ~ message); >>> + } >>> + >>> + this(char[] name, uint errno) >>> + { char* s = strerror(errno); >>> + this(name, std.string.toString(s).dup); >>> + this.errno = errno; >>> + } >>> +} >>> + >>> +/******************************************** >>> + * Read a file. >>> + * Returns: >>> + * array of bytes read >>> + */ >>> + >>> +void[] read(char[] name) >>> +{ >>> + uint size; >>> + uint numread; >>> + int fd; >>> + struct_stat statbuf; >>> + byte[] buf; >>> + char *namez; >>> + >>> + namez = toStringz(name); >>> + //printf("file.read('%s')\n",namez); >>> + fd = std.c.linux.linux.open(namez, O_RDONLY); >>> + if (fd == -1) >>> + { >>> + //printf("\topen error, errno = %d\n",getErrno()); >>> + goto err1; >>> + } >>> + >>> + //printf("\tfile opened\n"); >>> + if (std.c.linux.linux.fstat(fd, &statbuf)) >>> + { >>> + //printf("\tfstat error, errno = %d\n",getErrno()); >>> + goto err2; >>> + } >>> + size = statbuf.st_size; >>> + buf = new byte[size]; >>> + >>> + numread = std.c.linux.linux.read(fd, cast(char*)buf, size); >>> + if (numread != size) >>> + { >>> + //printf("\tread error, errno = %d\n",getErrno()); >>> + goto err2; >>> + } >>> + >>> + if (std.c.linux.linux.close(fd) == -1) >>> + { >>> + //printf("\tclose error, errno = %d\n",getErrno()); >>> + goto err; >>> + } >>> + >>> + return buf; >>> + >>> +err2: >>> + std.c.linux.linux.close(fd); >>> +err: >>> + delete buf; >>> + >>> +err1: >>> + throw new FileException(name, getErrno()); >>> +} >>> + >>> +/********************************************* >>> + * Write a file. >>> + * Returns: >>> + * 0 success >>> + */ >>> + >>> +void write(char[] name, void[] buffer) >>> +{ >>> + int fd; >>> + int numwritten; >>> + char *namez; >>> + >>> + namez = toStringz(name); >>> + fd = std.c.linux.linux.open(namez, O_CREAT | O_WRONLY | O_TRUNC, >> 0660); >>> + if (fd == -1) >>> + goto err; >>> + >>> + numwritten = std.c.linux.linux.write(fd, buffer, buffer.length); >>> + if (buffer.length != numwritten) >>> + goto err2; >>> + >>> + if (std.c.linux.linux.close(fd) == -1) >>> + goto err; >>> + >>> + return; >>> + >>> +err2: >>> + std.c.linux.linux.close(fd); >>> +err: >>> + throw new FileException(name, getErrno()); >>> +} >>> + >>> + >>> +/********************************************* >>> + * Append to a file. >>> + */ >>> + >>> +void append(char[] name, void[] buffer) >>> +{ >>> + int fd; >>> + int numwritten; >>> + char *namez; >>> + >>> + namez = toStringz(name); >>> + fd = std.c.linux.linux.open(namez, O_APPEND | O_WRONLY | O_CREAT, >> 0660); >>> + if (fd == -1) >>> + goto err; >>> + >>> + numwritten = std.c.linux.linux.write(fd, buffer, buffer.length); >>> + if (buffer.length != numwritten) >>> + goto err2; >>> + >>> + if (std.c.linux.linux.close(fd) == -1) >>> + goto err; >>> + >>> + return; >>> + >>> +err2: >>> + std.c.linux.linux.close(fd); >>> +err: >>> + throw new FileException(name, getErrno()); >>> +} >>> + >>> + >>> +/*************************************************** >>> + * Rename a file. >>> + */ >>> + >>> +void rename(char[] from, char[] to) >>> +{ >>> + char *fromz = toStringz(from); >>> + char *toz = toStringz(to); >>> + >>> + if (std.c.stdio.rename(fromz, toz) == -1) >>> + throw new FileException(to, getErrno()); >>> +} >>> + >>> + >>> +/*************************************************** >>> + * Delete a file. >>> + */ >>> + >>> +void remove(char[] name) >>> +{ >>> + if (std.c.stdio.remove(toStringz(name)) == -1) >>> + throw new FileException(name, getErrno()); >>> +} >>> + >>> + >>> +/*************************************************** >>> + * Get file size. >>> + */ >>> + >>> +ulong getSize(char[] name) >>> +{ >>> + uint size; >>> + int fd; >>> + struct_stat statbuf; >>> + char *namez; >>> + >>> + namez = toStringz(name); >>> + //printf("file.getSize('%s')\n",namez); >>> + fd = std.c.linux.linux.open(namez, O_RDONLY); >>> + if (fd == -1) >>> + { >>> + //printf("\topen error, errno = %d\n",getErrno()); >>> + goto err1; >>> + } >>> + >>> + //printf("\tfile opened\n"); >>> + if (std.c.linux.linux.fstat(fd, &statbuf)) >>> + { >>> + //printf("\tfstat error, errno = %d\n",getErrno()); >>> + goto err2; >>> + } >>> + size = statbuf.st_size; >>> + >>> + if (std.c.linux.linux.close(fd) == -1) >>> + { >>> + //printf("\tclose error, errno = %d\n",getErrno()); >>> + goto err; >>> + } >>> + >>> + return size; >>> + >>> +err2: >>> + std.c.linux.linux.close(fd); >>> +err: >>> +err1: >>> + throw new FileException(name, getErrno()); >>> +} >>> + >>> + >>> +/*************************************************** >>> + * Get file attributes. >>> + */ >>> + >>> +uint getAttributes(char[] name) >>> +{ >>> + struct_stat statbuf; >>> + char *namez; >>> + >>> + namez = toStringz(name); >>> + if (std.c.linux.linux.stat(namez, &statbuf)) >>> + { >>> + throw new FileException(name, getErrno()); >>> + } >>> + >>> + return statbuf.st_mode; >>> +} >>> + >>> +/**************************************************** >>> + * Does file/directory exist? >>> + */ >>> + >>> +int exists(char[] name) >>> +{ >>> + if(access(toStringz(name),0)) >>> + return 0; >>> + else >>> + return 1; >>> +} >>> + >>> +/**************************************************** >>> + * Is name a file? >>> + */ >>> + >>> +int isfile(char[] name) >>> +{ >>> + return (getAttributes(name) & S_IFMT) == S_IFREG; // regular file >>> +} >>> + >>> +/**************************************************** >>> + * Is name a directory? >>> + */ >>> + >>> +int isdir(char[] name) >>> +{ >>> + return (getAttributes(name) & S_IFMT) == S_IFDIR; >>> +} >>> + >>> +/**************************************************** >>> + * Change directory. >>> + */ >>> + >>> +void chdir(char[] pathname) >>> +{ >>> + if (std.c.linux.linux.chdir(toStringz(pathname))) >>> + { >>> + throw new FileException(pathname, getErrno()); >>> + } >>> +} >>> + >>> +/**************************************************** >>> + * Make directory. >>> + */ >>> + >>> +void mkdir(char[] pathname) >>> +{ >>> + if (std.c.linux.linux.mkdir(toStringz(pathname), 0777)) >>> + { >>> + throw new FileException(pathname, getErrno()); >>> + } >>> +} >>> + >>> +/**************************************************** >>> + * Remove directory. >>> + */ >>> + >>> +void rmdir(char[] pathname) >>> +{ >>> + if (std.c.linux.linux.rmdir(toStringz(pathname))) >>> + { >>> + throw new FileException(pathname, getErrno()); >>> + } >>> +} >>> + >>> +/**************************************************** >>> + * Get current directory. >>> + */ >>> + >>> +char[] getcwd() >>> +{ char* p; >>> + >>> + p = std.c.linux.linux.getcwd(null, 0); >>> + if (!p) >>> + { >>> + throw new FileException("cannot get cwd", getErrno()); >>> + } >>> + >>> + size_t len = std.string.strlen(p); >>> + char[] buf = new char[len]; >>> + buf[] = p[0 .. len]; >>> + std.c.stdlib.free(p); >>> + return buf; >>> +} >>> + >>> +/*************************************************** >>> + * Return contents of directory. >>> + */ >>> + >>> +char[][] listdir(char[] pathname) >>> +{ >>> + char[][] result; >>> + >>> + bool listing(char[] filename) >>> + { >>> + result ~= filename; >>> + return true; // continue >>> + } >>> + >>> + listdir(pathname, &listing); >>> + return result; >>> +} >>> + >>> +void listdir(char[] pathname, bool delegate(char[] filename) callback) >>> +{ >>> + DIR* h; >>> + dirent* fdata; >>> + >>> + h = opendir(toStringz(pathname)); >>> + if (h) >>> + { >>> + while((fdata = readdir(h)) != null) >>> + { >>> + // Skip "." and ".." >>> + if (!std.string.strcmp(fdata.d_name, ".") || >>> + !std.string.strcmp(fdata.d_name, "..")) >>> + continue; >>> + >>> + int len = std.string.strlen(fdata.d_name); >>> + if (!callback(fdata.d_name[0 .. len].dup)) >>> + break; >>> + } >>> + closedir(h); >>> + } >>> + else >>> + { >>> + throw new FileException(pathname, getErrno()); >>> + } >>> +} >>> + >>> +/*************************************************** >>> + * Copy a file. >>> + */ >>> + >>> +void copy(char[] from, char[] to) >>> +{ >>> + void[] buffer; >>> + >>> + /* If the file is very large, this won't work, but >>> + * it's a good start. >>> + * BUG: it should maintain the file timestamps >>> + */ >>> + buffer = read(from); >>> + write(to, buffer); >>> + delete buffer; >>> +} >>> + >>> + >>> + >>> +} >>> + >>> >> >> >> Regards, James Dunne |
July 07, 2005 Re: std.file.exists() | ||||
---|---|---|---|---|
| ||||
Posted in reply to James Dunne | James Dunne wrote:
> Congratulations, you've defeated the purpose of the patch/diff utility :).
Seriously, do make sure that the line endings match on both files...
Most of the DMD files come with DOS line endings (i.e. \r\n)
so they need to be converted first - before doing diff/patch.
Maybe this is a good time to renew the request for a .tar.gz ? ;-)
--anders
|
Copyright © 1999-2021 by the D Language Foundation