java压缩文件解析

本文介绍了一个用于Java的ZIP文件解析器,该解析器能够读取ZIP文件中的内容,并将其转换为字符串或Base64编码的图片数据。此外,还提供了获取指定文件夹内文件列表及所有图片的功能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

/**
 * Program  : ZipExtractor.java
 * Author   : laihm
 * Create   : 2009-5-4 下午03:20:34
 *
 * Copyright 2009 by iPanel Technologies ltd.,
 * All rights reserved.
 *
 * This software is the confidential and proprietary information
 * of iPanel Technologies ltd.("Confidential Information").  
 * You shall not disclose such Confidential Information and shall 
 * use it only in accordance with the terms of the license agreement 
 * you entered into with iPanel Technologies ltd.
 *
 */

package cn.ipanel.apps.portalBackOffice.util;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;

import cn.ipanel.apps.portalBackOffice.util.Base64Fiend;
import cn.ipanel.apps.portalBackOffice.util.CommonsFiend;

/**
 * 
 * @author   laihm
 * @version  1.0.0
 * @2009-5-4 下午03:20:34
 */
public class ZipExtractor {
	
	/**
	 * Task:获取压缩文件的文件列表
	 * @author laihm
	 * @create 2009-5-15 下午06:44:36
	 * @since 
	 * @param prePath前导路径
	 * @param zipNamezip文件名
	 * @param folder文件夹名称
	 * @return
	 * @throws FileNotFoundException当不存在文件时抛出此异常
	 * @throws IOException输入输出异常
	 */
	public static Map getFileStrMapByPathFolder(String prePath,String zipName,String folder) throws FileNotFoundException,IOException{
		if(FileFiend.judgeFileZip(zipName)){
			File f=new File(prePath+FileFiend.FILE_SEPARATOR+zipName);
			Map map=new HashMap();
			ZipInputStream zipInput=new ZipInputStream(new FileInputStream(f));
			ZipEntry zipEntry = null;
			while ((zipEntry = zipInput.getNextEntry()) != null&&zipEntry.getName().startsWith(zipName.substring(0,zipName.indexOf("."))+"/")){
				if(isInFolder(zipEntry,folder)){
					int len = new Long(zipEntry.getSize()).intValue();
					String fullName = suffix2LowerCase(zipEntry.getName());
					if(fullName.endsWith("Thumbs.db"))continue;
					byte[] data = new byte[len];
					int actual = 0;
					int bytesread = 0;
					while ((bytesread != len) && (actual != -1)) {
						actual = zipInput.read(data, bytesread, len
								- bytesread);
						bytesread += actual;
					}
					String fileStr;
					if(isPicFile(fullName)){
						fileStr = Base64Fiend.encode(data);
					}else{
						fileStr= new String(data);
					}
					map.put(fullName,fileStr);
				}	
			}
			zipInput.close();
			return map;
		}
		return null;
	}
	
	/**
	 * 获取压缩文件中所有的图片
	 * @author tianwl
	 * @param prePath
	 * @param zipName
	 * @param folder
	 * @return
	 * @throws FileNotFoundException
	 * @throws IOException
	 */
	public static Map getImgStrMapByPathFolder(String prePath,String zipName,String folder) throws FileNotFoundException,IOException{
		if(FileFiend.judgeFileZip(zipName)){
			File f=new File(prePath+FileFiend.FILE_SEPARATOR+zipName);
			Map map=new HashMap();
			ZipInputStream zipInput=new ZipInputStream(new FileInputStream(f));
			ZipEntry zipEntry = null;
			while ((zipEntry = zipInput.getNextEntry()) != null&&zipEntry.getName().startsWith(zipName.substring(0,zipName.indexOf("."))+"/")){
				if(isInFolder(zipEntry,folder)){
					int len = new Long(zipEntry.getSize()).intValue();
					String fullName = suffix2LowerCase(zipEntry.getName());
					if(fullName.endsWith("Thumbs.db"))continue;
					byte[] data = new byte[len];
					int actual = 0;
					int bytesread = 0;
					while ((bytesread != len) && (actual != -1)) {
						actual = zipInput.read(data, bytesread, len
								- bytesread);
						bytesread += actual;
					}
					String fileStr;
					if(isPicFile(fullName)){
						fileStr = Base64Fiend.encode(data);
						map.put(fullName,fileStr);
					}
				}	
			}
			zipInput.close();
			return map;
		}
		return null;
	}
	
