Jump to page: 1 2
Thread overview
std.stream.File
Jul 21, 2004
Arcane Jill
Jul 21, 2004
Stewart Gordon
Jul 21, 2004
Arcane Jill
Jul 21, 2004
Burton Radons
Jul 22, 2004
Regan Heath
Jul 22, 2004
Derek Parnell
Jul 22, 2004
Regan Heath
Jul 22, 2004
Stewart Gordon
Jul 22, 2004
Regan Heath
Jul 22, 2004
Stewart Gordon
Jul 22, 2004
Regan Heath
Jul 23, 2004
Stewart Gordon
Jul 24, 2004
Regan Heath
Jul 26, 2004
Stewart Gordon
Jul 26, 2004
Regan Heath
Jul 22, 2004
Derek
Jul 21, 2004
Ben Hinkle
Jul 21, 2004
Andrew Edwards
Jul 21, 2004
Andrew Edwards
Jul 21, 2004
Andrew Edwards
July 21, 2004
On the Windows platform:

#    import std.stream;
#
#    void main()
#    {
#        File f = new File("foo"); // where foo does not exist
#    }

creates the file "foo", does not throw any kind of exception, and then carries on executing as though everything were hunky dory.

This is currently a very good reason not to use std.stream.File

Arcane Jill


July 21, 2004
Arcane Jill wrote:
> On the Windows platform:
> 
> #    import std.stream;
> #
> #    void main()
> #    {
> #        File f = new File("foo"); // where foo does not exist
> #    }
> 
> creates the file "foo", does not throw any kind of exception, and then carries
> on executing as though everything were hunky dory.

In accordance with the documentation.

----------
this()
this(char[] filename)
this(char[] filename, FileMode mode)
    Create the stream with no open file, an open file in read and write mode, or an open file with explicit file mode. mode, if given, is a combination of FileMode.In (indicating a file that can be read) and FileMode.Out (indicating a file that can be written). If the file does not exist, it is created.
----------

After all, your code does say "new File"!  Even though that isn't what it really means!

> This is currently a very good reason not to use std.stream.File

Yes, the whole File class could be more clearly defined.  At the moment, it seems you're meant to manually call std.file.exists first.  Chances are this isn't part of the normal program logic....

My idea would probably be something like

enum FILE_MODE {
	IN                    = 0b000001,
	OUT                   = 0b000010,
	CREATE_IF_NONEXISTENT = 0b000100,
	NEW_FILE              = 0b001100,    /*!< create new file,
	                                      prevent overwrite */
	OVERWRITE             = 0b001000,    /*!< create new file,
	                                      overwrite if necessary */
	APPEND                = 0b010000,    //!< start pointer at end
	EXCLUSIVE             = 0b100000     /*!< lock for exclusive
 	                                      access, if that follows */
}

Obviously some combinations don't make sense....

Stewart.

-- 
My e-mail is valid but not my primary mailbox, aside from its being the unfortunate victim of intensive mail-bombing at the moment.  Please keep replies on the 'group where everyone may benefit.
July 21, 2004
To get the behavior Jill describes on Windows, change the two occurrences of
OPEN_ALWAYS in stream.d to
 (mode&FileMode.Out)?OPEN_ALWAYS:OPEN_EXISTING
and recompile phobos. I don't know about Linux.

"Arcane Jill" <Arcane_member@pathlink.com> wrote in message news:cdlm9m$2kle$1@digitaldaemon.com...
> On the Windows platform:
>
> #    import std.stream;
> #
> #    void main()
> #    {
> #        File f = new File("foo"); // where foo does not exist
> #    }
>
> creates the file "foo", does not throw any kind of exception, and then
carries
> on executing as though everything were hunky dory.
>
> This is currently a very good reason not to use std.stream.File
>
> Arcane Jill
>
>


July 21, 2004
In article <cdlpci$2ma4$1@digitaldaemon.com>, Stewart Gordon says...
>
>Arcane Jill wrote:
>> On the Windows platform:
>> 
>> #    import std.stream;
>> #
>> #    void main()
>> #    {
>> #        File f = new File("foo"); // where foo does not exist
>> #    }

Whoops. Should have said:

import std.stream;

#    void main()
#    {
#        File f = new File("foo", FileMode.In); // where foo does not exist
#    }

Please observe the FileMode.In parameter

>> creates the file "foo", does not throw any kind of exception, and then carries on executing as though everything were hunky dory.

Is /this/ in accordance with the documentation?

Arcane Jill


July 21, 2004
Arcane Jill wrote:
> In article <cdlpci$2ma4$1@digitaldaemon.com>, Stewart Gordon says...
> 
>>Arcane Jill wrote:
>>
>>>On the Windows platform:
>>>
>>>#    import std.stream;
>>>#
>>>#    void main()
>>>#    {
>>>#        File f = new File("foo"); // where foo does not exist
>>>#    }
> 
> 
> Whoops. Should have said:
> 
> import std.stream;
> 
> #    void main()
> #    {
> #        File f = new File("foo", FileMode.In); // where foo does not exist
> #    }
> 
> Please observe the FileMode.In parameter
> 
> 
>>>creates the file "foo", does not throw any kind of exception, and then carries
>>>on executing as though everything were hunky dory.
> 
> 
> Is /this/ in accordance with the documentation?

