项目迁移的过程中发现以前的代码维护性实在是差。
我把问题简化为以下这些简单的代码:项目M 引用了项目 A.jar,这个A在lib目录里面
在A里面放置了一个配置文件test.properties, 就放在jar的根目录下。
A.jar 
|___test.properties在M中有一段代码回去读取这个A.jar里的配置文件,简单一点就用下面这句话来调用。public class ConfigUtil {
public static String getInstance() throws Exception{

String path = ConfigUtil.class.getResource("/").toString();
path  = path.substring(0, path.length()-8);//
System.out.println(path);//这里打印的结果显示可以拿到当前类的绝对路径
InputStream f = new FileInputStream("jar:"+path+"lib!/A.jar/"+"test.properties");
return "xxx";
}
}现在报了file not found Exception
java.io.FileNotFoundException: jar:file:\file:\C:\project_material\test_workspace\.metadata\.plugins\org.eclipse.wst.server.core\tmp0\wtpwebapps\M\WEB-INF\lib!\A.jar\test.properties (The filename, directory name, or volume label syntax is incorrect)从出错的log可以看到它确实访问了eclipse tomcat 的发布路径。jar:file:\file:\C:\project_material\test_workspace\.metadata\.plugins\org.eclipse.wst.server.core\tmp0\wtpwebapps\M\WEB-INF\lib
但是要如何读取这个路径下某个jar包里的文件?

解决方案 »

  1.   


    public class ConfigUtil {
    public static String getInstance() throws Exception{

    URL u = ConfigUtil.class.getClassLoader().getResource("test.properties");
    System.out.println(u.getPath());
    InputStream f = new FileInputStream(u.getPath());
    return "xxx";
    }
    }
    网上查了一下,换了上面这种写法,但是依然报错,在实际的代码里我需要把某个路径传个InputStreamjava.io.FileNotFoundException: file:\C:\project_material\test_workspace\.metadata\.plugins\org.eclipse.wst.server.core\tmp0\wtpwebapps\M\WEB-INF\lib\A.jar!\test.properties (The filename, directory name, or volume label syntax is incorrect)
    at java.io.FileInputStream.open(Native Method)
    at java.io.FileInputStream.<init>(FileInputStream.java:120)
    at java.io.FileInputStream.<init>(FileInputStream.java:79)
    at com.test.ConfigUtil.getInstance(ConfigUtil.java:16)
    at org.apache.jsp.jsp._1_jsp._jspService(_1_jsp.java:65)
    at org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:70)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
    at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:374)
    at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:342)
    at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:267)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:128)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:293)
    at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:849)
    at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:583)
    at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:454)
    at java.lang.Thread.run(Thread.java:662)
      

  2.   

    jar是个ZIP压缩的文件,我该说的说完了。
      

  3.   

    直接用path传值给FileInputStream 不行吗?
      

  4.   

    你不会把A.jar拷贝到新项目的lib里面去吗
      

  5.   

    import java.io.BufferedInputStream;
    import java.io.ByteArrayOutputStream;
    import java.io.File;
    import java.io.FileInputStream;
    import java.io.InputStream;
    import java.util.zip.ZipEntry;
    import java.util.zip.ZipFile;import junit.framework.TestCase;public class Debug extends TestCase
    {
      public void test() throws Exception
      {
        //1.从外部jar包文件读取配置文件内容:
        //假设存在文件: E:/apache-tomcat-6.0.18/webapps/ROOT/WEB-INF/lib/log4j-1.2.16.jar
        //你可以这样读出jar包中的org/apache/log4j/xml/log4j.dtd文件的内容;
        byte[] data1 = readResource("E:/apache-tomcat-6.0.18/webapps/ROOT", "log4j-1.2.16.jar:org/apache/log4j/xml/log4j.dtd");
        System.out.println("E:/apache-tomcat-6.0.18/webapps/ROOT/WEB-INF/lib/log4j-1.2.16.jar包里的org/apache/log4j/xml/log4j.dtd内容如下: ");
        System.out.println(new String(data1));
        System.out.println();
        System.out.println();
        
        //2.从classes路径读取配置文件内容:
        //假设存在文件: E:/apache-tomcat-6.0.18/webapps/ROOT/WEB-INF/classes/conf/log4j.properties,
        //你可以这样读出/conf/log4j.properties文件的内容;
        byte[] data2 = readResource("E:/apache-tomcat-6.0.18/webapps/ROOT", "/conf/log4j.properties");
        System.out.println("E:/apache-tomcat-6.0.18/webapps/ROOT/WEB-INF/classes/conf/log4j.properties的内容如下: ");
        System.out.println(new String(data2));
        
      }  /**
       * 从外部jar包或classes类路径下读取配置文件
       * @param applicationRootPath Web应用目录
       * @param className jar包及其资源文件相对路径或classes类路径下配置文件的相对路径
       * @return 配置文件的2进制内容
       */
      public static byte[] readResource(String applicationRootPath, String className)
      {
        String[] classNames = className.split(":");
        if (classNames[0].endsWith(".jar"))
        {
          if (classNames.length == 1)
          {
            String jarFilePath = applicationRootPath + File.separator + "WEB-INF" + File.separator + "lib" + File.separator + classNames[0];
            return readResourceOfFile(jarFilePath);
          }      String jarFilePath = applicationRootPath + File.separator + "WEB-INF" + File.separator + "lib" + File.separator + classNames[0];
          return readResourceFromJar(jarFilePath, classNames[1]);
        }    String classesFilePath = applicationRootPath + File.separator + "WEB-INF" + File.separator + "classes" + File.separator + classNames[0];
        return readResourceOfFile(classesFilePath);
      }  private static byte[] readResourceOfFile(String className)
      {
        byte[] arr_result = null;
        InputStream in = null;
        ByteArrayOutputStream fout = new ByteArrayOutputStream(8192);
        try
        {
          in = new FileInputStream(className);
          BufferedInputStream fin = new BufferedInputStream(in, 8192);      byte[] data = new byte[8192];
          int count = 0;      while (count >= 0)
          {
            count = fin.read(data);
            if (count > 0)
            {
              fout.write(data, 0, count);
            }
          }
          
          arr_result = fout.toByteArray();
        } catch (Exception e)
        {
          e.printStackTrace();
        } finally
        {
          if (in != null)try{in.close();} catch (Exception ex){}
          if (fout != null)try{fout.close();} catch (Exception ex){}
        }    return arr_result;
      }  private static byte[] readResourceFromJar(String jarFile, String className)
      {
        byte[] arr_result = null;
        try
        {
          ZipFile zipFile = new ZipFile(jarFile);
          try
          {
            ZipEntry zipEntry = zipFile.getEntry(className);
            if (zipEntry == null)return null;
            BufferedInputStream fin = new BufferedInputStream(zipFile.getInputStream(zipEntry), 8192);
            ByteArrayOutputStream fout = new ByteArrayOutputStream(8192);
            try
            {
              byte[] data = new byte[8192];
              int count = 0;          while (count >= 0)
              {
                count = fin.read(data);
                if (count > 0)
                {
                  fout.write(data, 0, count);
                }
              }
              arr_result = fout.toByteArray();
            } finally
            {
              fin.close();
              fout.close();
            }
          } finally
          {
            zipFile.close();
          }
        } catch (Exception e){}
        
        return arr_result;
      }
      
    }