java.io.FileNotFoundException, хотя файл присутствует

я пытаюсь использовать ip2c для получения кодов стран на основе IP-адреса пользователя. Теперь проблема в том, что он не может найти двоичный файл, который он должен искать. Он выдает следующий 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)

Файл находится в базовой папке проекта, и если я делаю основную функцию и создаю файловый дескриптор, он правильно находит файл и все хорошо.

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

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

Но когда я запускаю свое приложение, которое является приложением spring mvc, а затем ip2c не может найти файл. Вот как ip2c пытается его найти.

m_input = новый MemoryMappedRandoeAccessFile (файл, «r»);

где файл — это просто имя bin-файла, то есть ip-to-country.bin . Я полностью застрял и понятия не имею, в чем проблема.


person Khizar    schedule 01.03.2012    source источник


Ответы (4)


Вы явно пытаетесь получить доступ к файлу, используя относительный путь. Когда вы сделаете это, исполняющая система Java попытается найти файл относительно текущего каталога приложения. И наиболее вероятная причина, по которой он работает в одном сценарии, а не в другом, заключается в том, что текущий каталог отличается в двух сценариях.

Вместо этого попробуйте использовать абсолютный путь.

person Stephen C    schedule 01.03.2012
comment
я не могу изменить код, он в банке, которую я использую. Ему нужен этот двоичный файл, и я должен поместить его куда-нибудь в свой проект, где к нему можно получить доступ как есть, и я не уверен, где :( - person Khizar; 02.03.2012
comment
Простой. Краткосрочное исправление состоит в том, чтобы определить текущий каталог и поместить туда файл. Долгосрочное исправление состоит в том, чтобы получить исходный код для этого JAR и изменить его, чтобы избавиться от зашитого пути. (И если вы не можете, ищите лучшего поставщика. Запрограммированные имена путей — явный признак низкого качества продукта.) - person Stephen C; 02.03.2012
comment
хорошо, большое спасибо, я надеялся получить решение, которое не связано с этим, но я думаю, что это единственное решение, поэтому я приму этот ответ :) - person Khizar; 02.03.2012

В случаях "сервер не может найти файл, но он есть!" проблемы, это решит это (всегда для меня):

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

Вы быстро обнаружите, что каталог, в который смотрит сервер, не тот, о котором вы думали. Обычно потому, что домашний каталог — это не то, что вы думаете.

person Bohemian♦    schedule 01.03.2012
comment
Большое спасибо, приятель, но странно, что он ищет в каталоге eclipse C:\development\eclipse\ip-to-country.bin. Учитывая, что это веб-проект, я подумал, что он будет искать в папке WebContent или что-то в этом роде. Теперь я не могу изменить код, который jar использует для предоставления абсолютного пути, так есть ли способ как-то изменить домашний каталог, чтобы он нашел файл? - person Khizar; 02.03.2012

Приложение Spring MVC, вероятно, запускается на каком-то сервере - в отличие от основной функции в классе.

Ваш корневой путь будет другим. Вы должны поместить этот файл рядом с папкой WEB-INF. Должен находиться в папке war. (Если вы начали с какого-то хорошего шаблона)

person Hurda    schedule 01.03.2012

Класс File — это просто оболочка для управления абстрактными именами файлов. Этот код

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

не требует, чтобы файл существовал и выполнялся нормально. Используйте метод File.exists() для проверки существования файла. Когда вы пытаетесь получить доступ к файлу с относительным путем, убедитесь, что он находится в текущем каталоге запущенного приложения. Вероятно, это не та же папка, что и корень проекта.

person Mersenne    schedule 01.03.2012
comment
Я пробовал это, я пробовал канонический путь, чтобы увидеть, находится ли он в той папке, о которой я думаю. - person Khizar; 02.03.2012