- Java – IOException: Failed to open file: Access denied
- Best Solution
- Related Solutions
- Read all text from a file
- Read lines of text from a file
- Memory utilization
- Character encoding
- Java — IOException: Failed to open file: Access denied
- Не удается запустить файл в сети с помощью Java Desktop?
- java.awt.Desktop cannot open file with Windows UNC filename
- Backports
- Description
Java – IOException: Failed to open file: Access denied
I’ve been developing some software in Java that’ll be distributed for use with Windows or MacOS. I’m programming on an iMac at the moment (because of the Apple specific requirements). The following method drags a helpfile (.pdf) out of resources and copies it locally so that it can be displayed on the local machine.
private void mHelpActionPerformed(java.awt.event.ActionEvent evt) < String sourceFile = "resources/BRC2Help.pdf"; String destFile = "brc2help.pdf"; File f = new File (destFile); if (!f.exists()) < try < URL url = ClassLoader.getSystemResource(sourceFile) ; InputStream is = url.openStream(); OutputStream os = new FileOutputStream(destFile); byte[] b = new byte[2048]; int length; while ((length = is.read(b)) != -1) < os.write(b, 0, length); >is.close(); os.close(); System.out.printf("loaded pdf file from resources: %d bytes\n",f.length()); > catch (IOException ex) > else < System.out.printf("%s exists: %d bytes\n",destFile,f.length()); >try < if (f.exists()) < f.setReadable(true); if (Desktop.isDesktopSupported()) < Desktop.getDesktop().open(f); >else < System.out.println("Awt Desktop is not supported!"); >> > catch (Exception ex) < JOptionPane.showMessageDialog(this, String.format("%s\n",ex), "Helpfile Problem?", JOptionPane.ERROR_MESSAGE); >>
This all works well enough on the Mac but gives an IOException on Windows 7:
java.io.IOException: Failed to open file:/C:/Program%20Files/BRC2/brc2help.pdf. Error message: Access denied.
Any idea what’s going wrong here ? I’ve tried copying the .pdf file to other locations but the result is the same.
Best Solution
What is the working directory for the program when running on Windows? It is possible that the user context running the program doesn’t have rights to write to c:\Program Files\ .
You did not specify the path to the file so my assumption is that c:\program files\brc\ is the working directory while running the program. Since Windows Vista, you need to have full administration rights to be able to write to the Program Files and other directories.
Updated: 7/1/2012
Ok, I was able to stub out your program and run it as a main class and was able to have Desktop.getDesktop().open(f); open a PDF file on Windows 7. I manually put a PDF file into the bin directory where Eclipse compiled my class file to.
I now need to try moving the class file and pdf into a subdirectory of c:\program files\ and see if I get the access denied exception you receive.
Hum, I was able to get Desktop.getDesktop().open(f); open the PDF file when it was in c:\program files\test\ , see my output below:
C:\Program Files\test>"\Program Files (x86)\Java\jre7\bin\java.exe" MyTestClass brc2help.pdf exists: 943123 bytes C:\Program Files\test>dir Volume in drive C is OS Volume Serial Number is 2035-793F Directory of C:\Program Files\test 07/01/2012 10:25 PM . 07/01/2012 10:25 PM .. 07/01/2012 09:55 PM 943,123 BRC2Help.pdf 07/01/2012 09:57 PM 2,391 MyTestClass.class 2 File(s) 945,514 bytes 2 Dir(s) 567,516,254,208 bytes free
What JRE are you using? Mine is java version «1.7.0_01» Java(TM) SE Runtime Environment (build 1.7.0_01-b08)
Related Solutions
Java – How to create a Java string from the contents of a file
Read all text from a file
Java 11 added the readString() method to read small files as a String , preserving line terminators:
String content = Files.readString(path, StandardCharsets.US_ASCII);
For versions between Java 7 and 11, here’s a compact, robust idiom, wrapped up in a utility method:
static String readFile(String path, Charset encoding) throws IOException
Read lines of text from a file
Java 7 added a convenience method to read a file as lines of text, represented as a List . This approach is «lossy» because the line separators are stripped from the end of each line.
List lines = Files.readAllLines(Paths.get(path), encoding);
Java 8 added the Files.lines() method to produce a Stream . Again, this method is lossy because line separators are stripped. If an IOException is encountered while reading the file, it is wrapped in an UncheckedIOException , since Stream doesn’t accept lambdas that throw checked exceptions.
try (Stream lines = Files.lines(path, encoding))
This Stream does need a close() call; this is poorly documented on the API, and I suspect many people don’t even notice Stream has a close() method. Be sure to use an ARM-block as shown.
If you are working with a source other than a file, you can use the lines() method in BufferedReader instead.
Memory utilization
The first method, that preserves line breaks, can temporarily require memory several times the size of the file, because for a short time the raw file contents (a byte array), and the decoded characters (each of which is 16 bits even if encoded as 8 bits in the file) reside in memory at once. It is safest to apply to files that you know to be small relative to the available memory.
The second method, reading lines, is usually more memory efficient, because the input byte buffer for decoding doesn’t need to contain the entire file. However, it’s still not suitable for files that are very large relative to available memory.
For reading large files, you need a different design for your program, one that reads a chunk of text from a stream, processes it, and then moves on to the next, reusing the same fixed-sized memory block. Here, «large» depends on the computer specs. Nowadays, this threshold might be many gigabytes of RAM. The third method, using a Stream is one way to do this, if your input «records» happen to be individual lines. (Using the readLine() method of BufferedReader is the procedural equivalent to this approach.)
Character encoding
One thing that is missing from the sample in the original post is the character encoding. There are some special cases where the platform default is what you want, but they are rare, and you should be able justify your choice.
The StandardCharsets class defines some constants for the encodings required of all Java runtimes:
String content = readFile("test.txt", StandardCharsets.UTF_8);
The platform default is available from the Charset class itself:
String content = readFile("test.txt", Charset.defaultCharset());
Note: This answer largely replaces my Java 6 version. The utility of Java 7 safely simplifies the code, and the old answer, which used a mapped byte buffer, prevented the file that was read from being deleted until the mapped buffer was garbage collected. You can view the old version via the «edited» link on this answer.
Java – File to byte[] in Java
From JDK 7 you can use Files.readAllBytes(Path) .
import java.io.File; import java.nio.file.Files; File file; // . (file is initialised). byte[] fileContent = Files.readAllBytes(file.toPath());
Related Question
Java — IOException: Failed to open file: Access denied
What is the working directory for the program when running on Windows? It is possible that the user context running the program doesn’t have rights to write to c:\Program Files\ .
You did not specify the path to the file so my assumption is that c:\program files\brc\ is the working directory while running the program. Since Windows Vista, you need to have full administration rights to be able to write to the Program Files and other directories.
Updated: 7/1/2012
Ok, I was able to stub out your program and run it as a main class and was able to have Desktop.getDesktop().open(f); open a PDF file on Windows 7. I manually put a PDF file into the bin directory where Eclipse compiled my class file to.
I now need to try moving the class file and pdf into a subdirectory of c:\program files\ and see if I get the access denied exception you receive.
Hum, I was able to get Desktop.getDesktop().open(f); open the PDF file when it was in c:\program files\test\ , see my output below:
C:\Program Files\test>"\Program Files (x86)\Java\jre7\bin\java.exe" MyTestClass brc2help.pdf exists: 943123 bytes C:\Program Files\test>dir Volume in drive C is OS Volume Serial Number is 2035-793F Directory of C:\Program Files\test 07/01/2012 10:25 PM . 07/01/2012 10:25 PM .. 07/01/2012 09:55 PM 943,123 BRC2Help.pdf 07/01/2012 09:57 PM 2,391 MyTestClass.class 2 File(s) 945,514 bytes 2 Dir(s) 567,516,254,208 bytes free
What JRE are you using? Mine is java version «1.7.0_01» Java(TM) SE Runtime Environment (build 1.7.0_01-b08)
Не удается запустить файл в сети с помощью Java Desktop?
(У меня есть проблема, которую я проиллюстрировал в этом вопросе, но у меня не было правильных ответов. Я уточнил свою проблему и попытался отредактировать первоначальный вопрос, чтобы отразить это, но я предполагаю, что из-за того, что SO отображает неотвеченные вопросы, он потерял импульс, и нет никакого способа чтобы восстановить его. Поэтому я снова публикую свой правильный вопрос).
У меня есть файл, который находится в общей сетевой папке:
"\\KUROSAVVAS-PC\Users\kuroSAVVAS\Desktop\New Folder\Warsaw Panorama.JPG"
import java.awt.Desktop; import java.io.File; import java.io.IOException; public class Test < public static void main(String[] args) < try < String s = "\\\\KUROSAVVAS-PC\\Users\\kuroSAVVAS\\Desktop\\New Folder\\Warsaw Panorama.jpg"; File f = new File(s); System.out.println(f.exists()); Desktop.getDesktop().open(f); >catch (IOException e) < e.printStackTrace(); >> >
Печатает в консоль, что файл существует (System.out.println (f.exists ());), но выдает это исключение!:
java.io.IOException: Failed to open file:////KUROSAVVAS-PC/Users/kuroSAVVAS/Desktop/New%20%20%20%20%20Folder/Warsaw%20%20%20%20Panorama.jpg. Error message: The system cannot find the file specified. at sun.awt.windows.WDesktopPeer.ShellExecute(WDesktopPeer.java:59) at sun.awt.windows.WDesktopPeer.open(WDesktopPeer.java:36) at java.awt.Desktop.open(Desktop.java:254) at Test.main(Test.java:13)
Кто-нибудь знает, почему может произойти нечто подобное? Я перепробовал все, от создания URI до декодирования их потом. Ничего не работает.
java.awt.Desktop cannot open file with Windows UNC filename
Priority: P2
Backports
Issue | Fix Version | Assignee | Priority | Status | Resolution | Resolved In Build |
---|---|---|---|---|---|---|
JDK-8008797 | 8 | Anton Litvinov | P2 | Closed | Fixed | b84 |
JDK-8021761 | 7u60 | Anton Litvinov | P2 | Resolved | Fixed | b01 |
JDK-8021554 | 7u51 | Anton Litvinov | P2 | Resolved | Fixed | b01 |
JDK-8018647 | 7u45 | Anton Litvinov | P2 | Closed | Fixed | b05 |
JDK-8008798 | 7u40 | Anton Litvinov | P2 | Closed | Fixed | b20 |
JDK-8016823 | 7u25 | Anton Litvinov | P2 | Closed | Fixed | b31 |
JDK-8013637 | 7u21 | Anton Litvinov | P2 | Closed | Fixed | b31 |
JDK-8017406 | 6u65 | Anton Litvinov | P2 | Closed | Fixed | b02 |
JDK-8019331 | 6u51 | Anton Litvinov | P2 | Resolved | Fixed | b31 |
Description
FULL PRODUCT VERSION :
java version «1.6.0»
Java(TM) SE Runtime Environment (build 1.6.0-b105)
Java HotSpot(TM) Client VM (build 1.6.0-b105, mixed mode)
ADDITIONAL OS VERSION INFORMATION :
Microsoft Windows XP [version 5.1.2600]
A DESCRIPTION OF THE PROBLEM :
Hi,
The java.awt.Desktop class does not allow to open a network file with blank character into the path. For example, it fails to open «//serverName/drive/Temp/my folder/a simple file.xxx», where xxx may be any extension : txt, pdf.
For information, it works if the path contains the drive letter «N:/Temp/my folder/a simple file.txt», or if the path does not contain any blank like «//serverName/drive/Temp/my_folder/a_simple_file.txt».
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED —
Should open the file with the application used for its extension, like Notepad for txt file.
ACTUAL —
IOException
ERROR MESSAGES/STACK TRACES THAT OCCUR :
The ouput is:
java.io.IOException: Failed to open file:////serverName/drive/Temp/my%20folder/a%20simple%20file.txt. Error message: Le chemin d’accès spécifié est introuvable.
at sun.awt.windows.WDesktopPeer.ShellExecute(Unknown Source)
at sun.awt.windows.WDesktopPeer.open(Unknown Source)
at java.awt.Desktop.open(Unknown Source)
at Swing.myDesktop.main(jvDesktop.java:26)
REPRODUCIBILITY :
This bug can be reproduced always.
import java.awt.*;
import java.io.*;
public class myDesktop
public static void main(String[] args)
try
Desktop myDesktop = null;
if (Desktop.isDesktopSupported())
myDesktop = Desktop.getDesktop();
if (myDesktop != null)
// -> Works
//File myFile = new File(«//sma-nasft04-1/servev/Temp/my_folder/a_simple_file.txt»);
//File myFile = new File(«N:/Temp/my folder/a simple file.txt»);
// -> Does not work
File myFile = new File(«//sma-nasft04-1/servev/Temp/my folder/a simple file.txt»);
if (myFile.exists())
myDesktop.open(myFile);
else
System.out.println(«This file is not a valid one»);
>
>
catch (IOException e)
e.printStackTrace();
>
>