java.io.FileNotFoundException although the file is

2020-02-15 14:50发布

问题:

i am trying to use ip2c to get country codes based on the ip of the user. Now the problem is it cannot find the binary file that it has to search. It throws the following ecxepion

java.io.FileNotFoundException: ip-to-country.bin (The system cannot find the file specified)
    at java.io.FileInputStream.open(Native Method)
    at java.io.FileInputStream.<init>(Unknown Source)
    at net.firefang.ip2c.input.RandomAccessBuffer.<init>(Unknown Source)
    at net.firefang.ip2c.IP2Country.<init>(Unknown Source)
    at net.firefang.ip2c.IP2Country.<init>(Unknown Source)
    at com.em.ss.controllers.CalendarController.postReminder(CalendarController.java:96)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.lang.reflect.Method.invoke(Unknown Source)
    at org.springframework.web.bind.annotation.support.HandlerMethodInvoker.invokeHandlerMethod(HandlerMethodInvoker.java:176)
    at org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter.invokeHandlerMethod(AnnotationMethodHandlerAdapter.java:427)
    at org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter.handle(AnnotationMethodHandlerAdapter.java:415)
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:788)
    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:717)
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:644)
    at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:549)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:621)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:722)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
    at com.em.ss.filter.GzipFilter.doFilter(GzipFilter.java:86)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
    at org.springframework.orm.jpa.support.OpenEntityManagerInViewFilter.doFilterInternal(OpenEntityManagerInViewFilter.java:113)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:76)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:224)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:169)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:168)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:98)
    at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:928)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:407)
    at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:987)
    at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:539)
    at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:298)
    at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(Unknown Source)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
    at java.lang.Thread.run(Unknown Source)

The file is in the base folder of the project and if I make a main function and create a file descriptor, it correctly finds the file and everything is good.

public static void main(String[] args) throws IOException
    {

        File file=new File("ip-to-country.bin");
        System.out.println(file.getCanonicalPath());
    }

But when i run my application, which is a spring mvc application and then ip2c cannot find the file. Here is how ip2c tries to look for it.

m_input = new MemoryMappedRandoeAccessFile(file, "r");

where file is simply the name of the bin file i.e ip-to-country.bin . I am totally stuck and have no idea whats the problem.

回答1:

You are clearly trying to access the file using a relative pathname. When you do this, the Java runtime system will attempt to find the file relative to the application's current directory. And the most likely reason it works in one scenario and not the other is the current directory is different in the two scenarios.

Try using an absolute pathname instead.



回答2:

In cases of "the server can't find the file, but it's there!" problems, this will solve it (always has for me):

File file = new File("somefilename");
System.out.println(file.getAbsolutePath());    

You will quickly discover that the directory where the server is looking isn't what you thought it was. Usually because the home directory isn't what you think it is.



回答3:

Spring MVC application probably run is some server - on contrary with main-function in class.

You root path would be different. You should put this file right next to WEB-INF folder. Should be located in a war folder. (If you have started from some good template)



回答4:

The File class is just wrapper for manipulating abstract filenames. This code

File file=new File("ip-to-country.bin");
System.out.println(file.getCanonicalPath());

not requres the file exist and executes normally. Use File.exists() method to check existence of file. As you trying to access file with relative path, make sure it located in current directory of running application. Probably it is not same folder as project root.