	private static String suffix2LowerCase(String fileName){
		String suffix = fileName.substring(fileName.lastIndexOf(".")+1);
		fileName = fileName.substring(0,fileName.lastIndexOf(".")+1) + suffix.toLowerCase();
		return  fileName;
	}
	
	/**
	 * Task:判断当前 zipEntry 是否是在指定的folder下,如果没有限定folder,则所有的文件都算是
	 * @author laihm
	 * @create 2009-5-5 上午09:52:11
	 * @since 
	 * @param zipEntry
	 * @param folder
	 * @return
	 */
	private static boolean isInFolder(ZipEntry zipEntry,String folder){
		if(zipEntry.isDirectory()){
			return false;
		}
		if("".equals(folder)){  //如果没有限定folder,则所有的文件都算是
			return true;
		}
		String fullName=zipEntry.getName();
		String tmp=folder+"/";
		if(fullName.startsWith(tmp)/*&&fullName.substring(tmp.length()).indexOf("/")==-1*/)
			return true;
		return false;
	}
	
	/**
	 * Task:判断是否是图片文件
	 * @author huangfei
	 * @create 2008-11-22 上午10:47:25
	 * @since 
	 * @param fileName
	 * @return
	 */
	private static boolean isPicFile(String fileName){
		return CommonsFiend.validateImgFormat(fileName);
	}
	
	public static String getZipRootFolder(String prePath,String zipName) throws FileNotFoundException,IOException{
		if(FileFiend.judgeFileZip(zipName)){
			File f=new File(prePath+FileFiend.FILE_SEPARATOR+zipName);
			ZipInputStream zipInput=new ZipInputStream(new FileInputStream(f));
			ZipEntry zipEntry = null;
			while ((zipEntry = zipInput.getNextEntry()) != null&&zipEntry.getName().startsWith(zipName.substring(0,zipName.indexOf("."))+"/")){
				if(zipEntry.getName().indexOf("/")!=-1){
					zipInput.close();
					return zipEntry.getName().substring(0, zipEntry.getName().indexOf("/"));
				}
			}
			zipInput.close();
		}
		return null;
	} 
	
	public static void main(String[] args){
//		System.out.println(null+"abc");
//		try{
//			System.out.println(getZipRootFolder("D:\\tomcat-5.0.28\\webapps\\Portal\\uploadTempDir\\1101877681","tvgame(virtual).zip"));
//			Map map=getFileStrMapByPathFolder("D:\\tomcat-5.0.28\\webapps\\Portal\\uploadTempDir\\1101877681","tvgame(virtual).zip","");
//			Iterator ite=map.entrySet().iterator();
//			while(ite.hasNext()){
//				Map.Entry entry=(Map.Entry)ite.next();
//				System.out.println(entry.getKey());
//			}
//		}catch(FileNotFoundException ex){
//			ex.printStackTrace();
//		}catch(IOException ex){
//			ex.printStackTrace();
//		}
		
		String str = "language  Spec ific ation";
		String str2 = str.replaceAll(" ", "");

		System.out.println(str2);


	}
}


