Java 文件 IO 和“拒绝访问”错误

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/6867832/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-30 17:39:08  来源:igfitidea点击:

Java file IO and "access denied" errors

javawindows-7file-io

提问by stimpy

I have been tearing my hair out on this and thus I am looks for some help .

我一直在为此烦恼,因此我正在寻求帮助。

I have a loop of code that performs the following

我有一个执行以下操作的代码循环

//imports ommitted
public void afterPropertiesSet() throws Exception{

  //building of URL list ommitted  
  // urlMap is a HashMap <String,String> created and populated just prior   

    for ( Object urlVar : urlMap.keySet() ){
    String myURLvar = urlMap.get(urlVar.toString);
    System.out.println ("URL is "+myURLvar );
    BufferedImage imageVar = ImageIO.read(myURLvar);//URL confirmed to be valid even for executions that fail
    String fileName2Save = "filepath"// a valid file path
    System.out.println ("Target path is "+fileName2Save );
    File file2Save = new File (fileName2Save);
    fileName2Save.SetWriteable(true);//set these just to be sure
    fileName2Save.SetReadable(true);
      try{
       ImageIO.write (imageVar,"png",file2save)//error thrown here 
      }catch (Exception e){
     System.out.println("R: "+file2Save.canRead()+" W: "+file2Save.canWrite()+" E:"+file2Save.canExecute()+" Exists: "+file2Save.exists+" is a file"+file2Save.isFile() );

     System.out.println("parent Directory perms");// same as above except on parent directory of destination
      }//end try
     }//end for
     }

This all runs on Windows 7 and JDK 1.6.26 and Netbeans,Tomcat 7.0.14 . The target directory is actually inside my netbeans project directory in a folder for a normal web app ( outside WEB-INF) where I would expect normally to have permission to write files.

这一切都在 Windows 7 和 JDK 1.6.26 以及 Netbeans,Tomcat 7.0.14 上运行。目标目录实际上位于我的 netbeans 项目目录中的一个普通 Web 应用程序(在 WEB-INF 之外)的文件夹中,我通常希望在该文件夹中拥有写入文件的权限。

When the error occurs I get one of two results for the file a.) All false b.)all true. The Parent directory permission never change all true except for isFile.

当错误发生时,我得到文件 a.) 全部错误 b.) 全部正确的两个结果之一。除了 isFile 之外,父目录权限永远不会改变全部为真。

The error thrown ( java.IO.error with "access denied" ") does not occur every time ... in fact 60% of the time the loop runs it throws no error. The remaining 40% of the time I get the error on 1 of the 60+ files it writes. Infrequently the same one. The order in which the URLs it starts from changes everytime so the order in which the files are written is variable. The file names have short concise names like "1.png". The images are small..less then 8k.

抛出的错误( java.IO.error with "access denied" ")不会每次都发生......事实上,循环运行的时间有 60% 不会抛出错误。剩下的 40% 的时间我得到错误在它写入的 60 多个文件中的 1 个上。很少是相同的。它开始的 URL 的顺序每次都会改变,因此写入文件的顺序是可变的。文件名具有简短的简洁名称,如“1.png” “。图像很小......小于8k。

In order to make sure the permissions are correct I have :

为了确保权限正确,我有:

Given "full control" to EVERYONE from the net beans project directory down

从 net beans 项目目录向下给予每个人“完全控制”

Run the JDK,JRE and Netbeans as Administrator

以管理员身份运行 JDK、JRE 和 Netbeans

Disabled UAC

禁用 UAC

Yet the error persists. Google searches for this seem to run the gamut and often read like vodoo. Clearly I ( and Java and Netbeans etc ) should have permission to write a file to the directory .

但是错误仍然存​​在。谷歌对此的搜索似乎涵盖了所有领域,并且通常读起来像伏都教。显然,我(以及 Java 和 Netbeans 等)应该有权将文件写入该目录。

Anyone have any insight ? This is all ( code and the web server hosting the URL) on a closed system so I can't cut and paste code or stacktrace.

任何人有任何见解?这就是封闭系统上的所有内容(代码和托管 URL 的 Web 服务器),因此我无法剪切和粘贴代码或堆栈跟踪。

Update: I confirmed the imageURL is valid by doing a println & toString prior to each read. I then confirmed that a.) the web server hosting the target URL returned the image with a http 200 code b.) that the URL returned the image when tested in a web browser. In testing I also put a if () in after the read to confirm that the values was not NULL or empty. I also put in tests for NULL on all the other values . They are always as expected even for a failure .The error always occurs inside the try block. The destination directory is the same every execution. Prior to every execution the directory is empty.

更新:我通过在每次读取之前执行 println & toString 来确认 imageURL 是有效的。然后我确认 a.) 托管目标 URL 的 Web 服务器返回了带有 http 200 代码的图像 b.) 在 Web 浏览器中测试时,该 URL 返回了图像。在测试中,我还在读取后放置了一个 if () 以确认值不是 NULL 或空。我还对所有其他值进行了 NULL 测试。即使失败,它们也总是如预期的那样。错误总是发生在 try 块内。每次执行的目标目录都是相同的。在每次执行之前,目录是空的。

