SpringMvc集成FTP连接池

104 阅读6分钟

本文已参与「新人创作礼」活动, 一起开启掘金创作之路。

 1.pom文件中引用依赖

<!-- https://mvnrepository.com/artifact/commons-net/commons-net -->
<dependency>
    <groupId>commons-net</groupId>
    <artifactId>commons-net</artifactId>
    <version>3.3</version>
</dependency>
<!-- https://mvnrepository.com/artifact/commons-pool/commons-pool -->
<dependency>
    <groupId>commons-pool</groupId>
    <artifactId>commons-pool</artifactId>
    <version>1.6</version>
</dependency>
  1. ftp的properties的配置文件
#FTP连接池配置
#最大数
ftpClient_maxTotal=100
#最小空闲
ftpClient_minIdle=10
#最大空闲
ftpClient_maxIdle=100
#最大等待时间
ftpClient_maxWait=3000
#池对象耗尽之后是否阻塞,maxWait<0时一直等待
ftpClient_blockWhenExhausted=true
#取对象是验证
ftpClient_testOnBorrow=true
#回收验证
ftpClient_testOnReturn=true
#创建时验证
ftpClient_testOnCreate=true
#空闲验证
ftpClient_testWhileIdle=false
#后进先出
ftpClient_lifo=false

#FTP连接属性配置
#ip
#测试
ftpClient_host=192.168.0.208

#端口
ftpClient_port=21
#登录名
#测试  线上
ftpClient_username=admin

#密码
#开发
#测试  线上
ftpClient_pasword=sinorock123
#连接是否为主动模式
ftpClient_passiveMode=true
#编码
ftpClient_encoding=UTF-8
#超时时间
ftpClient_clientTimeout=6000
#线程数
ftpClient_threaNum=1
#文件传送类型
#0=ASCII_FILE_TYPE(ASCII格式) 1=EBCDIC_FILE_TYPE 2=LOCAL_FILE_TYPE(二进制文件)  
ftpClient_transferFileType=2
#是否重命名
ftpClient_renameUploaded=true
#重新连接时间
ftpClient_retryTimes=1200
#缓存大小
ftpClient_bufferSize=1024
#默认进入的路径

#测试  线上
ftpClient_workingDirectory=/home/admin/

3.FtpConfig文件 

package com.lawschool.util.ftp;

public class FTPConfig {
   /**
    * 主机
    */
   private String host;
   /**
    * 端口
    */
   private int port;
   /**
    * 
    */
   private String username;
   /**
    * 
    */
   private String password;
   /**
    * 
    */
   private boolean passiveMode;
   /**
    * 
    */
   private String encoding;
   private int clientTimeout;
   private int threadNum;
   private int transferFileType;
   private boolean renameUploaded;
   private int retryTimes;
   private int bufferSize;
   private String workingDirectory;

   public String getWorkingDirectory() {
      return workingDirectory;
   }

   public void setWorkingDirectory(String workingDirectory) {
      this.workingDirectory = workingDirectory;
   }

   public int getBufferSize() {
      return bufferSize;
   }

   public void setBufferSize(int bufferSize) {
      this.bufferSize = bufferSize;
   }

   public String getHost() {
      return host;
   }

   public void setHost(String host) {
      this.host = host;
   }

   public int getPort() {
      return port;
   }

   public void setPort(int port) {
      this.port = port;
   }

   public String getUsername() {
      return username;
   }

   public void setUsername(String username) {
      this.username = username;
   }

   public String getPassword() {
      return password;
   }

   public void setPassword(String password) {
      this.password = password;
   }

   public boolean getPassiveMode() {
      return passiveMode;
   }

   public void setPassiveMode(boolean passiveMode) {
      this.passiveMode = passiveMode;
   }

   public String getEncoding() {
      return encoding;
   }

   public void setEncoding(String encoding) {
      this.encoding = encoding;
   }

   public int getClientTimeout() {
      return clientTimeout;
   }

   public void setClientTimeout(int clientTimeout) {
      this.clientTimeout = clientTimeout;
   }

