文件在使用FileChannel.map后不能被删除(Windows上)

同事发现在Windows上使用FileChannel的map方法之后, 不能够删除掉文件. 我在Linux上试了一下, 发现没这个问题。 做个笔记, 记录一下.

import java.io.File;
import java.io.RandomAccessFile;
import java.lang.reflect.Method;
import java.nio.ByteBuffer;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.channels.FileChannel.MapMode;

import sun.nio.ch.FileChannelImpl;

public class TestDeleteMappedFile {

public static void main(String args[]) {
File f = new File("mapfile");
RandomAccessFile aFile = null;
FileChannel inChannel = null;
try {
aFile = new RandomAccessFile(f, "rw");
inChannel = aFile.getChannel();
ByteBuffer buf = inChannel.map(MapMode.READ_WRITE, 0L, 4);
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
inChannel.close();
aFile.close();
} catch (Exception e) {
e.printStackTrace();
}
}
System.out.println("delete " + f + " : " + f.delete());
}
}


从[url=http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4715154]Oracle的buglist[/url]上看到了这个问题的描述.

[quote]
We cannot fix this. Windows does not allow a mapped file to be deleted. This
problem should be ameliorated somewhat once we fix our garbage collectors to
deallocate direct buffers more promptly (see 4469299), but otherwise there's
nothing we can do about this.
[/quote]

sun.misc.Cleaner为我们干了关闭文件, 释放资源的脏活. 这个类是一个幻引用, 所以会在gc的时候调用到. FileChannel正是调用了这个Cleaner, 在gc的时候做unmap.



// sun.nio.ch.FileChannelImpl类
Unmapper um = new Unmapper(addr, size + pagePosition);
if ((!writable) || (imode == MAP_RO))
return Util.newMappedByteBufferR(isize, addr + pagePosition, um);

// java.nio.DirectByteBuffer类
// For memory-mapped buffers -- invoked by FileChannelImpl via reflection
//
protected DirectByteBuffer(int cap, long addr, Runnable unmapper) {

super(-1, 0, cap, cap, true);
address = addr;
cleaner = Cleaner.create(this, unmapper);
viewedBuffer = null;


}


如果finalizer delay的时候不能调unmap, 那么手动调unmap, 应该就可以在windows上释放掉资源了. 我们试试


import java.io.File;
import java.io.RandomAccessFile;
import java.lang.reflect.Method;
import java.nio.ByteBuffer;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.channels.FileChannel.MapMode;

import sun.nio.ch.FileChannelImpl;

public class TestDeleteMappedFile {

public static void main(String args[]) {
File f = new File("mapfile");
RandomAccessFile aFile = null;
FileChannel inChannel = null;
try {
aFile = new RandomAccessFile(f, "rw");
inChannel = aFile.getChannel();
ByteBuffer buf = inChannel.map(MapMode.READ_WRITE, 0L, 4);
// 加上这几行代码,手动unmap
Method m = FileChannelImpl.class.getDeclaredMethod("unmap", MappedByteBuffer.class);
m.setAccessible(true);
m.invoke(FileChannelImpl.class, buf);
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
inChannel.close();
aFile.close();
} catch (Exception e) {
e.printStackTrace();
}
}
System.out.println("delete " + f + " : " + f.delete());
}
}


果然, 可以删除 :)