Update 2: Here is one of the stack traces ( in this case perms for file2Save are R: True W:True E: True isFile:True exists:True )

更新 2:这是堆栈跟踪之一(在这种情况下,file2Save 的权限为 R: True W:True E: True isFile:True exists:True )

    java.io.FileNotFoundException <fullFilepathhere> (Access is denied)
       at java.io.RandomAccessFile.open(Native Method)
       at java.io.RandomAccessFile.<init>(RandomAccessFile.java:212)
       at javax.imageio.stream.FileImageOutputStream.<init>(FileImageOutputStream.java:53)
       at com.sun.imageio.spi.FileImageOutputStreamSpi.createOutputStreamInstance(FileImageOutputStreamSpi.java:37)
       at javax.imageio.ImageIO.createImageOutputStream(ImageIO.java:393)
       at javax.imageio.ImageIO.write(ImageIO.java:1514)
       at myPackage.myClass.afterPropertiesSet(thisClassexample.java:204)// 204 is the line number of the ImageIO write

采纳答案by gigadot

This may not answer your problem since there can be many other possibilties to your limited information.

这可能无法解决您的问题,因为您的有限信息可能还有许多其他可能性。

One common possibilty for not being able to write a file in web application is the file locking issue on Windows if the following four conditions are met simultaneously:

如果同时满足以下四个条件,则无法在 Web 应用程序中写入文件的一种常见可能性是 Windows 上的文件锁定问题:

  1. the target file exists under web root, e.g. WEB-INFfolder and
  2. the target file is served by the default servlet and
  3. the target file has been requested at least once by client and
  4. you are running under Windows
  1. 目标文件存在于 web 根目录下,例如WEB-INF文件夹和
  2. 目标文件由默认 servlet 提供,并且
  3. 客户端至少请求过一次目标文件,并且
  4. 你在 Windows 下运行

If you are trying to replace such a file that meets all of the four conditions, you will not be able to because some servlet containers such as tomcat and jetty will buffer the static contents and lock the files so you are unable to replace or change them.

如果你试图替换这样一个满足所有四个条件的文件,你将无法替换,因为一些 servlet 容器如 tomcat 和 jetty 会缓冲静态内容并锁定文件,因此你无法替换或更改它们.

If your web application has exactly this problem, you should not use the default servlet to serve the file contents. The default servlet is desigend to serve the static content which you do not want to change, e.g. css files, javascript files, background images, etc.

如果您的 Web 应用程序恰好存在此问题,则不应使用默认 servlet 来提供文件内容。默认 servlet 被设计为提供您不想更改的静态内容,例如 css 文件、javascript 文件、背景图像等。

There is a trick to solve the file locking issue on Windows for jetty by disabling the NIO http://docs.codehaus.org/display/JETTY/Files+locked+on+Windows

有一个技巧可以通过禁用 NIO http://docs.codehaus.org/display/JETTY/Files+locked+on+Windows来解决 Windows 上的文件锁定问题。

The trick is useful for development process, e.g. you want to edit the css file and see the change without restarting your web application, but it is not recommended for production mode. If your web application relies on this trick in the production process, then you should seriously consider redesign your codes.

这个技巧对开发过程很有用,例如,您想编辑 css 文件并在不重新启动 Web 应用程序的情况下查看更改,但不建议用于生产模式。如果您的 Web 应用程序在生产过程中依赖于这个技巧,那么您应该认真考虑重新设计您的代码。

回答by Marsellus Wallace

I cannot tell you what's going on or why... I have a feeling that it's something dependent on the way ImageIOtries to save the image. What you could do is saving the BufferedImageby leveraging the ByteArrayOutputStreamas described below:

我不能告诉你发生了什么或为什么......我有一种感觉,这取决于ImageIO尝试保存图像的方式。您可以做的是BufferedImage通过利用ByteArrayOutputStream如下所述来保存:

BufferedImage bufferedImage = ImageIO.read(new File("sample_image.gif"));
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ImageIO.write( bufferedImage, "gif", baos );

baos.flush(); //Is this necessary??
byte[] resultImageAsRawBytes = baos.toByteArray();
baos.close(); //Not sure how important this is...

OutputStream out = new FileOutputStream("myImageFile.gif");
out.write(resultImageAsRawBytes);    
out.close();

I'm not really familiar with the ByteArrayOutputStream, but I guess its reset()function could be handy when dealing with saving multiple files. You could also try using its writeTo(OutputStream out)if you prefer. Documentation here.

我不是很熟悉ByteArrayOutputStream,但我想它的reset()功能在处理保存多个文件时可能会很方便。writeTo(OutputStream out)如果您愿意,也可以尝试使用它。文档在这里

Let me know how it goes...

让我知道事情的后续...