JDK-6182812 : FileOutputStream constructor throws FileNotFoundException with long file names
  • Type: Bug
  • Component: core-libs
  • Sub-Component: java.io
  • Affected Version:
    7.0se,8.1ee,1.3.1_13,1.4.0,1.4.2,5.0,6 7.0se,8.1ee,1.3.1_13,1.4.0,1.4.2,5.0,6
  • Priority: P3
  • Status: Closed
  • Resolution: Fixed
  • OS:
    generic,solaris_8,windows,windows_2000,windows_xp generic,solaris_8,windows,windows_2000,windows_xp
  • CPU: generic,x86
  • Submitted: 2004-10-21
  • Updated: 2010-12-03
  • Resolved: 2005-01-07
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 6
6 b19Fixed
Related Reports
Duplicate :  
Duplicate :  
Description
FULL PRODUCT VERSION :
java version "1.5.0"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0-b64)
Java HotSpot(TM) Client VM (build 1.5.0-b64, mixed mode, sharing)

java version "1.4.2_05"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.2_05-b04)
Java HotSpot(TM) Client VM (build 1.4.2_05-b04, mixed mode)

ADDITIONAL OS VERSION INFORMATION :
Microsoft Windows XP [Version 5.1.2600]

A DESCRIPTION OF THE PROBLEM :
The FileOutputStream constructor is throwing a FileNotFoundExeception when "long" paths or filenames are used.  We have noticed slightly different behavior depending on the exact nature of the file/path.

For just file name (no path), the file name must be very long (~200 characters).

For relative paths, the path needs to be fairly long, but no individual path component or file name is unusually long.

For absolute paths, the exception is not thrown, but the file is not created.

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Run the attached code.

EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
The FileOutputStream should be created without error and the file should exist.
ACTUAL -
The FileOutputStream constructor throws an exception. With an absolute path, the constructor succeeds, but the file does not exist.

ERROR MESSAGES/STACK TRACES THAT OCCUR :
java.io.FileNotFoundException: out\com.ascential.xmeta.persistence.impl.concrete.model.ConcreteRelationships\src\java\com\ascential\xmeta\persistence\impl\concrete\model\ConcreteRelationships\xmetagen\Fred123456.java (The system cannot find the path specified)
        at java.io.FileOutputStream.open(Native Method)
        at java.io.FileOutputStream.<init>(Unknown Source)
        at java.io.FileOutputStream.<init>(Unknown Source)
        at com.ascential.test.FileNotFoundTest.doTest(FileNotFoundTest.java:72)
        at com.ascential.test.FileNotFoundTest.testWithRelativePaths(FileNotFoundTest.java:41)
        at com.ascential.test.FileNotFoundTest.main(FileNotFoundTest.java:10)

REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------
package com.ascential.test;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;

public class FileNotFoundTest {
    public static void main(String[] args) {
        testWithLongFileNames();
        testWithRelativePaths();
        testWithAbsolutePaths();
    }
    
    /**
     * Demonstrate the problem with very long file names. This particular
     * aspect of the issue is not terribly concerning to us, but may be
     * related to the root cause.
     * 
     */
    private static void testWithLongFileNames() {
        String worksFileName = "123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345";
        String failsFileName = "1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456";

        System.out.println("Testing with long file names:");
        doTest(worksFileName);
        doTest(failsFileName);
        System.out.println("");
    }
    
    /**
     * Demonstrates the problem using relative paths. None of the individual
     * directory or file names are very long, but the problem still occurs.
     * 
     */
    private static void testWithRelativePaths() {
        String worksFileName ="out\\com.ascential.xmeta.persistence.impl.concrete.model.ConcreteRelationships\\src\\java\\com\\ascential\\xmeta\\persistence\\impl\\concrete\\model\\ConcreteRelationships\\xmetagen\\impl\\concrete\\model\\ConcreteRelationships\\xmetagen\\impl\\concrete\\model\\Fred123456.java";        
String failsFileName = "out\\com.ascential.xmeta.persistence.impl.concrete.model.ConcreteRelationships\\src\\java\\com\\ascential\\xmeta\\persistence\\impl\\concrete\\model\\ConcreteRelationships\\xmetagen\\impl\\concrete\\model\\ConcreteRelationships\\xmetagen\\impl\\concrete\\model\\Fred1234567.java";        
        System.out.println("Testing with relative paths:");
        doTest(worksFileName);
        doTest(failsFileName);
        System.out.println("");
    }
    
    /**
     * Demonstrate the problem with absolute paths. The real concern here is
     * that the second file appears to be opened successfully, but the file
     * is not created.
     * 
     */
    private static void testWithAbsolutePaths() {
          String worksFileName ="c:\\views\\mtucker_xmeta_sv\\metadata_infrastructure\\framework\\out\\com.ascential.xmeta.persistence.impl.concrete.model.ConcreteRelationships\\src\\java\\com\\ascential\\xmeta\\persistence\\impl\\concrete\\model\\ConcreteRelationships\\xmetagen\\Fred12345678901234567890.java";
          String failsFileName ="c:\\views\\mtucker_xmeta_sv\\metadata_infrastructure\\framework\\out\\com.ascential.xmeta.persistence.impl.concrete.model.ConcreteRelationships\\src\\java\\com\\ascential\\xmeta\\persistence\\impl\\concrete\\model\\ConcreteRelationships\\xmetagen\\Fred123456789012345678901.java";
    
          System.out.println("Testing with absolute paths:");
          doTest(worksFileName);
          doTest(failsFileName);
          System.out.println("");
    }
    
    
    private static void doTest(String fileName) {
        File firstFile = new File(fileName);
        
        if (firstFile.getParentFile() != null) {
            firstFile.getParentFile().mkdirs();
        }
        
        System.out.println("Testing: " + fileName);
        
        try {
            FileOutputStream fos = new FileOutputStream(firstFile);
            System.out.println("  file open succeeded");
        } catch (FileNotFoundException e) {
            System.out.println("  file open failed");
            e.printStackTrace();
        }
        
        System.out.println("  exists: " + firstFile.exists());
        System.out.println("");
    }
}

---------- END SOURCE ----------
###@###.### 10/21/04 20:15 GMT

Comments
EVALUATION The Microsoft documentation for CreateFile http://msdn.microsoft.com/library/default.asp?url=/library/en-us/fileio/base/createfile.asp says ----------------------------------------------------------------------- pFileName [in] Pointer to a null-terminated string that specifies the name of the object to create or open. In the ANSI version of this function, the name is limited to MAX_PATH characters. To extend this limit to 32,767 wide characters, call the Unicode version of the function and prepend "\\?\" to the path. For more information, see Naming a File. ----------------------------------------------------------------------- Amazing but true. It looks like all we have to do is prepend "\\?\" to the path in fileOpen in io_util_md.c. Or perhaps in pathToNTPath. ###@###.### 10/21/04 22:49 GMT Even with \\?\ or \\?\UNC\, each component of a path can still only be "up to 255" on Windows platform, so testWithLongFileNames() still fails for the "failsfileName" since it has a lenth of 257 filename. The rest of the 2 test cases "testWithRelativePaths" and "testWithAbsolutePaths" should work with the planning fix. ###@###.### 2004-12-13 22:06:24 GMT
2004-10-21