public InputStream getSqlImage(String sql,String tier) {
    Connection conn = null;
    PreparedStatement pstmt = null;
    ResultSet rs = null;
    InputStream in = null;
    try {
      conn = getConnection();
      if(conn==null){
        return null;
      }
      pstmt = conn.prepareStatement(sql);
      if(pstmt!=null){
        rs = pstmt.executeQuery();
      }
      if(rs!=null){
        if(rs.next()){
          in = rs.getBinaryStream(tier);
        }
      }
    }catch (Exception e) { } finally {
      rs.close();
      pstmt.close();
      conn.close();
    }
这么写返回的InputStream 是没有值的,因为rs、pstmt、conn都已经关掉了
我想在方法里面把rs、pstmt、conn都关掉,然后返回的对象还有值
比如说利用Iterator   可是具体怎么写,请高手指点一下。。或者用别的方法写出来也行

解决方案 »

  1.   

    InputStream nin = in.clone()应该可以达到你的目的吧
      

  2.   

    Iterator   是一个迭代器模型, 不许要你for语句达到循环的要求
    Iterator  it = collection.Iterator();
    it.hasnext();
    it.next();
      

  3.   

    majy(技术永无止境 生命永不停息)   InputStream 中有clone()这个方法吗?star_str(生命火花) 麻烦你说的清楚些?我是初学者  谢谢
      

  4.   

    不能用iterator,因为iterator本身不保存数据,它只访问数据而已。
    可以用一个类似与ResultSet的封装好的hashmap来保存所有的结果,将所有的字段都当作String 来处理。如果你不想丢失结果类型。就需要一个额外的数据结构来表示字段的类型。
    如下用columnNames,columnTypes分别保存字段的名字和类型。
    ResultSetMetaData rstmd = rst.getMetaData();
    int columnCount = rstmd.getColumnCount();// 得到rst即所要查找的事实表中存在的字段数目
    String[] columnNames = new String[columnCount];
    String[] columnTypes = new String[columnCount];
    for (int i = 0; i < columnCount; i++) {
    columnNames[i] = rstmd.getColumnName(i + 1);// 第i个字段的字段名
    columnTypes[i] = rstmd.getColumnTypeName(i + 1);// 第i个字段的数据类型
    然后再建立一个myRst来模仿并保存resultSet的内容。
    public class myRst
    {
       private HashMap[] content;//保存ResultSet内容的东西
       private int coursor;//游标,表示当前访问行
    private 
       
       public void beforeFirst()
      {
           coursor=-1;}
      public void next()
      {  coursor   
       
      

  5.   

    不能用iterator,因为iterator本身不保存数据,它只访问数据而已。
    可以用一个类似与ResultSet的封装好的hashmap来保存所有的结果,将所有的字段都当作String 来处理。如果你不想丢失结果类型。就需要一个额外的数据结构来表示字段的类型。
    如下用columnNames,columnTypes分别保存字段的名字和类型。
    ResultSetMetaData rstmd = rst.getMetaData();
    int columnCount = rstmd.getColumnCount();// 得到rst即所要查找的事实表中存在的字段数目
    String[] columnNames = new String[columnCount];
    String[] columnTypes = new String[columnCount];
    for (int i = 0; i < columnCount; i++) {
    columnNames[i] = rstmd.getColumnName(i + 1);// 第i个字段的字段名
    columnTypes[i] = rstmd.getColumnTypeName(i + 1);// 第i个字段的数据类型
    然后再建立一个myRst来模仿并保存resultSet的内容。
    public class myRst
    {
       private HashMap[] content;//保存ResultSet内容的东西
       private int coursor;//游标,表示当前访问行
    private 
       
       public void beforeFirst()
      {
           coursor=-1;}
      public void next()
      {  coursor   
       
      

  6.   

    Iterator   只提供一个遍历的服务 不会对之做io操作!它可以把一个容器里面的所有数据都取出来
      

  7.   

    自己封装对象完成这件事, 如:
    //执行器
    class Executer{
      Connection conn;
      PreparedStatement pstmt;
      ResultSet rs;
      //打开结果集
      ResultSet open(String sql){
          conn = getConnection();
          pstmt = conn.prepareStatement(sql);
          rs = pstmt.executeQuery();
      }  void close(){
          if (rs!=null) rs.close();
          if (pstmt!=null) pstmt.close();
          if (conn!=null) conn.close();
      }
    }
    //执行过程
    Executer executer = new Executer();
    try{
      executer.open(sql); 
      if(rs.next()){
        in = rs.getBinaryStream(tier);
      }
    } finally {
      executer.close();
    }
      

  8.   

    刚才没有写完,继续
    然后再建立一个myRst来模仿并保存resultSet的内容。public class myRst
    {
       private Object[][] content;//保存ResultSet内容的东西
       private int coursor;//游标,表示当前访问行
       private int length;   public    String[] columnNames,columnTypes;   
       public void beforeFirst()
      {
           coursor=-1;}
      public void next()
      {  coursor++;}  //仿照resultSet的afterlast()之类的操作游标的函数,这里就不写了
      
      public myRst(ResultSet rst)
      {
         ResultSetMetaData rstmd = rst.getMetaData();
    int columnCount = rstmd.getColumnCount();// 得到rst即所要查找的事实表中存在的字段数目
    columnNames = new String[columnCount];
    columnTypes = new String[columnCount];
    for (int i = 0; i < columnCount; i++) {
    columnNames[i] = rstmd.getColumnName(i + 1);// 第i个字段的字段名
    columnTypes[i] = rstmd.getColumnTypeName(i + 1);// 第i个字段的数据类型
           if (columnTypes[i]=="int") columnTypes[i]="Int";
           else if (columnTypes[i]=="varchar") columnTypes[i]="String";
           else if (columnTypes[i]=="char") columnTypes[i]="String";
           else if (columnTypes[i]=="datetime") columnTypes[i]="Date";//没有写完,自己继续列举,比如说int型,取数据要用getInt. varchar要用 getString。这里写的就是怎么取的后半部分。
    }
         
        rst.last();
        length=rst.getRow();
        rst.beforeFirst();
        content=new Object[length][columnCount];
        Class rstClass = rst.getClass();
        Class[] parameterTypes = {"String".getClass()};    for (int i=0;i<length;i++)
        { rst.next();
            for(int j=0;j<columnCount;j++)
             {
                Method method = rstClass.getMethod("get"+columnTypes[j], parameterTypes);
                 Object[] argsMethod = {strXmlDocument};
       content[i][j]= methodClass.invoke(rst, argsMethod);
              }
         }
       }
       public String getString(int j)//仿照ResultSet的getString,实现同样的功能
       {
          return content[coursor][j];
       }
       public String getString(String columnName)//仿照ResultSet的getString,实现同样的功能
       {
          for(int i=0;i<columnNames.length;i++)
             if(columnNames[i]==columnName) break;
          if (i<columnNames.length)  return content[coursor][i];
          else return null;
       }
     }           
    //其他的getInt,getDate之类自己去写。大概ResultSet有的,你觉得需要的,都可以自己实现。
      

  9.   

    //从数据库中读出blob字段之后把它保存在一个临时文件中,退出你写的方法之后,在从这个文件读出
    InputStream in = rs.getBinaryStream("字段名");
    String strFile = "c:\\1";
    OutputStream out = new FileOutputStream(strFile);
    byte[] bytes = new byte[1024];
    while(in.read(bytes,0,1024) != -1){
      out.write(bytes);
    }
    out.close();
    in.close();