用JAVA把CSV文件导入SQL2005

skyfly2000 2008-02-19 04:37:48
我想用JAVA把CSV文件导入SQL2005
现在情况是这样的:我有几千个csv文件,一个文件就可以作为数据库中的一张表.
现在我需要用java程序把这几千个文件中的数据导入到数据库中的几千张表里.

CSV中的数据如下:(我拿其中一个文件给大家看看,其他的格式是一样的)
Time,Price,Volume,Open_Int,SP1,SV1,BP1,BV1,isBuy
2007-1-16 10:07:32,18180,2,650,18290,3,18180,2,0
2007-1-16 10:34:32,18150,2,648,18150,5,18150,1,0
2007-1-16 10:34:42,18150,10,638,0,0,18064,1,1
2007-1-16 13:34:59,18190,2,638,18190,4,18150,2,1
2007-1-16 13:36:19,18150,4,642,18150,3,18150,3,0
2007-1-16 13:37:34,18150,6,642,18190,4,18150,3,1
2007-1-16 13:44:56,18000,10,652,18000,3,17980,1,0
2007-1-16 13:50:24,18190,8,660,18190,2,18190,6,1
2007-1-16 13:50:25,18190,12,672,18190,22,18190,1,1
2007-1-16 14:36:02,18250,6,672,18350,5,18250,1,1
2007-1-16 14:44:52,18230,2,672,18300,2,18230,2,0
2007-1-16 14:50:46,18250,2,670,18340,2,18250,1,1
2007-1-16 14:51:19,18230,2,670,18370,2,18020,2,0

谁能帮忙写一个代码,谢谢了,就是把这个文件导入到数据库中的表中,表就在程序中建立吧.
先给100分,代码理解后,立刻结帖,分数不够再追加.
谢谢谢谢
...全文
889 16 打赏 收藏 转发到动态 举报
写回复
用AI写文章
16 条回复
切换为时间正序
请发表友善的回复…
发表回复
mashihou 2011-09-21
  • 打赏
  • 举报
回复
不错不错不错不错不错不错
keke_tang 2010-03-18
  • 打赏
  • 举报
回复
呵呵 我最近也实现这样的功能,呵呵 把我的给你参考下吧 我导入的是oracle,不过实现过程都一样

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.struts2.ServletActionContext;

