3

Found a confusing question while learning about file separators

Suppose that the file c:\book\java exists. Which of the following lines of code creates an object that represents the file? (Choose all that apply.)

1. new File("c:\book\java"); 2. new File("c:\\book\\java"); 3. new File("c:/book/java"); 4. new File("c://book//java"); 5. None of the above

the book (assumig a dos based file system) says that

  1. & 3. are right answer
  1. is correct because Java requires a backslash to be escaped with another backslash.
  2. is also correct because Java will convert the slashes to the right one when working with paths..
  • Can 4 also be correct by this logic?
  • and when i change to mac/linux file system - what should be the answer ? (update: we are only creating a file object - whether it makes sense is not the question here - the question is which of these will finally return the path shown above)
RangerReturn
  • 171
  • 3
  • 3
  • 18
  • I'm not sure what "this logic" is, but considering [this](https://stackoverflow.com/questions/20979625/file-path-names-for-windows-and-linux), I think 4 is also correct. – shmosel Mar 04 '18 at 06:02
  • updated the proper explanation. thanks for pointing out – RangerReturn Mar 04 '18 at 06:13

3 Answers3

1

Bear in mind, the backslash ( \ ) is a special character in Java. When you want to place a single backslash character in a String, you must write it as:

"\\"

The above is a String of length 1.

Every OS has a single character that acts as the separator between path components. No matter what, you must specify one character between path components.*

Choices 2 and 3 are correct because they place a single character between path components.

Choice 4 places two characters between path components, which is incorrect. Forward slash, /, is not a special character in Java; if you write it twice, it is simply two characters.

Choice 1 is not legal Java. The backslash is a special character; in String literals, a backslash starts an escape sequence, and "\j" is not one of the valid escape sequences. "\b" is valid but will not do what you want; in particular, it will result in one (invisible) character, rather than a backslash followed by a b.

To answer your final question: There is no C: in Linux or OS X, so while "C:/book/java" is a syntactically legal path, it will not exist (unless someone decided to create their own directory named C: in the current directory, which is pretty unlikely and is almost certainly not what you wanted).

* Technically, paths can have multiple contiguous separators, but it’s meaningless to do that.

VGR
  • 40,506
  • 4
  • 48
  • 63
  • *Unix paths can have multiple contiguous separators...* So can Windows paths. *but it’s meaningless to do that.* So how does that make it incorrect? – shmosel Mar 04 '18 at 06:26
  • @shmosel So they can. I never knew Windows allowed that. Choice 4 is, strictly speaking, not an error, but it’s pointless. I would regard multiple separators much like invoking a static method on an instance: allowed, but incorrect to write. – VGR Mar 04 '18 at 06:31
1

Can 4 also be correct by this logic?

Given that the question is

Suppose that the file c:\book\java exists. Which of the following lines of code creates an object that represents the file? (Choose all that apply.)

  1. new File("c:\book\java");
  2. new File("c:\book\java");
  3. new File("c:/book/java");
  4. new File("c://book//java");
  5. None of the above

2 and 3 are obviously correct. So, does the File object in 4 "create an ojbect that represents the file"?

Yes it does.

Assuming C:\book\java exists, this code

public static void main( String[] args ) throws IOException
{
    File f = new File( args[ 0 ] );
    System.err.printf( "args[0]: %s\n", args[ 0 ] );
    System.err.printf( "Path: %s\n", f.getCanonicalPath() );
}

produces this output:

args[0]: C://book//java
Path: C:\book\java

So new File( "C://book//java" ) most definitely "creates an object that represents the file" and is also a correct answer.

Any argument that it does not is literally incorrect. The question is whether or not the string "creates an object that represents the file". C://book//java demonstrably does exactly that.

Andrew Henle
  • 32,625
  • 3
  • 24
  • 56
0

Forward slash is not an escape character, backslash is an escape character. It takes two backslashes to represent a single file separator in the path to the file, but only one forward slash to represent a single file separator -- where the forward slashes are doubled up, that represents two file separators in a row.

If you change to Mac or Linux, then the premise of the question, that there is a file c:\book\java, makes no sense.

The trick to this question is that you have to be thinking both about the file separators and about how strings in Java are escaped at the same time.

kshetline
  • 12,547
  • 4
  • 37
  • 73
  • The answer is that no, 4 isn't correct. As for the Mac/Linux question, 5 comes closest to the correct answer because the question doesn't make sense. – kshetline Mar 04 '18 at 06:06
  • You didn't test your assertion by any chance, did you? – shmosel Mar 04 '18 at 06:12
  • I don't know how to make the existence of a file `c:\book\java` true on a Mac or Linux system, the prerequisite of the question, in order to test this. – kshetline Mar 04 '18 at 06:15
  • @kshetline the point is - new File() - doesn't check for existence of a file - this is a logical question if you are on a MAC/Linux fs – RangerReturn Mar 04 '18 at 06:17
  • I know that new File() doesn't check for the existence of a file. But in order to test whether any of these variations would match such a file, wouldn't the file have to exist, and the File.exists() return true? If we don't test that, what else would we be testing? – kshetline Mar 04 '18 at 06:20
  • I was talking about the double forward slash. – shmosel Mar 04 '18 at 06:24
  • 1
    You can apparently get away with 4 on a Windows system, with each double forward slash being treated like a single forward slash, even though it's technically not correct. – kshetline Mar 04 '18 at 06:37
  • 1
    On my Mac, I tried this just to see what would happen: `File file = new File("c:\\book\\java"); System.out.println(file.getAbsolutePath());` . The output was `/Library/Java/JavaVirtualMachines/jdk1.8.0_151.jdk/Contents/Home/bin/c:\book\java`, so Java did try to make some sort of crazy sense of that path. – kshetline Mar 04 '18 at 06:40
  • @kshetline exactly my issue here - if 3 and 4 are same - should't they both be right if you try the same for mac the output of 3.and 4. will again be the same ? – RangerReturn Mar 04 '18 at 06:47
  • 1
    The Mac is tolerant of double slashes in a file path, so if somehow `new File("c:/book/java").exists()` were true on a Mac, then `new File("c://book//java").exists()` should also be true, if that's what you're asking. – kshetline Mar 04 '18 at 06:50