Have fun!
Java读取文本文件的5大陷阱与生产级解决方案 文本文件读取是Java基础I/O操作,但其背后涉及字符编码、JVM内存模型、操作系统I/O调度及资源生命周期管理等多层技术原理。理解UTF-8/BOM、`Charset.defaultCharset()`跨平台失效、`BufferedReader`缓冲机制与`Files.lines()`流泄漏等关键问题,直接决定微服务日志解析、ETL批处理、配置加载等场景的稳定性与性能。本文聚焦Java中`Files`、`BufferedReader`两大核心工具在真实工程环境(Spring Boot、Docker、Alp 阅读详情

相关推荐

Java获取文件大小的7大陷阱与生产级解决方案

文件大小是操作系统中最基础的元数据概念,其本质是inode中st_size字段的值,通过stat系统调用获取。不同API(如File.length、Files.size、getAttribute)在符号链接处理、错误语义、权限反馈和跨平台行为上存在根本性差异,导致静默失败、NFS阻塞、Docker路径幻影等高频故障。理解逻辑大小与物理大小、软硬链接语义、文件系统配额及JVM内存模型限制,是构建高可用文件处理能力的前提。本文聚焦Java I/O底层原理与真实生产边界问题,提供可落地的健壮获取方案。

weixin_34082789的博客 414

Java NIO学习之FileChannel

Java的FileChannel读文件方式

南风知我意 2048

Java NIO文件系统核心解析与高性能IO实践

Java NIO(Non-blocking I/O)是Java平台提供的高性能IO处理机制,其核心设计基于通道(Channel)和缓冲区(Buffer)模型,相比传统IO具有更高的吞吐量和更低的资源消耗。java.nio.file包作为NIO体系的核心组件,通过Path、Files等抽象实现了现代文件系统操作,支持符号链接、文件属性操作等高级特性。在分布式系统、大数据处理等需要高性能文件IO的场景中,NIO的文件内存映射(MappedByteBuffer)和异步通道(AsynchronousFileChan

weixin_30617737的博客 410

java filechannel map_FileChannel的map

上一节课讲了在操作系统上的内存映射,我们这节课来讲一下Java中的内存映射。在FileChannel中,也定义了一个内存映射的操作,我们可以使用它来加速文件的读写。map方法FileChannel提供了map方法来把文件影射为内存映像文件:MappedByteBuffer map(int mode,long position,long size);可以把文件的从position开始的size大小的...

weixin_39535752的博客 727

Java文件操作与IO流核心技术解析

文件操作是Java开发中的基础能力,涉及文件读写、目录管理等核心功能。Java通过java.io和java.nio包提供完整的API支持,其中File类作为基础入口,Path和Files则是更现代的替代方案。理解字节流与字符流的区别、掌握缓冲流优化技巧、正确处理字符编码问题是提升IO性能的关键。在实际应用中,这些技术广泛用于配置文件加载、日志记录、数据持久化等场景。特别需要注意资源释放管理,try-with-resources语法能有效防止内存泄漏。对于大文件处理,NIO的异步IO和内存映射技术能显著提升吞

weixin_30301449的博客 417

Ubuntu关闭更新提醒的三层控制方法:从GUI到APT配置

Linux系统更新机制本质上是包管理器(APT)驱动的自动化运维流程,其核心原理在于分离‘元数据刷新’、‘安全补丁安装’和‘用户通知’三个职能。这种分层设计既保障了基础安全性,又为系统管理员提供了策略定制空间。技术价值体现在提升生产环境稳定性、规避未经验证的内核/驱动升级风险,并支持ROS、Blender渲染、工业控制等对时序敏感的应用场景。本文聚焦Ubuntu系统入门教程中高频需求——科学关闭软件更新提醒,覆盖Ubuntu 20.04及LTS版本的GUI设置、systemd服务禁用与APT配置修改三大实操

weixin_29698641的博客 395

FileChannel map(MapMode mode, long position, long size)

我们可以通过FileChannel.map(MapMode mode, long position, long size)将文件通过关联的文件映射到内存区域,然后就可以通过 MappedByteBuffer的相关读写方法直接操作对应文件,接下来看下下面的代码: @Test public void map1() throws IOException { RandomAc...

johnhuster的专栏 1720

手把手教学:用国产GLM-4.6替代Claude4.0,实现AI自动化编程全流程

本文提供了一份详细的教程,指导开发者使用国产GLM-4.6模型替代Claude 4.0,实现AI自动化编程。内容涵盖从获取API密钥、搭建本地环境、改造Claude Code工具到实战开发与VSCode集成的全流程,旨在帮助用户低成本、高效率地体验AI自主编程。

weixin_29070861的博客 556

java.nio.channels.FileChannel.map读取超过2G文件的解决方案

MappedByteBuffer、FileChannel读取超大文件

青衫烟雨客的专栏 1万+

c语言【分糖果】2023蓝桥杯4124(枚举,递归,dfs)

但是这是不符合我们糖果刚好分完的条件的,我们应该往回退到上一层,也就是孩子6这层,然后j+1=3,孩子7分到3个第二种糖果,这也不符合我们糖果刚好分完的条件,然后就会再次回退到孩子6这里,然后j+1=4,让我们的孩子7获得5块第二种糖果,然后还是不符合糖果刚分完的条件,于是再一次退回到孩子6这里,然后就会有外循环i+1=1,j=1,孩子7分到1块第一种糖果1块第二块糖果......然后就是这样的不停地回溯,试探,直到把整棵树遍历一遍,并且记录所有的满足条件的组合。先放一下我的代码,我的代码超时啦救命!

weixin_74331419的博客 732

常学常新:《Attention Is All You Need》万字解读!

常学常新:《Attention Is All You Need》万字解读!

hunteritself的博客 3654

java filechannel map_Java NIO 文件通道 FileChannel 用法

FileChannel 提供了一种通过通道来访问文件的方式,它可以通过带参数 position(int) 方法定位到文件的任意位置开始进行操作,还能够将文件映射到直接内存,提高大文件的访问效率。本文将介绍其详细用法和原理。1. 通道获取FileChannel 可以通过 FileInputStream, FileOutputStream, RandomAccessFile 的对象中的 getChan...

weixin_31476341的博客 1126

Wafer的T7 Code是什么,怎么来的

在半导体Cim系统中,waferstart 业务需要支持 Sorter 读取 Wafer 的 T7 Code,与 MES 的 Wafer ID 进行绑定,以便向 前追溯 Wafer 历史,那么问题来了,T7code 是什么Wafer的T7 Code是一种,用于标识双面抛光的晶圆。这种标记采用二维矩阵代码符号,适用于各种尺寸的晶圆,不仅限于450mm无缺口晶圆7。T7 Code是衬底来料背面通常会有的供应商刻的追溯ID,这是一串数字和字母组成的流水码。

阿拉伯梳子的专栏 7931

java filechannel map_文件在使用FileChannel.map后不能被删除(Windows上)

同事发现在Windows上使用FileChannel的map方法之后, 不能够删除掉文件. 我在Linux上试了一下, 发现没这个问题。 做个笔记, 记录一下.Java代码 import java.io.File;import java.io.RandomAccessFile;import java.lang.reflect.Method;import java.nio.ByteBuffer;i...

weixin_42502811的博客 454

Nuclei漏洞扫描:从零到精通的Windows实战指南

本文详细介绍了Nuclei漏洞扫描工具在Windows平台上的安装与使用教程,从基础安装到高级实战技巧全面覆盖。通过具体案例展示如何利用Nuclei的模板库快速检测常见漏洞,并提供自定义POC开发指南,帮助安全从业者高效开展漏洞扫描工作。

weixin_28683689的博客 251

麻辣香锅病毒分析

Spicy Hot Pot浏览器劫持病毒(麻辣香锅病毒)从2020年初被安全公司监测到,因其病毒模块带有MLXG_KM被安全行业代称麻辣香锅病毒。目前通过各种激活工具传播, 包括暴风激活、小马激活和KMS激活等诸多工具,疑似与下载站进行合作推广此类激活工具。Spicy Hot Pot 是一个浏览器劫持 Rootkit,它会将用户的主页更改为指向恶意软件操作员控制的页面,此外还会将内存转储从机器上传到预定义的服务器,并结合本地更新功能以确保其保持更新。通常浏览器劫持者会通过更改用户主页的恶意可执行文件或注册表

不忘初心,护天下安全! 4794

使用FileChannel 处理文件时,文件无法删除

在Windows上使用FileChannel的map方法之后, 不能够删除掉文件。 in = new FileInputStream(file); ch = in.getChannel(); ByteBuffer byteBuffer = ch.map(FileChannel.MapMode.READ_ONLY, 0, file.length()); String md5 = MD5(byte...

MisshqZzz的博客 2000

华为OD机试真题 新系统2026-04-08 Python&JS 实现【直捣黄龙】

小王在玩一款叫做直捣黄龙的小游戏,在该游戏中他需要从入口位置进入敌营,绕过哨兵的层层封锁,达到敌军司令部实施斩首行动。 敌军阵营是一个n*n的矩阵,入口在坐标(0,n/2),敌军司令部在坐标(n-1,n/2),每个哨兵警戒以自己为中心的9宫格,一旦被哨兵发现则行动失败。

MISAYAONE的博客 594

JDK的bug导致Java文件删除不了,必须fgc

在windows系统下jdk无法释放已缓存的文件,导致文件无法删除,所以需要主动调用System.gc()

shy_snow的专栏 854

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

java 释放文件_在Windows中释放Java文件锁定

我在使用Java在Windows中删除文件时遇到一些问题。由于某种原因,java会锁定我的文件,但我不知道为什么。这是我的代码:private byte[] getFileByteArray(File file) {try {RandomAccessFile raf = new RandomAccessFile(file, "r");FileChannel channel = raf.getCha...

weixin_35779093的博客 455

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

Java文件操作核心技术解析与实战技巧

文件操作是软件开发中的基础功能,Java通过IO和NIO两套API提供了完整的文件处理能力。从技术原理看,Java文件操作涉及字节流/字符流转换、缓冲区优化、内存映射等核心机制,直接影响系统性能和资源利用率。在实际工程中,正确处理文件路径分隔符、大文件分块读取、临时文件管理等场景尤为关键,特别是跨平台兼容性和并发安全等问题需要特别关注。本文以Java文件路径处理、高效读写策略、文件锁机制等高频技术点为切入点,结合日志轮转、配置热加载等典型应用场景,深入解析文件操作的最佳实践方案。

weixin_34221276的博客 362

Java NIO.2文件系统API原理与实践指南

Java NIO.2是现代Java开发中处理文件系统的核心API,它通过Path、Files和FileSystem三大组件提供了跨平台的文件操作能力。其底层采用SPI机制实现可插拔架构,支持内存文件系统等特殊实现。在性能优化方面,NIO.2通过直接缓冲区、内存映射等技术显著提升I/O效率,特别适合处理大文件和高并发场景。文件监控、原子操作等高级特性使其成为构建现代文件处理应用的基础。结合异步I/O和响应式编程,NIO.2能够满足云原生时代对高性能文件操作的需求,是Java开发者必须掌握的关键技术。

weixin_33693070的博客 405

Java图片拷贝的正确方式与性能优化

在Java文件操作中,二进制文件与文本文件的处理方式存在本质区别。二进制文件由原始字节序列构成,而文本文件则基于字符编码。当使用字符流处理图片等二进制文件时,会导致字节序列被意外修改,引发文件损坏。正确的做法是采用字节流(如FileInputStream/FileOutputStream)或NIO的Files.copy方法,配合适当大小的缓冲区(推荐8KB-32KB)来确保数据完整性。对于大文件传输,可使用内存映射文件或分块并行拷贝技术提升性能。这些技术在电商图片处理、媒体文件备份等场景中尤为重要,能有效避

weixin_30291791的博客 444

CLM文件数模分离实战:SQLite+Java实现高效元数据治理

CLM(Common Lifecycle Model)作为航空、船舶等领域主流的三维模型生命周期封装格式,其核心挑战在于模型数据与业务元数据深度耦合导致的查询慢、变更重、难追溯。数模分离本质是将结构化元数据(BOM、工艺、版本等)与非结构化二进制大对象(blob)解耦,依托SQLite轻量级事务与哈希索引能力,实现毫秒级元数据检索与原子化模型更新。该方案规避了重型数据库部署依赖,适配军工/院所受限环境,并天然支持DB Browser等工程化工具链,显著提升设计变更响应效率与PLM协同质量。

weixin_34306593的博客 339
上一篇: 警惕使用jvm参数CMSRefProcTaskProxy
coderplay
博客等级 码龄19年 6粉丝 8原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值