   public int getThreadNum() {
      return threadNum;
   }

   public void setThreadNum(int threadNum) {
      this.threadNum = threadNum;
   }

   public int getTransferFileType() {
      return transferFileType;
   }

   public void setTransferFileType(int transferFileType) {
      this.transferFileType = transferFileType;
   }

   public boolean isRenameUploaded() {
      return renameUploaded;
   }

   public void setRenameUploaded(boolean renameUploaded) {
      this.renameUploaded = renameUploaded;
   }

   public int getRetryTimes() {
      return retryTimes;
   }

   public void setRetryTimes(int retryTimes) {
      this.retryTimes = retryTimes;
   }
}

4. FTPClientPool

package com.lawschool.util.ftp;

import java.util.Properties;

import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.pool2.impl.GenericObjectPool;
import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
import org.springframework.core.io.Resource;

public class FTPClientPool {
   private GenericObjectPool<FTPClient> ftpClientPool;

   private Resource configLocation;

   public Resource getConfigLocation() {
      return configLocation;
   }

   public void setConfigLocation(Resource configLocation) {

      this.configLocation = configLocation;
      Properties pro = new Properties();
      try {
         pro.load(configLocation.getInputStream());
      } catch (Exception e) {
         e.printStackTrace();
         System.exit(-1);
      }

      // 初始化对象池配置
      GenericObjectPoolConfig poolConfig = new GenericObjectPoolConfig();
      poolConfig.setBlockWhenExhausted(Boolean.parseBoolean(pro.getProperty("ftpClient_blockWhenExhausted")));
      poolConfig.setMaxWaitMillis(Long.parseLong(pro.getProperty("ftpClient_maxWait")));
      poolConfig.setMinIdle(Integer.parseInt(pro.getProperty("ftpClient_minIdle")));
      poolConfig.setMaxIdle(Integer.parseInt(pro.getProperty("ftpClient_maxIdle")));
      poolConfig.setMaxTotal(Integer.parseInt(pro.getProperty("ftpClient_maxTotal")));
      poolConfig.setTestOnBorrow(Boolean.parseBoolean(pro.getProperty("ftpClient_testOnBorrow")));
      poolConfig.setTestOnReturn(Boolean.parseBoolean(pro.getProperty("ftpClient_testOnReturn")));
      poolConfig.setTestOnCreate(Boolean.parseBoolean(pro.getProperty("ftpClient_testOnCreate")));
      poolConfig.setTestWhileIdle(Boolean.parseBoolean(pro.getProperty("ftpClient_testWhileIdle")));
      poolConfig.setLifo(Boolean.parseBoolean(pro.getProperty("ftpClient_lifo")));

      FTPConfig ftpConfig = new FTPConfig();
      ftpConfig.setHost(pro.getProperty("ftpClient_host"));
      ftpConfig.setPort(Integer.parseInt(pro.getProperty("ftpClient_port")));
      ftpConfig.setUsername(pro.getProperty("ftpClient_username"));
      ftpConfig.setPassword(pro.getProperty("ftpClient_pasword"));
      ftpConfig.setClientTimeout(Integer.parseInt(pro.getProperty("ftpClient_clientTimeout")));
      ftpConfig.setEncoding(pro.getProperty("ftpClient_encoding"));
      ftpConfig.setWorkingDirectory(pro.getProperty("ftpClient_workingDirectory"));
      ftpConfig.setPassiveMode(Boolean.parseBoolean(pro.getProperty("ftpClient_passiveMode")));
      ftpConfig.setRenameUploaded(Boolean.parseBoolean(pro.getProperty("ftpClient_renameUploaded")));
      ftpConfig.setRetryTimes(Integer.parseInt(pro.getProperty("ftpClient_retryTimes")));
      ftpConfig.setTransferFileType(Integer.parseInt(pro.getProperty("ftpClient_transferFileType")));
      ftpConfig.setBufferSize(Integer.parseInt(pro.getProperty("ftpClient_bufferSize")));
      // 初始化对象池
      ftpClientPool = new GenericObjectPool<FTPClient>(new FTPClientFactory(ftpConfig), poolConfig);


   }
   public FTPClientPool() {
   }