Yes.  "If the file does not exist, it is created."  There's nothing about examining the mode parameter for how to behave; it only modifies what operations can be performed on the stream.

I do think the API's incorrectly designed, but it's not a bug.
July 21, 2004
Arcane Jill wrote:
> On the Windows platform:
> 
> #    import std.stream;
> #
> #    void main()
> #    {
> #        File f = new File("foo"); // where foo does not exist
> #    }
> 
> creates the file "foo", does not throw any kind of exception, and then carries
> on executing as though everything were hunky dory.
> 
> This is currently a very good reason not to use std.stream.File
> 
> Arcane Jill
> 
> 
You know! I remember when this feature operated the way you now expect it to. Others requested that it be changed and it was. Just goes to show: you can't please everyone. No matter how hard you try!

Andrew
July 21, 2004
Andrew Edwards wrote:

> Arcane Jill wrote:
> 
>> On the Windows platform:
>>
>> #    import std.stream;
>> #
>> #    void main()
>> #    {
>> #        File f = new File("foo"); // where foo does not exist
>> #    }
>>
>> creates the file "foo", does not throw any kind of exception, and then carries
>> on executing as though everything were hunky dory.
>>
>> This is currently a very good reason not to use std.stream.File
>>
>> Arcane Jill
>>
>>
> You know! I remember when this feature operated the way you now expect it to. Others requested that it be changed and it was. Just goes to show: you can't please everyone. No matter how hard you try!
> 
> Andrew

As a matter of fact, here's the post that prompted the change:

  http://www.digitalmars.com/d/archives/17539.html
July 21, 2004
Andrew Edwards wrote:
> 
> As a matter of fact, here's the post that prompted the change:
> 
>   http://www.digitalmars.com/d/archives/17539.html

Teaches me for opening my mouth too fast. He was talking about "FileMode.Out".

I'll shut up now!
July 22, 2004
On Wed, 21 Jul 2004 14:00:01 +0100, Stewart Gordon <smjg_1998@yahoo.com> wrote:
> Arcane Jill wrote:
>> On the Windows platform:
>>
>> #    import std.stream;
>> #
>> #    void main()
>> #    {
>> #        File f = new File("foo"); // where foo does not exist
>> #    }
>>
>> creates the file "foo", does not throw any kind of exception, and then carries
>> on executing as though everything were hunky dory.
>
> In accordance with the documentation.
>
> ----------
> this()
> this(char[] filename)
> this(char[] filename, FileMode mode)
>      Create the stream with no open file, an open file in read and write mode, or an open file with explicit file mode. mode, if given, is a combination of FileMode.In (indicating a file that can be read) and FileMode.Out (indicating a file that can be written). If the file does not exist, it is created.
> ----------
>
> After all, your code does say "new File"!  Even though that isn't what it really means!
>
>> This is currently a very good reason not to use std.stream.File
>
> Yes, the whole File class could be more clearly defined.  At the moment, it seems you're meant to manually call std.file.exists first.  Chances are this isn't part of the normal program logic....
>
> My idea would probably be something like
>
> enum FILE_MODE {
> 	IN                    = 0b000001,
> 	OUT                   = 0b000010,
> 	CREATE_IF_NONEXISTENT = 0b000100,
> 	NEW_FILE              = 0b001100,    /*!< create new file,
> 	                                      prevent overwrite */
> 	OVERWRITE             = 0b001000,    /*!< create new file,
> 	                                      overwrite if necessary */
> 	APPEND                = 0b010000,    //!< start pointer at end
> 	EXCLUSIVE             = 0b100000     /*!< lock for exclusive
>   	                                      access, if that follows */
> }
>
> Obviously some combinations don't make sense....


I suggested these a little while back:

READ
WRITE
CREATE
APPEND
NEW

allowing:

"r"  - READ        - read, fails if file does not exist.
"w"  - CREATE      - write, overwrite existing.
"a"  - APPEND      - write, create if not exist.
"r+" - READ|WRITE  - read, write, fails if file does not exist.
"w+" - READ|CREATE - read, write, overwrite existing.
"a+" - READ|APPEND - read, append, create if not exist.
""   - WRITE|NEW   - write, fail if file exist.

to mirror fopen capability _and_ add new WRITE|NEW capability.


I would extend File creating LockedFile and/or add a LockFile class to handle file locking as it is done differently on the various *NIX operating systems.

Regan

-- 
Using M2, Opera's revolutionary e-mail client: http://www.opera.com/m2/
July 22, 2004
On Thu, 22 Jul 2004 12:00:32 +1200, Regan Heath wrote:

