Jump to page: 1 2
Thread overview
Strange behavior of read file
Aug 27, 2013
Paul Jurczak
Aug 27, 2013
Paul Jurczak
Aug 27, 2013
monarch_dodra
Aug 27, 2013
monarch_dodra
Aug 27, 2013
Ramon
Aug 27, 2013
Justin Whear
Aug 28, 2013
Ramon
Aug 27, 2013
H. S. Teoh
Aug 28, 2013
Paul Jurczak
Aug 27, 2013
H. S. Teoh
Aug 27, 2013
Jesse Phillips
Aug 27, 2013
monarch_dodra
August 27, 2013
module main;

import std.stdio, std.file, std.string, std.algorithm, std.range, std.datetime, std.conv, std.typetuple;

int f(string fileName = r"C:\Euler\data\e67.txt") {
   auto text = read(fileName);
   return text.length;
}

void main()
{
  try {
      string fileName = r"C:\Euler\data\e67.txt";
      auto text = read(fileName);
      writeln(text.length);

      writeln(f);  // **** EXCEPTION HERE
   }
   catch (Exception e) {
      writeln(e);
   }

   writeln(f);
}

I'm running this test code compiled with DMD 2.063.2 on Windows 7 and I'm getting an exception "The system cannot find the file specified". The same code runs fine on Linux. The file in question exists of course.

When I remove the default parameter value from f(), exceptions stop. Is there a problem of having two strings r"C:\Euler\data\e67.txt" with the same content?

August 27, 2013
Correction to my initial post:

I oversimplified the code example by snipping too much of context. Here is an example, which fails both on Windows and Linux:

module main;

import std.stdio, std.file, std.string, std.algorithm, std.range, std.datetime, std.conv, std.typetuple;

int e67_1(string fileName = r"67.txt") {
   // Read triangle numbers from file.
   int[][] cell;

   foreach (y, line; splitLines(cast(char[]) read(fileName))) {
      auto row = new int[y+1];

      foreach (x, token; split(line))
         row[x] = to!int(token);

      cell ~= row;
   }

   // Compute maximum value partial paths ending at each cell.
   foreach (y; 1..cell.length) {
      cell[y][0] += cell[y-1][0];

      foreach (x; 1..y)
         cell[y][x] += max(cell[y-1][x-1], cell[y-1][x]);

      cell[y][y] += cell[y-1][y-1];
   }

   // Return the maximum value terminal path.
   return cell[$-1].reduce!max;
}


void main()
{
   try {
      writeln(e67_1);
   }
   catch (Exception e) {
      writeln(e);
   }
}

Here is the message on Linux:

std.file.FileException@std/file.d(219): 67.txt: No such file or directory
----------------
./main(void[] std.file.read(const(char[]), ulong)+0x87) [0x4c5b2b]
./main(int main.e67_1(immutable(char)[])+0x41) [0x4805a9]
./main(_Dmain+0x56) [0x4807de]
./main(extern (C) int rt.dmain2._d_run_main(int, char**, extern (C) int function(char[][])*).void runMain()+0x18) [0x4b8e60]
./main(extern (C) int rt.dmain2._d_run_main(int, char**, extern (C) int function(char[][])*).void tryExec(scope void delegate())+0x2a) [0x4b8992]
./main(extern (C) int rt.dmain2._d_run_main(int, char**, extern (C) int function(char[][])*).void runAll()+0x40) [0x4b8eb0]
./main(extern (C) int rt.dmain2._d_run_main(int, char**, extern (C) int function(char[][])*).void tryExec(scope void delegate())+0x2a) [0x4b8992]
./main(_d_run_main+0x1ae) [0x4b894e]
./main(main+0x17) [0x4b879b]
/lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0xf5) [0x7ff2929ccea5]

Again, the file requested exists. I test that by adding other functions (from my initial post) to the code above.
August 27, 2013
On Tuesday, 27 August 2013 at 15:45:06 UTC, Paul Jurczak wrote:
> module main;
>
> import std.stdio, std.file, std.string, std.algorithm, std.range, std.datetime, std.conv, std.typetuple;
>
> int f(string fileName = r"C:\Euler\data\e67.txt") {
>    auto text = read(fileName);
>    return text.length;
> }
>
> void main()
> {
>   try {
>       string fileName = r"C:\Euler\data\e67.txt";
>       auto text = read(fileName);
>       writeln(text.length);
>
>       writeln(f);  // **** EXCEPTION HERE
>    }
>    catch (Exception e) {
>       writeln(e);
>    }
>
>    writeln(f);
> }
>
> I'm running this test code compiled with DMD 2.063.2 on Windows 7 and I'm getting an exception "The system cannot find the file specified". The same code runs fine on Linux. The file in question exists of course.
>
> When I remove the default parameter value from f(), exceptions stop. Is there a problem of having two strings r"C:\Euler\data\e67.txt" with the same content?