   public GenericObjectPool<FTPClient> getFtpClientPool() {
      return ftpClientPool;
   }

   public FTPClientPool(Resource configLocation) {


   }

   public FTPClient borrowObject() throws Exception {
      return ftpClientPool.borrowObject();
   }

   public void returnObject(FTPClient ftpClient) {
      ftpClientPool.returnObject(ftpClient);
   }
}

 5.FTPClientFactory

package com.lawschool.util.ftp;

import java.io.IOException;

import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPReply;
import org.apache.commons.pool2.BasePooledObjectFactory;
import org.apache.commons.pool2.PooledObject;
import org.apache.commons.pool2.impl.DefaultPooledObject;
import org.apache.log4j.Logger;




public class FTPClientFactory extends BasePooledObjectFactory<FTPClient>{
   
   private static Logger logger = Logger.getLogger(FTPClientFactory.class);
   
   private FTPConfig ftpConfig;

   public FTPClientFactory(FTPConfig ftpConfig) {
      this.ftpConfig = ftpConfig;
   }

   /**
    * 新建对象
    */
   @Override
   public FTPClient create() throws Exception {
      FTPClient ftpClient = new FTPClient();
      ftpClient.setConnectTimeout(ftpConfig.getClientTimeout());
      try {
         ftpClient.connect(ftpConfig.getHost(), ftpConfig.getPort());
         int reply = ftpClient.getReplyCode();
         if (!FTPReply.isPositiveCompletion(reply)) {
            ftpClient.disconnect();
            logger.error("FTPServer 拒绝连接");
            return null;
         }
         boolean result = ftpClient.login(ftpConfig.getUsername(), ftpConfig.getPassword());
         if (!result) {
            logger.error("ftpClient登陆失败!");
            throw new Exception("ftpClient登陆失败! userName:" + ftpConfig.getUsername() + " ; password:"
                  + ftpConfig.getPassword());
         }
         ftpClient.setFileType(ftpConfig.getTransferFileType());
         ftpClient.setBufferSize(ftpConfig.getBufferSize());
         ftpClient.setControlEncoding(ftpConfig.getEncoding());
         if (ftpConfig.getPassiveMode()) {
            ftpClient.enterLocalPassiveMode();
         }
         ftpClient.changeWorkingDirectory(ftpConfig.getWorkingDirectory());
      } catch (IOException e) {
         logger.error("FTP连接失败:", e);
      }
      return ftpClient;
   }


   
   @Override
   public PooledObject<FTPClient> wrap(FTPClient ftpClient) {
      return new DefaultPooledObject<FTPClient>(ftpClient);
   }

   /**
    * 销毁对象
    */
   @Override
   public void destroyObject(PooledObject<FTPClient> p) throws Exception {
      FTPClient ftpClient = p.getObject();
      ftpClient.logout();
      super.destroyObject(p);
   }

   /**
    * 验证对象
    */
   @Override
   public boolean validateObject(PooledObject<FTPClient> p) {
      FTPClient ftpClient = p.getObject();
      boolean connect = false;
      try {
         connect = ftpClient.sendNoOp();
         if (connect) {
            ftpClient.changeWorkingDirectory(ftpConfig.getWorkingDirectory());
         }
      } catch (IOException e) {
         e.printStackTrace();
      }
      return connect;
   }
   
   
   
}

  1. FtpUtil
package com.lawschool.util;

import com.lawschool.beans.accessory.AccessoryEntity;
import com.lawschool.service.accessory.AccessoryService;
import com.lawschool.util.ftp.FTPClientPool;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPFile;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.context.ContextLoaderListener;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.text.SimpleDateFormat;
import java.util.Date;

@Component
public class FileUtil {
    private static Logger logger = LoggerFactory.getLogger(FileUtil.class);

    /**
     * @return com.lawschool.util.Result
     * @Author MengyuWu
     * @Description 上传文件
     * @Date 19:23 2018-12-19
     * @Param [filename, input]
     **/