import com.bonc.base.dao.PagiParam;
import com.bonc.dss.web.telecom.revenue.RevenueAction;
import com.runqian.base.util.upload.Request;
public class InputAction extends RevenueAction {
/**
* 长度数量,下面用于文件上传的读取长度
*/
private static final int FILE_SIZE = 16 * 1024;

/**
* 符号,下面用于得到系统路径符号
*/
private static final String sysMark=System.getProperty("file.separator");

private static final String SPECIAL_CHAR_A = "[^\",\\n  ]";

private static final String SPECIAL_CHAR_B = "[^\",\\n]";

/**
* 缓冲区读取对象
*/
private BufferedReader bufferedreader = null;

/**
* 上传的文件对象
* 注:在struts2中可以认为上传的文件被封装在这个对象中,
* 并且由于该对象无法获得上传文件的名字及类型,
* 所以下面使用到了其他2个属性:XXXFileName、XXXContentType
*/
private File upload;

/**
* 上传的文件
*/
private String uploadFileName;

/**
* 长度数量,下面用于文件上传的读取长度
*/
private String uploadContentType;

/**
* action入口方法
*/
public String execute() {

return SUCCESS;
}

public void upFile() {
//获得当前工程下文件上传目录的路径
String tpath = ServletActionContext.getServletContext().getRealPath("")+sysMark+ "document";

//实例目录文件夹对象
File file=new File(tpath);
//判断目录文件夹是否存在
if(!file.exists())
{
try {
//不存在,则创建
file.mkdir();
} catch (RuntimeException e) {
e.printStackTrace();
}
}
//得到拼接之后的上传文件名
String targetFileName=tpath+sysMark+(new Date().getTime())+this.getUploadFileName();
//实例得到目标文件对象
File targetFile=new File(targetFileName);

//传入上传源文件对象与目标源文件对象进行文件上传
boolean b=upLoadFile(this.getUpload(),targetFile);
if(b)
{
CsvReader(targetFileName);
}
}

/**
* 文件上传
* @param source
* @param target
* @return
*/
public boolean upLoadFile(File source, File target) {
//用于返回,标识上传是否成功
boolean flag=true;

//输入、输出流对象
InputStream in = null;
OutputStream out = null;

try {
//实例输入流获得指定大小的源文件
in = new BufferedInputStream(new FileInputStream(source), FILE_SIZE);
//实例输出流获得指定大小的目标文件
out = new BufferedOutputStream(new FileOutputStream(target),
FILE_SIZE);

//实例指定大小的字节数组对象
byte[] image = new byte[FILE_SIZE];
int len=-1;
//输入流循环读取指定字节数的源文件
while ((len=in.read(image))!= -1) {
//输入流循环输出指定字节数的目标文件
out.write(image,0,len);
}
} catch (IOException ex) {
//出现异常则上传失败
flag=false;
} finally {
//关闭输入、输出流
try {
if(out!=null)
{
in.close();
out.close();
}
} catch (IOException ex) {
ex.printStackTrace();
}
}
return flag;
}

public void CsvReader(String fileName){
//实例缓冲读取目标csv文件
try {
bufferedreader = new BufferedReader(new FileReader(fileName));
} catch (FileNotFoundException e) {
e.printStackTrace();
}
//获取正则表达式
String regExp = this.getRegExp();

//存放临时读取行对象
String stemp = null;

//单元格字符串
String str;
int i=0;

//循环读取文件的每一行
try {
while ((stemp = bufferedreader.readLine()) != null) {i++;
//通过正则表达式得到正则样式对象
Pattern pattern = Pattern.compile(regExp);

//通过正则样式对象得到每行的matcher对象
Matcher matcher = pattern.matcher(stemp);

// 每行记录一个list
List<String> cells = new ArrayList<String>();

// 读取每个单元格
while (matcher.find()) {
//得到单元格内容
str = matcher.group();
//过滤内容中的空格
str = str.trim();// 注意这里获取的子字符串是带分隔符的

//单元格内容后面包含逗号则需要去掉
if (str.endsWith(",")) {
str = str.substring(0, str.length() - 1);
str = str.trim();
}
/*
* 单元格内容前后都包含双引号则需要去掉,前后都需要处理
* 注意:如果csv单元格有双引号,则解析时会是3个引号,前后包围中间一个
* 过滤掉第一个引号之后还剩下2个引号,则需要替换成需要的内容即可
* 此处的过滤及替换可以进行要求变更
*/
if (str.startsWith("\"") && str.endsWith("\"")) {
str = str.substring(1, str.length() - 1);
if (this.isExisted("\"\"", str)) {
str = str.replaceAll("\"\"", "");
}
}
//判断过滤后的单元格内容,非空则添加到行数据集中
if (!"".equals(str)) {
System.out.print(str+" ");
}
}
System.out.println();
}
} catch (IOException e) {
e.printStackTrace();
}finally
{
try {
//关闭缓冲
if(bufferedreader!=null)
{
bufferedreader.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}System.out.println("**********"+i);
}

/**
* 正则表达式
* @return String
*/
private String getRegExp() {
//实例化得到动态字符串对象
StringBuffer strRegExps = new StringBuffer();

strRegExps.append("\"((");

strRegExps.append(SPECIAL_CHAR_A);

strRegExps.append("*[,\\n  ])*(");

strRegExps.append(SPECIAL_CHAR_A);

strRegExps.append("*\"{2})*)*");

strRegExps.append(SPECIAL_CHAR_A);

strRegExps.append("*\"[  ]*,[  ]*");

strRegExps.append("|");

strRegExps.append(SPECIAL_CHAR_B);

strRegExps.append("*[  ]*,[  ]*");

strRegExps.append("|\"((");

strRegExps.append(SPECIAL_CHAR_A);

strRegExps.append("*[,\\n  ])*(");

strRegExps.append(SPECIAL_CHAR_A);

strRegExps.append("*\"{2})*)*");

strRegExps.append(SPECIAL_CHAR_A);

strRegExps.append("*\"[  ]*");

strRegExps.append("|");

strRegExps.append(SPECIAL_CHAR_B);

strRegExps.append("*[  ]*");

return strRegExps.toString();
}

/**
* 检索比对
* @param argChar
* @param argStr
* @return
*/
private boolean isExisted(String argChar, String argStr) {
//判断的boolean对象
boolean blnReturnValue = false;
//检索被检索字符串中是否包含检索字符串
if ((argStr.indexOf(argChar) >= 0)
&& (argStr.indexOf(argChar) <= argStr.length())) {
blnReturnValue = true;
}
return blnReturnValue;
}

public File getUpload() {
return upload;
}

public void setUpload(File upload) {
this.upload = upload;
}

public String getUploadFileName() {
return uploadFileName;
}

public void setUploadFileName(String uploadFileName) {
this.uploadFileName = uploadFileName;
}

public String getUploadContentType() {
return uploadContentType;
}

public void setUploadContentType(String uploadContentType) {
this.uploadContentType = uploadContentType;
}
}
whoisme123 2009-12-07
  • 打赏
  • 举报
回复
学习啊
skyfly2000 2008-04-29
  • 打赏
  • 举报
回复
谢谢,今天总算完成了把数据倒入数据库的工作
马上结帖
再次感谢两位的热心回答
olivesoup 2008-02-21
  • 打赏
  • 举报
回复
没关系,解决问题,互相学习要紧

很多初学者都喜欢用StringTokenizer,
StringTokenizer 是出于兼容性的原因而被保留的遗留类(虽然在新代码中并不鼓励使用它),
建议所有寻求此功能的人使用 String 的 split 方法或 java.util.regex 包。
skyfly2000 2008-02-21
  • 打赏
  • 举报
回复
olivesoup,老紫竹没有去那里,那我那个帖子的分数都给你了吧,这里的分数就不给你了,望理解哦.
:)
skyfly2000 2008-02-21
  • 打赏
  • 举报
回复
split效率高么?split的用法没看到过
我想到的思路是用StringTokenizer类来分割语言符号,然后依次输入

还有老紫竹的StringBuilder类也没看到过,我看的只是一本初中级教材
呵呵,得多来请教各位了.
:)
wdman 2008-02-20
  • 打赏
  • 举报