> On Wed, 21 Jul 2004 14:00:01 +0100, Stewart Gordon <smjg_1998@yahoo.com> wrote:
>> Arcane Jill wrote:
>>> On the Windows platform:
>>>
>>> #    import std.stream;
>>> #
>>> #    void main()
>>> #    {
>>> #        File f = new File("foo"); // where foo does not exist
>>> #    }
>>>
>>> creates the file "foo", does not throw any kind of exception, and then
>>> carries
>>> on executing as though everything were hunky dory.
>>
>> In accordance with the documentation.
>>
>> ----------
>> this()
>> this(char[] filename)
>> this(char[] filename, FileMode mode)
>>      Create the stream with no open file, an open file in read and write
>> mode, or an open file with explicit file mode. mode, if given, is a
>> combination of FileMode.In (indicating a file that can be read) and
>> FileMode.Out (indicating a file that can be written). If the file does
>> not exist, it is created.
>> ----------
>>
>> After all, your code does say "new File"!  Even though that isn't what it really means!
>>
>>> This is currently a very good reason not to use std.stream.File
>>
>> Yes, the whole File class could be more clearly defined.  At the moment, it seems you're meant to manually call std.file.exists first.  Chances are this isn't part of the normal program logic....
>>
>> My idea would probably be something like
>>
>> enum FILE_MODE {
>> 	IN                    = 0b000001,
>> 	OUT                   = 0b000010,
>> 	CREATE_IF_NONEXISTENT = 0b000100,
>> 	NEW_FILE              = 0b001100,    /*!< create new file,
>> 	                                      prevent overwrite */
>> 	OVERWRITE             = 0b001000,    /*!< create new file,
>> 	                                      overwrite if necessary */
>> 	APPEND                = 0b010000,    //!< start pointer at end
>> 	EXCLUSIVE             = 0b100000     /*!< lock for exclusive
>>   	                                      access, if that follows */
>> }
>>
>> Obviously some combinations don't make sense....
> 
> I suggested these a little while back:
> 
> READ
> WRITE
> CREATE
> APPEND
> NEW
> 
> allowing:
> 
> "r"  - READ        - read, fails if file does not exist.
> "w"  - CREATE      - write, overwrite existing.
> "a"  - APPEND      - write, create if not exist.
> "r+" - READ|WRITE  - read, write, fails if file does not exist.
> "w+" - READ|CREATE - read, write, overwrite existing.
> "a+" - READ|APPEND - read, append, create if not exist.
> ""   - WRITE|NEW   - write, fail if file exist.
> 
> to mirror fopen capability _and_ add new WRITE|NEW capability.
> 
> I would extend File creating LockedFile and/or add a LockFile class to handle file locking as it is done differently on the various *NIX operating systems.
> 

Hmmmm...this got me a-thinkin'...

I came up with this...
The open() routine seems to controls four aspects:

  Access: Read, Write, Both, Neither
  File-Exists action: Use, Overwrite, Fail
  File-Not-Exists action: Create, Fail
  Initial Seek: Start-of-File (normal), End-of-File (append)

This leads to 48 different combinations, some of which are not useful (eg. neither read nor write, fails if exists and if not-exists, read starting from end of file, etc...). So after removing the useless combinations, we are left with 20 possible ones.

I've devised six codes that encompass these combinations:
R : read access from start of file
W : write access from start of file
A : write access from end of file
U : use existing file
O : overwrite existing file
C : create non-existing file

So the useful combinations that either open a file or fail are (I've also show Regan's equivalent codes) ...

RWUC      - read, write, use existing, create if not existing.
RAUC "a+" - read, append (to existing), create if not exist.
RWOC "w+" - read, write, overwrite existing(, create if not existing).
RWU  "r+" - read, write, fails if file does not exist.
RAU       - read, append to existing, fail if not exist.
RWC       - read, write, fail if exists, create if not existing.
RWO       - read, write, overwrite if exists, fail if not existing.
RAO       - read, append if exists, fail if not existing.
WUC       - write, use if exists, create if not existing.
AUC  "a"  - write(, append if exists), create if not exist.
WOC  "w"  - write, overwrite existing(, create if not existing).
RUC       - read, use if exists, create if not existing.
ROC       - read, overwrite if exists, create if not existing. (Used to
                 always create an empty file).
RU   "r"  - read, fails if file does not exist.
RC        - read, fail if exists, create if not existing. (Used to create
                 an empty file if it doesn't already exist).
RO        - read, overwrite if exists, fail if not existing. (Used to wipe
                 an existing file).
WU        - write, use if file exists, fail if not existing.
AU        - write, append if file exists, fail if not existing.
WC    ""  - write, fail if file exists(, create if not existing).
WO        - write, overwrite if exists, fail if not existing.(Used to
                 replace an existing file).


Of course, these don't take file locking into account ;-)

-- 
Derek
Melbourne, Australia
22/Jul/04 12:06:49 PM
« First   ‹ Prev
1 2