定时从远程FTP服务器下载txt文件并导入本地Oracle数据库
(最近发现一款不错FTP服务器批量管理工具,推荐一下)
工具:FTP客户端-IIS7服务器管理工具
简介:作为FTP客户端,它支持批量管理ftp站点
官网地址:http://fwqglgj.iis7.net/cp/ftp/?cmc-zc 使用截图如下
具体功能:
定时上传和定时下载,定时备份,且操作简洁
iis7服务器管理工具还是vnc客户端
支持批量管理管理windows及linux服务器、vps
让服务器真正实现了一站式管理,真的是非常方便。
附两张使用截图:
下面说一下我自己的类似功能实现,从远程FTP服务器上定时获取txt数据文件,并将数据导入到本地Oracle数据库。
每天需要从FTP下载的txt文件有40-50个,除第一次全量数据文件在10G左右较大、下载耗时较长外,后续的增量文件都在500M以内。
需要使用到的技术、工具:FTPClient、Java多线程、Oracle提供的sqlldr命令、Oracle提供Merge、spring的quartz定时包、EXTJS前台框架。
功能模块的具体流程在此不做详细介绍,主要记录在实现过程中遇到的问题以及解决办法:
下载文件:1、使用多线程从FTP下载文件时,需要每个线程开启一个新的FTPClient,否则会出现FTP拒绝连接、链接超时等问题。
2、使用FTPClient的storeFile(remote, local)方法时,超过一定数量的文件之后就会出现程序阻塞、假死的现象,找了很多解决方案都不行,后来采用FTPClient的retrieveFileStream(remote)方法获取输入流手动循环read()保存txt文件之后,不存在假死、阻塞现象。以下为下载代码:
1 public void run() { 2 try { 3 //ftp.enterLocalPassiveMode(); 切换到本地模式 4 ftp.setFileType(FTP.ASCII_FILE_TYPE); 5 6 File dirFile = new File(dir); 7 8 if(!dirFile.exists()){ 9 dirFile.mkdirs(); 10 } 11 File localFile = new File(dir+localFileName); 12 13 OutputStream os = new FileOutputStream(localFile); 14 15 InputStream is = ftp.retrieveFileStream(ftpFileName); 16 17 BufferedReader br = new BufferedReader(new InputStreamReader(is, "UTF-8")); 18 19 BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(os, "GBK")); 20 21 int read = br.read(); 22 while(read!= -1){ 23 bw.write(read); 24 read = br.read(); 25 } 26 br.close(); 27 is.close(); 28 bw.flush(); 29 bw.close(); 30 os.close(); 31 //ftp.completePendingCommand(); 32 end = System.currentTimeMillis(); 33 34 //日志记录 35 36 } catch (IOException e) { 37 //日志记录 38 e.printStackTrace(); 39 } 40 }
执行sqlldr命令:
1、解决每张表的字段都存在需要格式化的转换,所以通过每张表在文件系统中建立一个txt文件用来存取表头字段信息,字段信息将用于生成sqlldr所需的ctl文件,表头字段信息描述txt文件内容如下:
id,bill_no,bill_type,status,biz_type,ref_bill_no,ref_bill_type,ref_biz_type,company_no,order_unit_no,order_unit_name,sys_no,supplier_no,supplier_name,store_no,store_name,order_no,contract_no,invoice_no,send_out_date date 'YYYY-MM-DD HH24:MI:SS' ,tax_rate,merchandiser,create_user,create_time timestamp 'YYYY-MM-DD HH24:MI:SS' ,auditor,audit_time timestamp 'YYYY-MM-DD HH24:MI:SS.ff9' ,remark,update_time timestamp 'YYYY-MM-DD HH24:MI:SS' ,trans_no,send_detail_total,zone_yyyymm,sharding_flag,is_imported,yw_update_time timestamp 'YYYY-MM-DD HH24:MI:SS' |
sqlldr支持的具体转换格式可自行在网上查询。
2、sqlldr所需ctl文件内容格式:
load data characterset ZHS16GBK infile '数据文件位置' --可以是txt、csv... append into table '需导入的表名' fields terminated by '' --字段值之间的分隔字符,此处为\u0001 trailing nullcols 空字段自动赋值了null值 ("表头字段名称,名称之间用‘,’号隔开,存在格式转换的需要在字段名后追加转换格式....")
3、生成sqlldr命令:
sqlldr 数据库用户名+"/"+数据库密码+"@"+数据库服务名); control='...' //控制文件绝对路径 bad='...' //异常数据文件保存路径 log='...' //log文件保存路径 parallel=true //并行 errors=0 //允许的错误行数 rows=5000 //5000行提交一次 skip=1 //跳过数据文件的第一行 bindsize=10000000 readsize=10000000 //缓存区大小
4、开启多线程在命令行中执行sqlldr命令:
(待续)
【推荐】还在用 ECharts 开发大屏?试试这款永久免费的开源 BI 工具!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步