`
周凡杨
  • 浏览: 234626 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

BufferedOutputStream

阅读更多
     首先说一下这个大批量,是指有上千万的数据量。
     例子:
     有一张短信历史表,其数据有上千万条数据,要进行数据备份到文本文件,就是执行如下SQL然后将结果集写入到文件中!
     select t.msisdn,t.source,t.seq,t.area,t.send_date,t.msg,t.optcode from   hnsms.SMS_SEND_10086_HIS_102 t
     数据库:Oracle
    
   下面主要列一下我写文件操作的不同实现方法,及运行结果:
第一种:-----------------------------------------------------------------------------
 
      package wap.ftp;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import wap.util.PublicUtil;

public class FileWriteTest {

private Connection conn_a = null;
private PreparedStatement pstmt_a = null;
private ResultSet rs_a = null;


private String FilePath = "";
private File fileName = null;
private FileWriter writer;
private PrintWriter pw;
private String fileAllPath = "";

Map map = new HashMap();

public void init(){
    try {
    Class.forName("oracle.jdbc.driver.OracleDriver");
  
        map = PublicUtil.readConfigFile();
       
        conn_a = DriverManager.getConnection((String)map.get("URL"),(String)map.get("USERNAME"),(String)map.get("PASSWORD"));
       
        FilePath = PublicUtil.readServerPath();
    } catch (Exception e) {
e.printStackTrace();
}
   
  }

/**
* 读取数据库表内容 并生成文件 把数据写到文件中
*/
public void  readDataToFile(){
long totalStart = System.currentTimeMillis();
init();
try {
    Date date = new Date();
    SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
    //SimpleDateFormat sdf2 = new SimpleDateFormat("yyyy/MM/dd HH:mm");
    String nowDateStr = sdf.format(date);
    fileAllPath  = FilePath+nowDateStr+".txt";
    fileName = new File(fileAllPath);
  
    try {
writer = new FileWriter(fileAllPath);
pw=new PrintWriter(writer);
} catch (IOException e) {
e.printStackTrace();
}
//createFile("");

//读配置文件--取SQL
String sql_a= (String)map.get("SQL");
System.out.println(sql_a);
pstmt_a = conn_a.prepareStatement(sql_a);
rs_a = pstmt_a.executeQuery();

    int num = 0;            //记录写文件写了多少行
        while(rs_a.next()){
        long startTime = System.currentTimeMillis();
        String size = (String)map.get("SIZE");
            String s = "";
        for(int i=1;i<=Integer.parseInt(size);i++){
           s  += rs_a.getString(i)+"|";
        }
        s = s.substring(0, s.length()-1);
        createFile(s);
        num++;
        long endTime = System.currentTimeMillis();
        System.out.println("写入文件第"+num+"行,耗时"+(endTime-startTime)+"毫秒.");
       
        }
       
} catch (SQLException e) {
e.printStackTrace();
}finally{
finish();    //关闭输入流
closeDB();
}

long totalEnd = System.currentTimeMillis();
System.out.println("-----总耗时:"+(totalEnd-totalStart)+"毫秒");
}

public void createFile(String s){
pw.println(s);
}

public void finish(){//关闭输入流,将文字从缓存写入文件
try{
writer.close();
}catch (IOException iox){
    System.err.println(iox);
    }
}

public void closeDB(){  //关闭数据库连接
if(rs_a!=null){
try {
rs_a.close();
} catch (SQLException e) {
e.printStackTrace();
}finally{
if(pstmt_a!=null){
try {
pstmt_a.close();
} catch (SQLException e) {
e.printStackTrace();
}finally{
if(conn_a!=null){
try {
conn_a.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
}

}
}
}
主要是通过FileWriter + PrintWriter 实现文件数据的写操作!
第二种-------------------------------------------------------------------------------------
package wap.ftp;

import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import wap.util.PublicUtil;

public class BuffOutPutStreamTest {

private Connection conn_a = null;
private PreparedStatement pstmt_a = null;
private ResultSet rs_a = null;


private String FilePath = "";
private File fileName = null;
private FileOutputStream fos;
private BufferedOutputStream bos;
private String fileAllPath = "";

Map map = new HashMap();

public void init(){
    try {
    Class.forName("oracle.jdbc.driver.OracleDriver");
  
        map = PublicUtil.readConfigFile();
       
        conn_a = DriverManager.getConnection((String)map.get("URL"),(String)map.get("USERNAME"),(String)map.get("PASSWORD"));
       
        FilePath = PublicUtil.readServerPath();
    } catch (Exception e) {
e.printStackTrace();
}
   
  }

/**
* 读取数据库表内容 并生成文件 把数据写到文件中
*/
public void  readDataToFile(){
long totalStart = System.currentTimeMillis();
init();
try {
    Date date = new Date();
    SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
    SimpleDateFormat sdf2 = new SimpleDateFormat("yyyy/MM/dd HH:mm");
    String nowDateStr = sdf.format(date);
    fileAllPath  = FilePath+nowDateStr+".txt";
    fileName = new File(fileAllPath);
  
    try {
fos = new FileOutputStream(fileName);
bos = new BufferedOutputStream(fos);
} catch (IOException e) {
e.printStackTrace();
}
createFile("");

//读配置文件--取SQL
String sql_a= (String)map.get("SQL");
System.out.println(sql_a);
pstmt_a = conn_a.prepareStatement(sql_a);
rs_a = pstmt_a.executeQuery();

    int num = 0;            //记录写文件写了多少行
        while(rs_a.next()){
        long startTime = System.currentTimeMillis();
        String size = (String)map.get("SIZE");
            String s = "";
        for(int i=1;i<=Integer.parseInt(size);i++){
           s  += rs_a.getString(i)+"|";
        }
        s = s.substring(0, s.length()-1);
        createFile(s);
        num++;
        long endTime = System.currentTimeMillis();
        System.out.println("写入文件第"+num+"行,耗时"+(endTime-startTime)+"毫秒.");
        
        if(num>=1000000){
        break;
        }
        //-----------定量清缓存一次,如果数据量大(上百万),请开启这个机制
        if(num%100000==0){
        System.out.println("===============清缓存一次===========");
        try {
bos.flush();
} catch (IOException e) {
e.printStackTrace();
}
        }
        //-----------清缓存机制 end--------------------------------------
        }
       
} catch (SQLException e) {
e.printStackTrace();
}finally{
finish();    //关闭输入流
closeDB();
}

long totalEnd = System.currentTimeMillis();
System.out.println("----总耗时:"+(totalEnd-totalStart)+"毫秒");
}

public void createFile(String s){
try {
bos.write(s.getBytes());
} catch (IOException e) {
e.printStackTrace();
}
}

public void finish(){//关闭输入流,将文字从缓存写入文件
try{
bos.flush();
bos.close();
fos.close();
}catch (IOException iox){
    System.err.println(iox);
    }
}

public void closeDB(){  //关闭数据库连接
if(rs_a!=null){
try {
rs_a.close();
} catch (SQLException e) {
e.printStackTrace();
}finally{
if(pstmt_a!=null){
try {
pstmt_a.close();
} catch (SQLException e) {
e.printStackTrace();
}finally{
if(conn_a!=null){
try {
conn_a.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
}

}
}
}
   主要用BufferedOutputStream的缓冲机制
第三种:-----------------------------------------------------------------------------
package wap.ftp;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import wap.util.PublicUtil;

public class FileWriteBufferTest {

private Connection conn_a = null;
private PreparedStatement pstmt_a = null;
private ResultSet rs_a = null;


private String FilePath = "";
private File fileName = null;
private FileWriter writer;
private PrintWriter pw;
private String fileAllPath = "";

Map map = new HashMap();

public void init(){
    try {
    Class.forName("oracle.jdbc.driver.OracleDriver");
  
        map = PublicUtil.readConfigFile();
       
        conn_a = DriverManager.getConnection((String)map.get("URL"),(String)map.get("USERNAME"),(String)map.get("PASSWORD"));
       
        FilePath = PublicUtil.readServerPath();
    } catch (Exception e) {
e.printStackTrace();
}
   
  }

/**
* 读取数据库表内容 并生成文件 把数据写到文件中
*/
public void  readDataToFile(){
long totalStart = System.currentTimeMillis();
init();
try {
    Date date = new Date();
    SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
    SimpleDateFormat sdf2 = new SimpleDateFormat("yyyy/MM/dd HH:mm");
    String nowDateStr = sdf.format(date);
    fileAllPath  = FilePath+nowDateStr+".txt";
    fileName = new File(fileAllPath);
  
    try {
writer = new FileWriter(fileAllPath);
pw=new PrintWriter(new BufferedWriter(writer));
} catch (IOException e) {
e.printStackTrace();
}
createFile("");

//读配置文件--取SQL
String sql_a= (String)map.get("SQL");
System.out.println(sql_a);
pstmt_a = conn_a.prepareStatement(sql_a);
rs_a = pstmt_a.executeQuery();

    int num = 0;            //记录写文件写了多少行
        while(rs_a.next()){
        long startTime = System.currentTimeMillis();
        String size = (String)map.get("SIZE");
            String s = "";
        for(int i=1;i<=Integer.parseInt(size);i++){
           s  += rs_a.getString(i)+"|";
        }
        s = s.substring(0, s.length()-1);
        createFile(s);
        num++;
        long endTime = System.currentTimeMillis();
        System.out.println("写入文件第"+num+"行,耗时"+(endTime-startTime)+"毫秒.");
 
               if(num>=1000000){
        break;
        }      
        
          //-----------定量清缓存一次,如果数据量大(上百万),请开启这个机制
        /* if(num%300000==0){
        try {
pw.flush();
} catch(Exception e) {
e.printStackTrace();
}
        }*/
          //-----------清缓存机制 end--------------------------------------
        }
       
} catch (SQLException e) {
e.printStackTrace();
}finally{
finish();    //关闭输入流
closeDB();
}

long totalEnd = System.currentTimeMillis();
System.out.println("----总耗时:"+(totalEnd-totalStart)+"毫秒");
}

public void createFile(String s){
pw.println(s);
}

public void finish(){//关闭输入流,将文字从缓存写入文件
try{
pw.flush();
writer.close();
}catch (IOException iox){
    System.err.println(iox);
    }
}

public void closeDB(){  //关闭数据库连接
if(rs_a!=null){
try {
rs_a.close();
} catch (SQLException e) {
e.printStackTrace();
}finally{
if(pstmt_a!=null){
try {
pstmt_a.close();
} catch (SQLException e) {
e.printStackTrace();
}finally{
if(conn_a!=null){
try {
conn_a.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
}

}
}
}
主要用的是FileWriter(加缓冲)的机制。
------------------------------------------------------------------------------
在写不同量的数据的情况下运行结果:
        /*   当只写数据为100000条时(取三次结果): 
*         fileWriter:          总耗时:30500、26250、25078毫秒
*         fileWriter(加缓冲):  总耗时:23781、20875、20688毫秒
*         OutputStreamBuffer:  总耗时:21157、23094、22484毫秒
*
*   当只写数据为1000000条时(取三次结果): 
*         fileWriter:          总耗时:213844、218250、216985毫秒
*         fileWriter(加缓冲):  总耗时:249672、238094、207203毫秒
*         OutputStreamBuffer:  总耗时:239563、234234、229829毫秒
         *   发现当写数据量为10万时,加缓冲机制的写数据效率更高些!当写数据量达到100万时
         *   加缓冲机制的写数据效率反倒低了,我想因为是数据放入缓存>再从缓存写入文件当数据
         *   量大时,这个额外的开销就会加大,反而对整体写数据影响会大。
         *   那我就在想如果定量的清缓存,是不是会效率高些呢?
*   -----------------------------------------------------------------
*   当只写数据为1000000条时(取三次结果)
*   启动定时将缓存中的数据写入文件:(每20万就清缓存一次)
*         fileWriter(加缓冲):  总耗时:232875 毫秒
*         OutputStreamBuffer:  总耗时:229172、216594、234421毫秒
*
*   当只写数据为1000000条时(取三次结果)
*   启动定时将缓存中的数据写入文件:(每10万就清缓存一次)
*         fileWriter(加缓冲):  总耗时: 毫秒
*         OutputStreamBuffer:  总耗时:227156、224047、210891毫秒
*
*   当只写数据为1000000条时(取三次结果)
*   启动定时将缓存中的数据写入文件:(每30万就清缓存一次)
*         fileWriter(加缓冲): 总耗时:248735、213172毫秒
*         OutputStreamBuffer:  总耗时:224703、235828、220765毫秒
*        
*    ---------------------------------------------------------------
*    总的来说,100万数据时,需要约3.5分钟   1000万需要40分钟,如果表没有索引,
*    会需要更长时间  
*    而且,如果要写的数据小于百万时,调缓冲的会好些!
*    如果数据量上百万,若要调缓冲,请开启定量清缓冲机制
* @param args
*/

总结,当然我这个测试只是去验证三种写文件方式的机制的在不同数据量时的效率问题!
如果想更快的去完成上千万数量的写操作,最好是启多个线程去操作,这样可以解决时间问题
但要注意数据库连接的释放,要不对数据库是有影响的,特别是我拿的生产数据库测试的。

打完收工。
分享到:
评论

相关推荐

    BufferedOutputStream 介绍_动力节点Java学院整理

    BufferedOutputStream 是缓冲输出流。它继承于FilterOutputStream。 BufferedOutputStream 的作用是为另一个输出流提供“缓冲功能”。

    BufferedOutputStream的用法---马克-to-win java视频

    BufferedOutputStream的用法---马克-to-win java视频 缓存输出流

    BufferedOutputStream.html

    java的BufferedOutputStream,开发过程中使用字符流,效率提高。字符流很好,初学者要分清字符流和字节流

    jdk api-BufferedOutputStream基础、应用、实战

    jdk api-BufferedOutputStream基础、应用、实战

    java算法,实现压缩及解压缩

    import java.io.BufferedOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.util.zip.ZipEntry; import java.util.zip.ZipOutputStream; ``` ...

    BufferedOutputStream与BufferedInputStream

    在Java I/O流处理中,`BufferedOutputStream` 和 `BufferedInputStream` 是两种非常重要的类,它们分别属于字节缓冲输出流和字节缓冲输入流。这两个类都是为了提高I/O操作的效率,通过在实际操作底层流之前,先将...

    Java导出txt文件的方法

    BufferedOutputStream buff = new BufferedOutputStream(response.getOutputStream()); StringBuffer write = new StringBuffer(); for (VideoListModel item : list) { write.append(item.getUrl() + ","); write...

    java面试题目大全

    - 输出流:OutputStream、FileOutputStream、ByteArrayOutputStream、BufferedOutputStream 等。 - **字符流**:字符流是专门处理字符数据的流类型,主要用于文本处理。 - 输入流:Reader、FileReader、...

    Java中缓冲字节流.pdf

    BufferedOutputStream bfout = new BufferedOutputStream(out); ``` 在上面的代码示例中,`BufferedInputStream`和`BufferedOutputStream`被用来读取和写入文件。`read()`方法用于从`BufferedInputStream`读取字节...

    缓冲流&转换流习题答案1

    例如,`BufferedInputStream`和`BufferedOutputStream`分别是对`InputStream`和`OutputStream`的缓冲包装,它们增加了内部缓冲区,使得数据读写更加高效。 在练习一中,我们看到如何使用`BufferedOutputStream`向...

    JAVA IO-(FileBuffered的InputOutputStream的基本操作)

    为了提高效率,我们通常会结合BufferedInputStream和BufferedOutputStream使用,以实现缓冲功能。本文将详细探讨Java中FileBuffered的InputOutputStream的基本操作。 1. FileInputStream与FileOutputStream: - ...

    FastDFS上传下载多种API测速情况及代码。

    下载 download_file(group_name, remote_filename , downloadStream) 1073741824(约1G) 24352ms 44092 42.04940796 2K 1 fastDFS的DowloadStream,BufferedOutputStream 下载 download_file(group_name, remote_...

    java IO(下)

    BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("file.txt")); bos.write(data); bos.flush(); // 确保所有数据被写出 bos.close(); // 关闭流并自动flush ``` #### 三、...

    例10.02 使用字节流访问URL资源.rar_url

    BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(fileOutputStream); ``` 最后,我们通过循环读取`bufferedInputStream`中的字节,并写入`bufferedOutputStream`,完成数据的下载: ```...

    Java教程之javaIO详解

    BufferedOutputStream bos = new BufferedOutputStream(fos); bos.write("过滤流".getBytes()); bos.close(); FileInputStream fis = new FileInputStream("7.txt"); BufferedInputStream bis = new ...

    java序列号流基础入门.pdf

    BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("Copy.java")); while ((len = sis.read(bys)) != -1) { bos.write(bys, 0, len); } ``` 在另一个示例(SequenceInputStreamDemo2)中...

    欧柏泰克:java写入文件的三种方式

    本文将详细介绍三种常见的Java写入文件的方法,它们分别是:`FileOutputStream`、`BufferedOutputStream`和`FileWriter`。这三种方式各有特点,适用于不同的场景。 首先,我们来看`FileOutputStream`。`...

    基于java的二进制IO类与文件复制操作实例.zip

    BufferedOutputStream bos = new BufferedOutputStream(fos)) { byte[] buffer = new byte[1024]; int bytesRead; while ((bytesRead = bis.read(buffer)) != -1) { bos.write(buffer, 0, bytesRead); } ...

Global site tag (gtag.js) - Google Analytics