Works for me on my own win7 with 2.063.2 (replaced file with
r"C:\D\test.txt"). Not sure what else is going on. Did you copy
paste the *exact* code that was failing? Please try inserting
this trace:

int f(string fileName = r"C:\D\test.txt") {
    writeln("fileName: ", fileName); //HERE
    auto text = read(fileName);
    return text.length;
}

And report what happens.

Off topic, "text" might be a poor choice for a variable name, as
it shadows the pretty common function "std.conv.text"
August 27, 2013
On Tuesday, 27 August 2013 at 17:14:23 UTC, Paul Jurczak wrote:
> Correction to my initial post:

I'll investigate later then.
August 27, 2013
On Tue, Aug 27, 2013 at 07:14:22PM +0200, Paul Jurczak wrote:
> Correction to my initial post:
> 
> I oversimplified the code example by snipping too much of context. Here is an example, which fails both on Windows and Linux:
> 
> module main;
> 
> import std.stdio, std.file, std.string, std.algorithm, std.range, std.datetime, std.conv, std.typetuple;
> 
> int e67_1(string fileName = r"67.txt") {
>    // Read triangle numbers from file.
>    int[][] cell;
> 
>    foreach (y, line; splitLines(cast(char[]) read(fileName))) {

Maybe try inserting a writeln just before the foreach to print out what filename it's actually trying to read? Or try using File to open it and see if you get the same error?

	auto f = File(fileName, "r");


T

-- 
Ignorance is bliss... until you suffer the consequences!
August 27, 2013
On Tuesday, 27 August 2013 at 17:19:08 UTC, monarch_dodra wrote:
> On Tuesday, 27 August 2013 at 17:14:23 UTC, Paul Jurczak wrote:
>> Correction to my initial post:
>
> I'll investigate later then.

I am unable to reproduce.
August 27, 2013
I played a little with it

int f(string fileName = r"someExistingPath") {
   auto text = read(fileName);
   return text.length;
}

void main()
{
  try {
      string fileName = r"someExistingPath";
      if(exists(fileName))
         writeln("File '", fileName, "' does exist.");
      auto text = read(fileName);
      writeln(text.length);

      writeln(f);  // **** EXCEPTION HERE
   }
   catch (Exception e) {
      writeln(e);
   }

   writeln(f);
}

As you see, I mistrustingly inserted a dumb exist test before attempting to read.

Here's what I came up with (on linux):

- trying with filename r"~/text.txt" (i.e. an existing file in my home dir) it FAILED.

- trying with the same filename but this time home dir explicitely written out fully (r"/home/me/test.txt) it WORKED.

- your code did NOT throw where you say it does ("writeln(f)") but actually in the read call.

Conclusion: I assume D's OS path related mechanisms to be somewhat dumb. Anyway the code throws where it's supposed to, i.e. when confronted with a non existing (or not recognized?) path.
August 27, 2013
On Wed, 28 Aug 2013 00:51:12 +0200, Ramon wrote:

> 
> - trying with filename r"~/text.txt" (i.e. an existing file in my home
> dir) it FAILED.
> 
> - trying with the same filename but this time home dir explicitely written out fully (r"/home/me/test.txt) it WORKED.
> 
> Conclusion: I assume D's OS path related mechanisms to be somewhat dumb. Anyway the code throws where it's supposed to, i.e. when confronted with a non existing (or not recognized?) path.

You need to use the expandTilde function: http://dlang.org/phobos/ std_path.html#.expandTilde
August 27, 2013
On Wed, Aug 28, 2013 at 12:51:12AM +0200, Ramon wrote: [...]
> Here's what I came up with (on linux):
> 
> - trying with filename r"~/text.txt" (i.e. an existing file in my
> home dir) it FAILED.
> 
> - trying with the same filename but this time home dir explicitely written out fully (r"/home/me/test.txt) it WORKED.
[...]

That's because '~' is expanded not by the OS but by the shell. The OS treats it as a directory with the literal name '~', which doesn't exist. D's file I/O functions don't go through the shell.

std.path.expandTilde is your friend. :)


T

-- 
This sentence is false.
August 27, 2013
On Tuesday, 27 August 2013 at 17:14:23 UTC, Paul Jurczak wrote:
> Correction to my initial post:
>
> I oversimplified the code example by snipping too much of context. Here is an example, which fails both on Windows and Linux:

I get a range violation in Linux, but that is to be expected since my file is empty. Removing the file gives the file not found exception.
« First   ‹ Prev
1 2