文件泄漏

一、Windows中的文件锁定机制

在Java中操作文件流时,确保及时关闭文件流是非常重要的。在Windows系统上,由于文件锁定机制比较严格,如果一个文件流没有被关闭,可能会导致文件被锁定,从而阻止其它程序对文件的访问,例如进行删除操作。

package com.example.demo.serivice;import java.io.File;public interface IFileService {void handler(File file) throws Exception;
}
package com.example.demo.serivice.impl;import cn.hutool.core.io.FileUtil;
import com.example.demo.serivice.IFileService;
import org.springframework.stereotype.Service;import java.io.File;
import java.io.FileInputStream;@Service
public class FileServiceImpl implements IFileService {@Overridepublic void handler(File file) throws Exception{FileInputStream fileInputStream = new FileInputStream(file);// 文件处理...FileUtil.del(file);}
}
package com.example.demo.controller;import com.example.demo.serivice.IFileService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;import java.io.File;@RestController
@RequestMapping("/file")
@Slf4j
public class FileController {@Autowiredprivate IFileService fileService;@PostMapping("/handler")public void handler(){log.info("---------开始测试---------");File file =new File("D:\\test\\example.docx");try {fileService.handler(file);} catch (Exception e) {e.printStackTrace();}log.info("---------结束测试---------");}
}

项目服务启动后,访问/file/handler接口,控制台中会报错: 

cn.hutool.core.io.IORuntimeException: FileSystemException: D:\test\example.docx: 另一个程序正在使用此文件,进程无法访问。

在上述业务逻辑处理中,虽然fileInputStream对象和删除操作都是位于handler方法中,但是由于fileInputStream对象未调用close方法关闭文件流,指定的文件还是处于锁定状态,所以后面接着调用FileUtil工具类的del方法进行删除操作是会报错的。 

针对上述这种情况,我们只需要在FileUtil.del();这行代码的前面添加下述代码就可以:

fileInputStream.close();

除了合理的关闭文件流,还有另外一种处理方法,就是在业务逻辑处理的外层调用System.gc();进行垃圾回收。

import com.example.demo.serivice.IFileService;
import org.springframework.stereotype.Service;import java.io.File;
import java.io.FileInputStream;@Service
public class FileServiceImpl implements IFileService {@Overridepublic void handler(File file) throws Exception{FileInputStream fileInputStream = new FileInputStream(file);// 文件处理...}
}
import cn.hutool.core.io.FileUtil;
import com.example.demo.serivice.IFileService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;import java.io.File;@RestController
@RequestMapping("/file")
@Slf4j
public class FileController {@Autowiredprivate IFileService fileService;@PostMapping("/handler")public void handler(){log.info("---------开始测试---------");File file =new File("D:\\test\\example.docx");try {fileService.handler(file);System.gc();} catch (Exception e) {e.printStackTrace();} finally {FileUtil.del(file);}log.info("---------结束测试---------");}
}

不过并不是很建议采用使用垃圾回收这种处理机制来解决这个问题,因为垃圾回收的过程需要占用CPU时间片,而且在执行垃圾回收时,应用程序的运行会被暂停,频繁的垃圾回收会影响我们的用户体验(Web界面卡顿),这个要慎用,当然作为一个排查问题的调试思路还是可以的。

二、Mac和Linux中的文件锁定机制

在Java中,如果你使用的是FileOutputstream、Filewriter等文件输出流,这些流在打开文件时可能会获取文件锁,而当流关闭时,相应的文件锁会被释放。因此,如果你没有在使用完文件流后关闭它,可能会导致文件锁一直存在,阻止其它进程对文件的操作。

在Mac或Linux系统上,文件锁定机制和Windows系统不同,可能会出现这么一种情况,即使文件流没有关闭但仍然可以删除文件。在Java中,你可以使用close()方法确保在使用完文件流后关闭流,这样就可以避免文件被锁定,使得在Windows、Mac和Linux系统上都能够正常删除文件。

总之,为了确保跨平台的兼容性和良好的文件管理实践,最好在使用完文件流后及时关闭它,以释放文件锁并允许其它进程对文件执行操作。

三、文件泄漏

文件描述符:文件描述符在形式上是一个非负整数。实际上,它是一个索引值,指向内核为每一个进程所维护的该进程打开文件的记录表。当程序打开一个现有文件或者创建一个新文件时,内核向进程返回一个文件描述符。

文件描述符就是内核为了高效管理已被打开的文件所创建的索引,用来指向被打开的文件,所有执行I/O操作的系统调用都会通过文件描述符。

资源泄漏:通常指的是系统资源,比如socket、文件描述符等,因为这些在系统中都是有限制的,如果创建了而不归还,久而久之,就会耗尽资源,导致其它程序不可用。

文件泄漏(资源泄漏包含文件泄漏):是指在程序中未正确关闭文件描述符或文件句柄,导致文件资源无法被释放的情况。这可能导致系统资源被耗尽,使得系统无法正常工作。

在Linux系统中,文件泄漏是一个比较常见的问题,一般情况下,删除一个文件并不会导致文件泄漏。删除文件只是从文件系统中删除文件的目录项(directory entry),而文件系统会维护一个文件的引用计数。只有当文件的引用计数降为零时,文件系统才会释放文件的磁盘空间。 文件泄漏通常是由于在程序中未正确关闭文件描述符或文件句柄,导致文件资源无法被释放,而不是由于删除文件引起的。删除文件只是删除了文件系统中的目录项,并不直接影响已经打开的文件描述符。 

当一个文件被删除时,如果有进程持有该文件的打开句柄,该文件仍然存在于文件系统中(原始文件会一直占用磁盘空间),直到所有的文件描述符都被关闭。 

四、文件泄漏的常见原因及解决方法

以下是一些可能导致文件泄漏的常见原因以及如何避免它们:

4.1 未正确关闭文件描述符

在程序中,确保在使用完文件后调用相应的关闭函数,例如Java语言中的close()方法。

4.2 异常情况未处理

在程序中处理异常或错误时,确保也关闭相应的文件。使用try-catch或类似机制来捕获异常,然后在适当的位置关闭文件。

FileReader reader = null;
try{reader = new FileReader("example.txt")// 使用文件...
}catch(IOException e){e.printStackTrace();
}finally{try{if(reader!=null){reader.close()}}catch(IOException e){e.printStackTrace();}
}

如果你在删除文件后仍然遇到文件泄漏问题,你可能需要仔细检查程序中文件的打开和关闭逻辑,确保文件描述符在适当的时候被关闭。 

另外,在Linux系统中可以使用"lsof"命令来查看哪些文件虽然已经删除了,但是仍然被打开,可以帮助你找出潜在的文件泄漏问题。

4.3 使用自动关闭资源(try-with-resources)

如果你使用Java7或更高版本,可以使用try-with-resources语句,它可以自动关闭实现"AutoCloseable"接口的资源,包括文件流。 

import java.io.File;public interface IFileService {void handler(File file);
}
import com.example.demo.serivice.IFileService;
import org.springframework.stereotype.Service;import java.io.File;
import java.io.FileInputStream;@Service
public class FileServiceImpl implements IFileService {@Overridepublic void handler(File file){try(FileInputStream fileInputStream = new FileInputStream(file)){// 文件处理...}catch (Exception e){e.printStackTrace();}}
}
import cn.hutool.core.io.FileUtil;
import com.example.demo.serivice.IFileService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;import java.io.File;@RestController
@RequestMapping("/file")
@Slf4j
public class FileController {@Autowiredprivate IFileService fileService;@PostMapping("/handler")public void handler(){log.info("---------开始测试---------");File file =new File("D:\\test\\example.docx");fileService.handler(file);FileUtil.del(file);log.info("---------结束测试---------");}
}

4.4 使用合适的资源管理工具

对于更复杂的应用程序,可能需要使用资源管理工具或框架,以确保在资源使用完成后进行适当的清理。例如在Java中可以使用Apache Commons IO库中的"IOUtils.closeQuitely()"方法。 

<dependency><groupId>commons-io</groupId><artifactId>commons-io</artifactId><version>2.11.0</version>
</dependency>
import java.io.File;public interface IFileService {void handler(File file);
}
import com.example.demo.serivice.IFileService;
import org.apache.commons.io.IOUtils;
import org.springframework.stereotype.Service;import java.io.File;
import java.io.FileInputStream;@Service
public class FileServiceImpl implements IFileService {@Overridepublic void handler(File file){FileInputStream fileInputStream=null;try{fileInputStream = new FileInputStream(file);// 文件处理...}catch (Exception e){e.printStackTrace();}finally {IOUtils.closeQuietly(fileInputStream); // 使用框架安全关闭文件流}}
}
import cn.hutool.core.io.FileUtil;
import com.example.demo.serivice.IFileService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;import java.io.File;@RestController
@RequestMapping("/file")
@Slf4j
public class FileController {@Autowiredprivate IFileService fileService;@PostMapping("/handler")public void handler(){log.info("---------开始测试---------");File file =new File("D:\\test\\example.docx");fileService.handler(file);FileUtil.del(file);log.info("---------结束测试---------");}
}

通过遵循良好的文件资源管理实践,你可以有效地避免文件泄漏问题。同时,在编写代码时要留意异常处理,以确保即使发生错误,也能够正确地关闭文件资源。 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/635809.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

学习Spring的第九天

Spring Bean的生命周期 Bean的实例化阶段 : 看配置文件里Bean标签的信息 , 来判断进行实例化(如是否有lazy-init , 或者是否是FactoryBean等等) (实际就是Bean标签表面的信息 , 即BeanDefinition) Bean的初始化阶段 : 对Bean的属性(重要 : BeanPostProcessor方法 , 及如下 , pr…

L1-059 敲笨钟(Java)

微博上有个自称“大笨钟V”的家伙&#xff0c;每天敲钟催促码农们爱惜身体早点睡觉。为了增加敲钟的趣味性&#xff0c;还会糟改几句古诗词。其糟改的方法为&#xff1a;去网上搜寻压“ong”韵的古诗词&#xff0c;把句尾的三个字换成“敲笨钟”。例如唐代诗人李贺有名句曰&…

什么是安全SCDN,有什么作用?

前两天有个站长被朋友推荐联系到了德迅云安全&#xff0c;想要对自己网站做一些安全防护&#xff0c;聊天中问及到了安全SCDN是什么意思&#xff0c;有哪些作用&#xff1f;那么德迅云安全今天就来简单讲述一下安全SCDN&#xff0c;来了解下什么是安全SCDN&#xff0c;以及它有…

vue3中l和vue2中v-model不同点

vue2比较让人诟病的一点就是提供了两种双向绑定&#xff1a;v-model和.sync&#xff0c; 在vue3中&#xff0c;去掉了.sync修饰符&#xff0c;只需要使用v-model进行双向绑定即可。 为了让v-model更好的针对多个属性进行双向绑定&#xff08;vue2中自定义组件中v-model只能使用…

一键拆分,轻松整理,高效管理文本文件,让工作更轻松!

在日常工作中&#xff0c;我们经常需要处理大量的文本文件。如何快速整理这些文件&#xff0c;方便管理和使用成为了关键问题。为此&#xff0c;我们为您推荐一款强大的一键拆分和整理工具&#xff0c;助您高效管理文本文件&#xff01; 首先&#xff0c;在首助编辑高手的主页面…

Java-IO流【登录注册小项目】

♥️作者&#xff1a;白日参商 &#x1f935;‍♂️个人主页&#xff1a;白日参商主页 ♥️坚持分析平时学习到的项目以及学习到的软件开发知识&#xff0c;和大家一起努力呀&#xff01;&#xff01;&#xff01; &#x1f388;&#x1f388;加油&#xff01; 加油&#xff01…

29、WEB攻防——通用漏洞SQL注入增删改查盲注延迟布尔报错

文章目录 盲注增删改查 盲注 概念&#xff1a;在注入过程中&#xff0c;获取的数据不能回显至前端页面&#xff0c;此时我们需要利用一些方法进行判断或尝试&#xff0c;这个过程被称为盲注。 解决&#xff1a;常规的联合查询注入不行的情况。 分类&#xff1a; 基于布尔的SQ…

原码,补码的乘法运算

目录 一.原码一位乘法 二.补码一位乘法 一.原码一位乘法 在手算10进制乘法中&#xff0c;我们是这样计算的&#xff1a; 这里的本质是因为&#xff1a; 0.211 0.985 所以0.211*0.985 对应&#xff1a; 0.000985 0.00985 …

【面试突击】硬件级别可见性问题面试实战(下:synchronized和volatile底层对原子性、可见性、有序性的保证)

&#x1f308;&#x1f308;&#x1f308;&#x1f308;&#x1f308;&#x1f308;&#x1f308;&#x1f308; 欢迎关注公众号&#xff08;通过文章导读关注&#xff1a;【11来了】&#xff09;&#xff0c;及时收到 AI 前沿项目工具及新技术的推送&#xff01; 在我后台回复…

CHS_01.2.2.1+调度的概念、层次

CHS_01.2.2.1调度的概念、层次 调度的概念、层次知识总览调度的基本概念调度的三个层次——高级调度![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/6957fdec179841f69a0508914145da36.png)调度的三个层次——低级调度调度的三个层次——中级调度补充知识&#xff…

laravel8.*集成dingo

learnku中的dingo版本为2&#xff0c;不支持laravel8 实际上dingo已经出到了4&#xff0c;已经支持laravel9 社区活跃度已经不高了&#xff0c;本人特别讨厌重复造轮子&#xff0c;这里特此记录下 文档地址&#xff1a;https://learnku.com/docs/dingo-api/3.x github地址&…

9.1 Maven项目管理(❤❤❤❤)

9.1 Maven项目管理 1. Maven介绍2. 创建Maven项目2.1 创建2.2 结构分析3. Maven依赖管理3.1 简介3.2 设置下载镜像仓库4. 本地仓库与中央仓库5. Maven生命周期6. Maven插件技术1. Maven介绍

钡铼 楼宇暖通网关之 BACnet网关在空气源热泵智能控制系统中的应用介绍

前言 在刚刚过去的2023年&#xff0c;空气源热泵市场依然火爆&#xff0c;全线市场销量递增&#xff0c;各种新品层出不穷&#xff0c;市场认可度持续攀升&#xff0c;在整个采暖市场&#xff0c;空气源热泵已然成为当红明星。 热泵组管道比较复杂&#xff0c;传感器分布比较分…

路飞项目--02

补充&#xff1a;axios封装 # 普通使用&#xff1a;安装 &#xff0c;导入使用 const filmListreactive({result:[]}) axios.get().then() async function load(){let responseawait axios.get()filmList.resultresponse.data.results } # 封装示例&#xff1a;请求发出去之前…

(蓝桥杯每日一题)love

问题描述 马上就要到七夕情人节了&#xff0c;小蓝在这天想要心爱得男神表白&#xff0c;于是她写下了一个长度为n仅由小写字母组成的字符串。 她想要使这个字符串有 1314个 love 子序列但是马虎的小蓝却忘记了当前已经有多少个子序列为 love。 请你帮小蓝计算出当前字符串有多…

【llm 使用llama 小案例】

huggingfacehttps://huggingface.co/meta-llama from transformers import AutoTokenizer, LlamaForCausalLMPATH_TO_CONVERTED_WEIGHTS PATH_TO_CONVERTED_TOKENIZER # 一般和模型地址一样model LlamaForCausalLM.from_pretrained(PATH_TO_CONVERTED_WEIGHTS) tokenize…

pyvisa 打包

pyvisa 打包之后&#xff0c;错误提示&#xff1a; D:\dwp_backup\python study\communication_instrument_visa\dist>"D:\dwp_backup\python study\communication_instrument_visa\dist\EMI_Test_ok.exe" Traceback (most recent call last): File "EMI_…

Java和SpringBoot学习路线图

看了一下油管博主Amigoscode的相关视频&#xff0c;提到了Java和SpringBoot的学习路线&#xff0c;相关视频地址为&#xff1a; How To Master Java - Java for Beginners RoadmapSpring Boot Roadmap - How To Master Spring Boot 如下图所示&#xff1a; 当然关于Java和Spr…

fastjson-BCEL不出网打法原理分析

FastJson反序列化漏洞 与原生的 Java 反序列化的区别在于&#xff0c;FastJson 反序列化并未使用 readObject 方法&#xff0c;而是由 FastJson 自定一套反序列化的过程。通过在反序列化的过程中自动调用类属性的 setter 方法和 getter 方法&#xff0c;将JSON 字符串还原成对…

鸿蒙开发系列教程(五)--ArkTS语言:组件开发

1、基础组件 组件API文档&#xff1a;https://developer.huawei.com/consumer/cn/doc/harmonyos-references-V2/84_u58f0_u660e_u5f0f_u5f00_u53d1_u8303_u5f0f_uff09-0000001427744776-V2 查看组件API 外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传 容…