    public static Result uploadToFTPServer(String filename, InputStream input) {
        Result result = new Result();
        FTPClientPool ftpClientPool = (FTPClientPool) SpringContextUtils.getBean("ftpClientPool");
        FTPClient ftpClient = null;
        try {
            ftpClient = ftpClientPool.borrowObject();
            //根据文件名截取相关的文件类型
            int start = filename.lastIndexOf(".");
            String type = filename.substring(start + 1, filename.length());//后缀名
            //获取附件servcie
            AccessoryService accessoryService = SpringContextUtils.getBean("accessoryService", AccessoryService.class);
            //AccessoryService accessoryService =(AccessoryService)ContextLoaderListener.getCurrentWebApplicationContext().getBean ("accessoryService");

            AccessoryEntity accessoryEntity = new AccessoryEntity();
            accessoryEntity.setId(GetUUID.getUUIDs("AE"));//设置id
            accessoryEntity.setAccessoryName(filename);//设置文件名
            accessoryEntity.setAccessoryType(type);//设置文件类型

            System.out.println("开始上传文件");
            //inputStream = new FileInputStream(new File(originfilename));
            //initFtpClient();
            ftpClient.setFileType(ftpClient.BINARY_FILE_TYPE);
            String curDate = new SimpleDateFormat("yyyyMMdd").format(new Date());
            //CreateDirecroty(curDate);
            ftpClient.makeDirectory(curDate);
            ftpClient.changeWorkingDirectory(curDate);
            ftpClient.storeFile(accessoryEntity.getId() + "." + type, input);
            input.close();
            //不需要退出  要不然返回到ftp连接池就会报错啦
            //ftpClient.logout();
            String filePath = curDate;
            accessoryEntity.setFilePath(filePath);//设置文件路径
            accessoryService.insert(accessoryEntity);//保存文件信息
            result.put("accessoryId", accessoryEntity.getId());
            System.out.println("上传文件成功");


        } catch (Exception e) {
            System.out.println("上传文件失败");
            e.printStackTrace();
            return Result.error("上传文件失败");
        } finally {
            ftpClientPool.returnObject(ftpClient);
            if (null != input) {
                try {
                    input.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return result;
    }

    /**
     * @return boolean
     * @Author MengyuWu
     * @Description 改变目录路径
     * @Date 19:41 2018-12-19
     * @Param [directory]
     **/

    public static boolean changeWorkingDirectory(String directory, FTPClient ftpClient) {
        boolean flag = true;
        try {
            flag = ftpClient.changeWorkingDirectory(directory);
            if (flag) {
                System.out.println("进入文件夹" + directory + " 成功!");

            } else {
                System.out.println("进入文件夹" + directory + " 失败!开始创建文件夹");
            }
        } catch (IOException ioe) {
            ioe.printStackTrace();
        }
        return flag;
    }

    /**
     * @return
     * @Author MengyuWu
     * @Description 创建多层目录文件,如果有ftp服务器已存在该文件,则不创建,如果无,则创建
     * @Date 19:42 2018-12-19
     * @Param
     **/

    public static boolean CreateDirecroty(String remote, FTPClient ftpClient) throws IOException {
        boolean success = true;
        String directory = remote + "/";
        // 如果远程目录不存在,则递归创建远程服务器目录
        if (!directory.equalsIgnoreCase("/") && !changeWorkingDirectory(new String(directory), ftpClient)) {
            int start = 0;
            int end = 0;
            if (directory.startsWith("/")) {
                start = 1;
            } else {
                start = 0;
            }
            end = directory.indexOf("/", start);
            String path = "";
            String paths = "";
            while (true) {
                String subDirectory = new String(remote.substring(start, end).getBytes("GBK"), "iso-8859-1");
                path = path + "/" + subDirectory;
                if (!existFile(path, ftpClient)) {
                    if (makeDirectory(subDirectory, ftpClient)) {
                        changeWorkingDirectory(subDirectory, ftpClient);
                    } else {
                        System.out.println("创建目录[" + subDirectory + "]失败");
                        changeWorkingDirectory(subDirectory, ftpClient);
                    }
                } else {
                    changeWorkingDirectory(subDirectory, ftpClient);
                }

                paths = paths + "/" + subDirectory;
                start = end + 1;
                end = directory.indexOf("/", start);
                // 检查所有目录是否创建完毕
                if (end <= start) {
                    break;
                }
            }
        }
        return success;
    }

    /**
     * @return boolean
     * @Author MengyuWu
     * @Description 判断ftp服务器文件是否存在
     * @Date 19:42 2018-12-19
     * @Param [path]
     **/

    public static boolean existFile(String path, FTPClient ftpClient) throws IOException {
        boolean flag = false;
        FTPFile[] ftpFileArr = ftpClient.listFiles(path);
        if (ftpFileArr.length > 0) {
            flag = true;
        }
        return flag;
    }

    /**
     * @return boolean
     * @Author MengyuWu
     * @Description 创建目录
     * @Date 19:42 2018-12-19
     * @Param [dir]
     **/

    public static boolean makeDirectory(String dir, FTPClient ftpClient) {
        boolean flag = true;
        try {
            flag = ftpClient.makeDirectory(dir);
            if (flag) {
                System.out.println("创建文件夹" + dir + " 成功!");

            } else {
                System.out.println("创建文件夹" + dir + " 失败!");
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return flag;
    }

    /**
     * @return void
     * @Author MengyuWu
     * @Description 下载文件
     * @Date 19:42 2018-12-19
     * @Param [accessoryId, outputStream]
     **/


    public static OutputStream downloadFromFileServer(String accessoryId, OutputStream outputStream) {
        //获取附件servcie
        AccessoryService accessoryService = SpringContextUtils.getBean("accessoryService", AccessoryService.class);

        //根据附件id下载相关的附件
        AccessoryEntity accessoryEntity = accessoryService.selectById(accessoryId);
        if (UtilValidate.isEmpty(accessoryEntity)) {
            logger.info("文件不存在");
        }
        FTPClientPool ftpClientPool = (FTPClientPool) SpringContextUtils.getBean("ftpClientPool");
        FTPClient ftpClient = null;
        try {
            ftpClient = ftpClientPool.borrowObject();
            System.out.println("开始下载文件");
            //切换FTP对应的文件目录
            boolean test = ftpClient.changeWorkingDirectory(accessoryEntity.getFilePath());
            //每次数据连接之前,ftp client告诉ftp server开通一个端口来传输数据。
            ftpClient.enterLocalPassiveMode();
            FTPFile[] ftpFiles = ftpClient.listFiles();
            for (FTPFile file : ftpFiles) {
                if (file.getName().equals(accessoryEntity.getId() + "." + accessoryEntity.getAccessoryType())) {
                    ftpClient.retrieveFile(file.getName(), outputStream);
                    outputStream.close();
                }
            }
            //不需要退出  要不然返回到ftp连接池就会报错啦
            //ftpClient.logout();
            System.out.println("下载文件成功");
        } catch (Exception e) {
            System.out.println("下载文件失败");
            e.printStackTrace();
        } finally {
            ftpClientPool.returnObject(ftpClient);
            if (null != outputStream) {
                try {
                    outputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return  outputStream;
    }

    /**
     * @Author MengyuWu
     * @Description 删除文件
     * @Date 19:43 2018-12-19
     * @Param [pathname, filename]
     * @return boolean
     **/
    
    public boolean deleteFile(String pathname, String filename){
        boolean flag = false;
        FTPClientPool ftpClientPool = (FTPClientPool) SpringContextUtils.getBean("ftpClientPool");
        FTPClient ftpClient = null;

        try {
            System.out.println("开始删除文件");
            ftpClient = ftpClientPool.borrowObject();
            //切换FTP目录
            ftpClient.changeWorkingDirectory(pathname);
            ftpClient.dele(filename);
            //ftpClient.logout();
            flag = true;
            System.out.println("删除文件成功");
        } catch (Exception e) {
            System.out.println("删除文件失败");
            e.printStackTrace();
        } finally {
            ftpClientPool.returnObject(ftpClient);
        }
        return flag;
    }


}

6.SysCommonController

package com.lawschool.controller.system;

import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.lawschool.base.AbstractController;
import com.lawschool.beans.User;
import com.lawschool.beans.accessory.AccessoryEntity;
import com.lawschool.beans.system.SysMenuEntity;
import com.lawschool.service.UserService;
import com.lawschool.service.accessory.AccessoryService;
import com.lawschool.util.FileUtil;
import com.lawschool.util.Result;
import com.lawschool.util.UtilValidate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

/**
 * ClassName: SysCommonController
 * Description: 系统公共的controller
 * date: 2018-12-6 13:48
 *
 * @author MengyuWu
 * @since JDK 1.8
 */


@Controller
@RequestMapping("/sys")
public class SysCommonController extends AbstractController {

    @Autowired
    private AccessoryService accessoryService;

    @Autowired
    private UserService userService;
    /**
     * @Author MengyuWu
     * @Description 系统文件上传
     * @Date 14:13 2018-12-6
     * @Param [request]
     * @return com.lawschool.util.Result
     **/
    @ResponseBody
    @RequestMapping(value = "/upload", method = RequestMethod.POST)
    public Result upload(MultipartHttpServletRequest request) throws IOException {
        Result result = new Result();
        List<MultipartFile> importfile = request.getFiles("importfile");
        if (UtilValidate.isEmpty(importfile)) {
            throw new RuntimeException("上传失败:文件为空");
        }
        for (MultipartFile multipartFile : importfile) {
            //获取文件名
            String originalFilename = multipartFile.getOriginalFilename();
            if (originalFilename.contains(",")) {
                originalFilename = originalFilename.replaceAll(",", "");
            }
            InputStream inputStream = multipartFile.getInputStream();//输入流
            Result uploadResult = FileUtil.uploadToFTPServer(originalFilename,inputStream);
            if("success".equals(uploadResult.get("msg"))){
                return uploadResult;
            }else{
                return result.error("上传失败");
            }
        }
        return result.error("未知异常");
    }

    /**
     * @Author MengyuWu
     * @Description 附件下载
     * @Date 14:13 2018-12-6
     * @Param [filePath, filename, response]
     * @return void
     **/
    
    /*@RequestMapping("/download")
    public void downLoad(@RequestParam(value = "accessoryId") String accessoryId, HttpServletResponse response) throws IOException {
        if (UtilValidate.isEmpty(accessoryId)) {
            throw new RuntimeException("文件路径错误");
        }
        //根据附件id下载相关的附件
        AccessoryEntity accessoryEntity = accessoryService.selectById(accessoryId);
        if(UtilValidate.isEmpty(accessoryEntity)){
            logger.info("文件不存在");
        }
        ServletOutputStream outputStream = response.getOutputStream();
        response=FileUtil.downloadFromFileServer(accessoryId,outputStream,response);
        outputStream.close();
    }*/
    @RequestMapping("/download")
    public void downLoad(@RequestParam String accessoryId, HttpServletResponse response) throws IOException {

        if (UtilValidate.isEmpty(accessoryId)) {
            throw new RuntimeException("附件id为空");
        }
        ServletOutputStream outputStream = response.getOutputStream();

            AccessoryEntity accessoryEntity = accessoryService.selectOne(new EntityWrapper<AccessoryEntity>().eq("id", accessoryId));
            if (UtilValidate.isNotEmpty(accessoryEntity)) {
                String fileName = null;
                if (UtilValidate.isNotEmpty(accessoryEntity.getAccessoryName())) {
                    fileName = java.net.URLEncoder.encode(accessoryEntity.getAccessoryName(), "UTF-8");
                } else {
                    fileName = "未知名称的附件";
                }
                if (fileName.contains(",")) {
                    fileName = fileName.replaceAll(",", "");
                }
                response.setHeader("Content-Disposition",
                        "attachment; filename=" + fileName);
                outputStream=(ServletOutputStream)FileUtil.downloadFromFileServer(accessoryId,outputStream);
            }

        outputStream.close();
    }

   
}