我想用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分,代码理解后,立刻结帖,分数不够再追加.
谢谢谢谢

解决方案 »

  1.   

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

  2.   

    方法老紫竹已经说的很明白了,我就把关键部分的代码写了一下,根据你自己的要求再修改一下就行    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();
                }
            }
        }
      

  3.   

    inserDb(line.split(","));请问这一句具体怎么实施呢
    我想在程序中自己建立数据库中的表,字段名也在程序中建立,用SQL语句(这个应该没问题,用JDBC连接应该可以)
    然后就是读取了文件中的内容,再插入数据库中的表中,这个过程我写不出来.
    楼上的写的程序这里我也看不懂,能否多指点一二?谢谢了哦至于遍历文件,我想是不是用多线程来做会效率比较高呢,毕竟都是同样的操作.
      

  4.   

    你不会拼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','天津','不告诉你')怎么执行,我们就不管了!你也不要再问怎么执行了。嘿嘿!!!
      

  5.   

    多线程可以,不过这样主键(ID)建议设置为自动增加了,否则处理起来难度稍微高一点。稍微。呵呵!性能问题可以参考这个 http://www.java2000.net/viewthread.jsp?tid=370
      

  6.   

    感谢两位
    这个帖子先不结束,有问题我继续问但为了承诺给分,请两位到http://topic.csdn.net/u/20080219/04/162979c4-d90d-4b3f-890e-57d71ea25f47.html这个帖子里去回个帖.那里有100分,我先把那个帖子结了,把分给两位.谢谢哦.
    这个帖子等我目前这个连接什么的成功了后再请教
    另外,for (String s : parts)这种语句我看不懂,是不是遍历?我没学过遍历,也看不懂这样的语法.呵呵要是不忙马还请指点一二哦
      

  7.   

    >for(String s : parts)这种语句我看不懂,是不是遍历?
    是遍历,是jdk1.5引入的增强型for循环,他等同于以前的
    for(int i = 0; i < parts.length; i++){
    }就是每次从数组parts中拿出一个String s,直到全部拿完结束
      

  8.   

    豁然开朗
    现在在考虑是多线程的效率高还是直接用遍历的效率高PS:老紫竹前辈,方便的话移步另外个帖子,我把分数给两位.
    地址是:http://topic.csdn.net/u/20080219/04/162979c4-d90d-4b3f-890e-57d71ea25f47.html
      

  9.   

    解析CSV文件的话,不能通过split来做,也许数据里本身就有逗号引号什么的.
      

  10.   

    split效率高么?split的用法没看到过
    我想到的思路是用StringTokenizer类来分割语言符号,然后依次输入还有老紫竹的StringBuilder类也没看到过,我看的只是一本初中级教材
    呵呵,得多来请教各位了.
    :)
      

  11.   

    olivesoup,老紫竹没有去那里,那我那个帖子的分数都给你了吧,这里的分数就不给你了,望理解哦.
    :)
      

  12.   

    没关系,解决问题,互相学习要紧很多初学者都喜欢用StringTokenizer,
    StringTokenizer 是出于兼容性的原因而被保留的遗留类(虽然在新代码中并不鼓励使用它),
    建议所有寻求此功能的人使用 String 的 split 方法或 java.util.regex 包。
      

  13.   

    呵呵   我最近也实现这样的功能,呵呵  把我的给你参考下吧  我导入的是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;
    }
    }