<think>好的,用户现在问的是`torch.cuda.empty_cache()`是否只能清空一个GPU的缓存。我需要先回忆一下PyTorchCUDA内存管理的机制。 首先,用户之前遇到了关于Scikit-learn的分类指标警告和PyTorch的NCCL支持问题,现在转向了CUDA内存管理。可能用户正在处理多GPU训练,或者在单GPU使用中遇到了显存问题。 `torch.cuda.empty_cache()`的作用是释放当前由缓存分配器持有的未使用内存PyTorch默认情况下会缓存一部分内存以提高分配效率,这个函数可以释放那些未被使用的缓存内存。但用户的问题是,这个函数是否只影响当前的一个GPU。 根据PyTorch的文档,当使用多GPU时,每个GPU都有自己的缓存分配器。所以,如果用户有多个GPU,`torch.cuda.empty_cache()`只会释放当前设备(即通过`torch.cuda.current_device()`指定的那个)的缓存。要清空所有GPU的缓存,需要遍历每个设备,切换当前设备,然后分别调用该函数。 用户可能是在多GPU环境下运行代码,发现显存没有完全释放,或者遇到显存不足的问题。需要确认用户是否在使用多GPU,以及是否正确地切换了设备来清空每个GPU的缓存。 另外,用户可能对PyTorch内存管理机制不太熟悉,所以需要解释清楚这个函数的行为,以及在不同情况下的正确使用方法。可能还需要提醒用户,即使调用了这个函数,显存的释放也依赖于是否有未使用的缓存,实际使用的张量不会被释放。 最后,给出示例代码,说明如何为所有GPU清空缓存,并强调正确使用设备切换的重要性。还要提醒用户,显存管理需要结合其他方法,如手动删除变量、运行垃圾回收等,才能有效管理显存使用。</think>--- 在 PyTorch 中,`torch.cuda.empty_cache()` 的作用是释放当前 CUDA 设备(即当前选中的 GPU)的**未使用缓存内存**。其行为取决于 **GPU 设备的选择**和 **多 GPU 环境**的配置。以下是详细说明: --- ### **1.GPU 场景** - 如果你只有一个 GPU,或者代码中未显式指定 GPU 设备: `torch.cuda.empty_cache()` 会清空当前默认 GPU 的缓存内存。 例如: ```python import torch # 默认使用 GPU 0(仅单卡时) a = torch.randn(1000, 1000, device="cuda") # 占用显存 del a # 删除变量 torch.cuda.empty_cache() # 释放 GPU 0 的未使用缓存 ``` --- ### **2.GPU 场景** - 如果你有多个 GPU,且代码中显式切换了设备: 需要**依次选中每个 GPU 并单独调用** `empty_cache()`,才能清空所有 GPU 的缓存。 例如: ```python import torch # 清空 GPU 0 的缓存 torch.cuda.set_device(0) torch.cuda.empty_cache() # 清空 GPU 1 的缓存 torch.cuda.set_device(1) torch.cuda.empty_cache() ``` --- ### **3. 关键注意事项** 1. **缓存释放的范围**: `empty_cache()` **仅释放由 PyTorch 缓存分配器管理的未占用内存**,不会释放正在被张量占用的显存。 - 已分配的张量必须手动删除(如 `del tensor`)或超出作用域后,其显存才会被缓存分配器回收。 - 调用 `empty_cache()` 后,这些回收的内存才会真正释放回系统。 2. **多进程分布式训练**: 在分布式训练(如使用 `torch.distributed` 或 `DataParallel`)时,每个进程可能绑定到不同的 GPU。 - 每个进程需独立调用 `empty_cache()` 清理自己绑定的 GPU 缓存。 - 例如: ```python # 每个进程仅清理自己绑定的 GPU torch.cuda.empty_cache() ``` 3. **自动缓存管理**: PyTorch 默认会缓存部分显存以提高分配效率。频繁调用 `empty_cache()` 可能导致性能下降,建议仅在显存不足时手动调用。 --- ### **4. 验证显存释放** 可以使用 `torch.cuda.memory_summary()` 或以下代码查看显存状态: ```python import torch # 查看当前 GPU 的显存使用情况(单位:字节) print(torch.cuda.memory_allocated()) # 当前已分配的显存 print(torch.cuda.memory_reserved()) # 当前缓存分配器保留的显存(包括未使用的) ``` --- ### **总结** | 场景 | 行为 | |------------|----------------------------------------------------------------------| | **单 GPU** | 清空当前 GPU 的未使用缓存。 | | **多 GPU** | 需遍历所有 GPU,分别调用 `empty_cache()` 才能清空每个设备的缓存。 | --- ### **最佳实践** - 显存不足时手动调用 `empty_cache()`,但避免在循环中频繁使用。 - 结合显存监控工具(如 `nvidia-smi` 或 PyTorch 内置函数)诊断显存泄漏。 - 多 GPU 场景显式指定设备并分别清理: ```python for i in range(torch.cuda.device_count()): torch.cuda.set_device(i) torch.cuda.empty_cache() ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值