解决FileUtils.copyURLToFile请求失效URL时无限阻塞问题
解决NSE股价数据获取中URL失效导致的阻塞问题
我用Java程序从NSE网站获取股价数据,示例代码如下:
url = new URL("https://archives.nseindia.com/archives/equities/bhavcopy/pr/PR071122.zip"); f = new File("NSEData.zip"); try { FileUtils.copyURLToFile(url, f); } catch (Exception e) { }
这段代码在有市场数据的日期(比如07/11/22)能正常运行,但在无数据的日期(比如08/11/22),对应的URL失效,导致FileUtils.copyURLToFile方法无限阻塞。目前我通过判断DayOfWeek排除周末,并用HashSet存储公共节假日来排查,但这个方案不够完善,想找简便方法识别失效URL,跳过try块继续执行,避免阻塞。
方案1:给FileUtils.copyURLToFile设置超时时间
FileUtils.copyURLToFile提供了带超时参数的重载方法,设置连接和读取超时后,一旦URL失效或请求超时,会抛出IOException,直接进入catch块处理,不会无限阻塞:
URL url = new URL("https://archives.nseindia.com/archives/equities/bhavcopy/pr/PR081122.zip"); File f = new File("NSEData.zip"); try { // 连接超时5秒,读取超时10秒,可根据网络情况调整 FileUtils.copyURLToFile(url, f, 5000, 10000); } catch (IOException e) { // URL失效或超时,直接跳过 System.out.println("该日期无数据或请求超时,跳过"); }
方案2:先发送HEAD请求验证URL有效性
在执行下载前,先发送HEAD请求获取响应状态码,只有当状态码为200(HTTP_OK)时才执行下载,避免无效的下载请求:
URL url = new URL("https://archives.nseindia.com/archives/equities/bhavcopy/pr/PR081122.zip"); HttpURLConnection connection = (HttpURLConnection) url.openConnection(); connection.setRequestMethod("HEAD"); connection.setConnectTimeout(5000); connection.setReadTimeout(5000); try { int responseCode = connection.getResponseCode(); if (responseCode == HttpURLConnection.HTTP_OK) { // URL有效,执行下载 FileUtils.copyURLToFile(url, new File("NSEData.zip")); } else { // URL无效,跳过 System.out.println("该日期无数据,跳过"); } } catch (IOException e) { System.out.println("请求失败,跳过"); } finally { connection.disconnect(); }
HEAD请求仅获取响应头,不下载文件,能快速判断URL是否有效,节省带宽和时间。
方案3:结合日期判断+超时机制(优化现有方案)
把你现有的周末、节假日判断和超时/HEAD验证结合,先过滤掉大概率无数据的日期,再对剩余日期做网络验证,减少无效请求:
LocalDate date = LocalDate.of(2022, 11, 8); // 先判断是否是周末 if (date.getDayOfWeek() == DayOfWeek.SATURDAY || date.getDayOfWeek() == DayOfWeek.SUNDAY) { System.out.println("周末无数据,跳过"); return; } // 判断是否是节假日 Set<LocalDate> holidays = new HashSet<>(); holidays.add(LocalDate.of(2022, 11, 8)); // 示例节假日,可按需扩展 if (holidays.contains(date)) { System.out.println("节假日无数据,跳过"); return; } // 再带超时执行下载 URL url = new URL("https://archives.nseindia.com/archives/equities/bhavcopy/pr/PR081122.zip"); File f = new File("NSEData.zip"); try { FileUtils.copyURLToFile(url, f, 5000, 10000); } catch (IOException e) { System.out.println("该日期无数据或请求失败,跳过"); }
这种方式既能减少不必要的网络请求,又能兜底处理遗漏的节假日或临时休市情况。
内容的提问来源于stack exchange,提问作者Vebby
相关产品推荐
相关产品推荐

