ZipInputStream实现压缩文件的读取与数据转化的过程

因为项目业务需要,实现调用第三方接口获取zip文件(byte数组形式接收),并解析文件的数据内容,将数据转化为自定义的对象保存于数据库中。整个过程不需要将文件存于磁盘。

以下为笔者所实现功能的代码,首次分享,大牛勿喷,多多指教~

    public void resolveZipFile() {
    	//自定义对象接收数据
        Class<Item> clazz = Item.class;

       //调用第三方接口获取文件(byte[]形式接收,为utf-8的编码格式)
        byte[] byt = new byte[0];
        try {
            byt = ThirdService.downloadZipFile();
            System.out.println(new String(byt,"UTF-8"));
        } catch (NullPointerException e) {
            loger.info(">>>>>>>>>>>>>>>>>>>>>>>>>>文件为空<<<<<<<<<<<<<<<<<<<<<<<<<<<<<");
        }

		//输出文件到磁盘,检查文件数据内容及结构,方便测试。
        OutputStream os = null;
       	  InputStream in = null;
          try {
              os = new FileOutputStream("e://2019-01-31.zip");
              in = new ByteArrayInputStream(byt);
              byte[] bs = new byte[1024];
              int len = 0;
              while((len = in.read(bs)) != -1){
                  os.write(bs,0,len);
                  os.flush();
              }
              in.close();
              os.close();
          } catch (IOException e) {
              e.printStackTrace();
          }
	
		/*File file = new File("d://test.zip");
        InputStream input = null;
        byte[] byt = new byte[0];*/
	
		//自定义ZipInputStream对象解析zip文件(参数为字节数组读入流读入上面的字节数组)
        ZipInputStream zip = null;
        //自定义字符缓冲流
        BufferedReader br = null;
        
        try {
      	  /*input = new FileInputStream(file);
            byt = new byte[input.available()];
            input.read(byt);*/
            
            zip = new ZipInputStream(new ByteArrayInputStream(byt));
            ZipEntry zipEntry = null;
            
            //记录文件数据行数(最终转为的对象数目)
            int number = 0;
            
            //当zip压缩文件内有文件时候进入解析
            while ((zipEntry = zip.getNextEntry()) != null){
            
            	//读入文件,编码格式utf-8
                br = new BufferedReader(new InputStreamReader(zip,"UTF-8"));
                
                //读取文件第一行
                String line = br.readLine();
                
                //定义分隔符(这边文件分隔符为‘char27’)
                String seperator = Character.toString((char) 27);
                
                //获取第一行第一个字段(总记录数)
                String num = line.split(seperator)[0];
                //Field[] fields = clazz.getDeclaredFields();
                
                while (line != null && !"0".equals(num)) {
                    //Object object = clazz.newInstance();
                    line = br.readLine(); // 一次读入一行数据
                    if (line == null || "".equals(line.trim())){
                        break;
                    }
                    
                    //将每行数据转对象item
                    Item item = (Item) DataUtils.Str2Obj(line, seperator, clazz, 2);
                    System.out.println(item);
                    number++;
                    
                    //保存到MongDB
                    mongoTemplate.save(item,"item");
                }
            }
            System.out.println("文件数据行数:"+number);
        } catch (IOException  e) {
            e.printStackTrace();
        }finally {
            try {
                //input.close();
                zip.close();
                br.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

    }

总结:通过将 byteArrayInputStream对象读入字节数组,作为ZipInputStream的读入对象,再由字符缓冲流BufferInputStream读入ZipInputStream(作为new InputStreamReader的参数),编码格式utf-8。利用字符缓冲流的readLine()方法读入文件每一行数据,转化为item对象保存数据库。
流转化过程: byte[] --> new ByteArrayInputStream(byt) --> new ZipInputStream(bais) --> new InputStreamReader(zis,“UTF-8”) --> new BufferReader(ins)

如果初始以文件流形式接收而非byte[],可通过byteOutPutStream写入文件,再转字节数组,代码如下:

//自定义数组对象
 byte[] byt= null;
 
 //读入zip文件
File file = new File("d://test.zip");
FileInputStream fis = new FileInputStream(file);
ByteArrayOutputStream bos = new ByteArrayOutputStream(fis.available());
byte[] bytes = new byte[fis.available()];
int temp;
while ((temp = fis.read(bytes)) != -1) {
          bos.write(bytes, 0, temp);
	}
fis.close();
bos.close();

//转化成字节数组
byt = bos.toByteArray();

嘿嘿,细心的小伙伴已经发现了,这里是其中一种实现方案,另一种已经写在前面的代码块里,不通过字节数组输出流便完成了转化

在前面的代码块中,本人自定义了工具类 DataUtils.Str2Obj方法实现字符串到对象的转化,至于工具类的实现细节,想了解的请点击另外一篇文章:https://blog.csdn.net/qq_41981107/article/details/85053446

你可能感兴趣的:(ZipInputStream实现压缩文件的读取与数据转化的过程)