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

时间:2011-07-29 01:54:12

标签: java windows-7 file-io

我一直在梳理我的头发,因此我寻求一些帮助。

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

//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
     }

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

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

抛出的错误(带有“拒绝访问”的java.IO.error“)每次都不会发生...实际上60%的时间循环运行它不会引发任何错误。剩余的40%的时间我在它写的60多个文件中的1个上得到错误。不经常是同一个。它开始的URL的顺序每次都会改变,因此文件的写入顺序是可变的。文件名有简短的简洁名称,如“ 1.png“。图像很小......然后是8k。

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

给net beans项目目录中的EVERYONE“完全控制”

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

已停用的UAC

但错误仍然存​​在。谷歌搜索这个似乎运行的范围,经常读作像vodoo。很明显,我(以及Java和Netbeans等)应该有权将文件写入目录。

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

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

更新2:这是堆栈跟踪之一(在这种情况下,file2Save的perms是R:True W:True E:True isFile:True存在: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

2 个答案:

答案 0 :(得分:1)

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

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

  1. 目标文件存在于web根目录下,例如WEB-INF文件夹和
  2. 目标文件由默认servlet和
  3. 提供
  4. 客户端至少要求一次目标文件
  5. 您在Windows下运行
  6. 如果您尝试替换满足所有这四个条件的文件,您将无法进行,因为某些servlet容器(如tomcat和jetty)将缓冲静态内容并锁定文件,因此您无法替换或改变它们。

    如果您的Web应用程序确实存在此问题,则不应使用默认servlet来提供文件内容。默认的servlet用于提供您不想更改的静态内容,例如: css文件,javascript文件,背景图片等

    通过禁用NIO http://docs.codehaus.org/display/JETTY/Files+locked+on+Windows

    ,可以解决Windows上针对jetty的文件锁定问题

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

答案 1 :(得分:1)

我无法告诉你发生了什么或为什么......我觉得这取决于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();

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

让我知道它是怎么回事......