有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

windows 7 Java文件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
     }

这些都运行在Windows7和JDK1.6.26以及Netbeans、Tomcat7.0.14上。目标目录实际上位于我的netbeans项目目录中,在一个普通web应用程序(web-INF外部)的文件夹中,我通常希望在该文件夹中有写文件的权限

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

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

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

从netbeans项目目录下给每个人“完全控制权”

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

残疾UAC

但错误依然存在。谷歌对此的搜索范围似乎很广,读起来就像vodoo。显然,我(以及Java和Netbeans等)应该有权限将文件写入目录

有人有什么见解吗?这是一个封闭系统上的全部内容(代码和承载URL的web服务器),因此我无法剪切和粘贴代码或堆栈跟踪

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

更新2:这里是一个堆栈跟踪(在本例中,file2Save的perm是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

共 (2) 个答案

  1. # 1 楼答案

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

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

    1. 目标文件存在于web根目录下,例如WEB-INF文件夹和
    2. 目标文件由默认的servlet和
    3. 客户端和客户端至少请求了一次目标文件
    4. 你正在Windows下运行

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

    如果您的web应用程序正好存在这个问题,那么不应该使用默认的servlet来提供文件内容。默认的servlet是designed,用于提供您不想更改的静态内容,例如css文件、javascript文件、背景图像等

    通过禁用NIO http://docs.codehaus.org/display/JETTY/Files+locked+on+Windows可以解决Windows for jetty上的文件锁定问题

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

  2. # 2 楼答案

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

    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

    让我知道进展如何