回复
解析CSV文件的话,不能通过split来做,也许数据里本身就有逗号引号什么的.
skyfly2000 2008-02-20
  • 打赏
  • 举报
回复
豁然开朗
现在在考虑是多线程的效率高还是直接用遍历的效率高

PS:老紫竹前辈,方便的话移步另外个帖子,我把分数给两位.
地址是:http://topic.csdn.net/u/20080219/04/162979c4-d90d-4b3f-890e-57d71ea25f47.html
olivesoup 2008-02-20
  • 打赏
  • 举报
回复
>for(String s : parts)这种语句我看不懂,是不是遍历?
是遍历,是jdk1.5引入的增强型for循环,他等同于以前的
for(int i = 0; i < parts.length; i++){
}

就是每次从数组parts中拿出一个String s,直到全部拿完结束
skyfly2000 2008-02-20
  • 打赏
  • 举报
回复
感谢两位
这个帖子先不结束,有问题我继续问

但为了承诺给分,请两位到http://topic.csdn.net/u/20080219/04/162979c4-d90d-4b3f-890e-57d71ea25f47.html这个帖子里去回个帖.那里有100分,我先把那个帖子结了,把分给两位.谢谢哦.
这个帖子等我目前这个连接什么的成功了后再请教


另外,for (String s : parts)这种语句我看不懂,是不是遍历?我没学过遍历,也看不懂这样的语法.呵呵要是不忙马还请指点一二哦
老紫竹 2008-02-20
  • 打赏
  • 举报
回复
多线程可以,不过这样主键(ID)建议设置为自动增加了,否则处理起来难度稍微高一点。稍微。呵呵!

性能问题可以参考这个 http://www.java2000.net/viewthread.jsp?tid=370
老紫竹 2008-02-20
  • 打赏
  • 举报
回复
你不会拼SQL吗?

    String[] parts = line.split(",");
StringBuilder b = new StringBuilder();
b.append("insert into myTable(id,name,address,phone) values (");
for (String s : parts) {
b.append("'" + s + "',");
}
b.deleteCharAt(b.length() - 1);
b.append(")");
String sql = b.toString();


生成的效果如下
insert into myTable(id,name,address,phone) values ('1','java2000.net','天津','不告诉你')


怎么执行,我们就不管了!你也不要再问怎么执行了。嘿嘿!!!

olivesoup 2008-02-19
  • 打赏
  • 举报
回复
方法老紫竹已经说的很明白了,我就把关键部分的代码写了一下,根据你自己的要求再修改一下就行

private static void readCSV() throws IOException {
File[] files = new File("D:\\csvfile").listFiles();//到目录下取文件
BufferedReader br = null;
try {
for (File file : files) {//遍历所有文件
if (!file.isFile()) {//如果不是文件则跳过
continue;
}
br = new BufferedReader(new InputStreamReader(
new FileInputStream(file)));//获得文件流
String line = null;
while ((line = br.readLine()) != null) {//读取一行
// inserDb(line.split(","));//将这一行插入db
}
}
} finally {
if (br != null) {
br.close();
}
}
}
skyfly2000 2008-02-19
  • 打赏
  • 举报
回复
inserDb(line.split(","));

请问这一句具体怎么实施呢
我想在程序中自己建立数据库中的表,字段名也在程序中建立,用SQL语句(这个应该没问题,用JDBC连接应该可以)
然后就是读取了文件中的内容,再插入数据库中的表中,这个过程我写不出来.
楼上的写的程序这里我也看不懂,能否多指点一二?谢谢了哦

至于遍历文件,我想是不是用多线程来做会效率比较高呢,毕竟都是同样的操作.
老紫竹 2008-02-19
  • 打赏
  • 举报
回复
我只能提供思路,没时间替你编码!

1 循环打开文件
2 循环读取文件的每一行,舍弃第一行,如果那行是表头的话
3 用 String[] parts = line.split(","); 拆分行为各个字段
4 拼装SQL语句,唯一注意的是日期字段,如果是SQLServer 就没问题,Oracle不行,需要to_date
5 插入数据库
6 循环下一行,直到文件结束
7 循环下一个文件,直到完成

62,614

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