【踩坑】JDK1.8 AudioSystem 无法关闭流的问题

news2024/12/26 22:40:21

文章目录

  • 一、前言
  • 二、开始狼人杀
    • 嫌疑人1:
    • 嫌疑人2:
  • 三、复盘
    • Jdk8原生bug
    • 解决方法和原理解析

一、前言

做了一个基于文字转语言的小接口,想删除本地wav文件来着,结果发现删除不了。
很明显被占用了,还是被Java占用了…

在这里插入图片描述

二、开始狼人杀

嫌疑人1:

之前的代码是有一个spring的工具类FileCopyUtils.copy()使用


FileCopyUtils.copy(file, Paths.get(absPath).toFile());
if (file.exists() && !file.delete()){
	System.out.println(file.getAbsolutePath() + "删除失败");
}

看起来很正常,里面更正常:

public static int copy(InputStream in, OutputStream out) throws IOException {
	Assert.notNull(in, "No InputStream specified");
	Assert.notNull(out, "No OutputStream specified");

	int var2;
	try {
		var2 = StreamUtils.copy(in, out);
	} finally {
		close(in);
		close(out);
	}
	return var2;
}

close(in); close(out);很好很好,直接发个金水

嫌疑人2:

想到流程中用了Jdk8 javax.sound.sampled包下的 AudioInputStream,用于获取wav音频文件的时长,我是这样写的:

public static int getSoundLength(String filePath) {
	File file = new File(filePath);
	double duration;
	try(AudioInputStream audioInputStream = AudioSystem.getAudioInputStream(file)){
		int sampleRate = (int) audioInputStream.getFormat().getSampleRate();
		int dataSize = audioInputStream.available();
		duration = dataSize / (sampleRate*audioInputStream.getFormat().getFrameSize());
	} catch (UnsupportedAudioFileException | IOException e) {
		return 0;
	}
	return (int) duration;
}

我觉得我调用的也没问题,但是我把这个功能删掉之后文件就不占用了,这个直接标铁狼

三、复盘

Jdk8原生bug

博客园找到了类似的贴子:https://www.cnblogs.com/hligy/p/17659473.html
包括给Jdk官方提交的bug票:https://bugs.openjdk.org/browse/JDK-8013586

在这里插入图片描述
1.7u9报的,看情况应该是在17修复了这个bug,直接润,换成别的方法实现

解决方法和原理解析

用Java内置的java.io.DataInputStream来读wav头文件

  • 代码
	import java.io.DataInputStream;
	import java.io.File;
	import java.io.FileInputStream;
	
    public static int getSoundLength(String filePath) {
        File audioFile = new File(filePath);
        int duration = 0;
        try (FileInputStream fis = new FileInputStream(audioFile);
             DataInputStream dis = new DataInputStream(fis)) {
            // 读取 WAV 文件的头部信息
            byte[] header = new byte[44]; // WAVE 文件头部长度固定为 44 字节
            dis.readFully(header);
            // 解析头部信息获取时长
            int sampleRate = (header[24] & 0xff) | ((header[25] & 0xff) << 8);
            int bitsPerSample = (header[34] & 0xff) | ((header[35] & 0xff) << 8);
            int channels = (header[22] & 0xff) | ((header[23] & 0xff) << 8);
            duration = (int) ((audioFile.length() - 44) * 8 / (sampleRate * bitsPerSample * channels));
        } catch (IOException e) {
            System.err.println("处理音频文件时发生错误: " + e.getMessage());
        }
        return duration;
    }
  • postman返回音频时长12秒
    在这里插入图片描述

  • idea控制台结果12秒:
    在这里插入图片描述

很好用,很润,用到的方法是:

在处理wav文件时,需要根据大小得到准确的播放时长,这中间是有确定关系的
Size = ((Rate * 1000 * Precision * Channels * Length) / 8) + 44 

参数说明:
Size : 文件大小,Byte
Rate :采样率,kHz
Precision : 采样位数,bit
Channels : 声道数量
Length : 音频长度,s()

那么根据反过来根据文件大小计算播放长度公式就是:
Length = (Size - 44) * 8 / (Rate * 1000 * Precision * Channerls)

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

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

相关文章

【uniapp】遇到的一些问题

一、小程序中textarea ios样式不生效的方法 默认有内边距&#xff0c;加个disable-default-padding"true" 二、uni-data-picker循环使用&#xff0c;一个改了全局的值 换成了uni自带的picker&#xff0c;下面括号里必须有默认值&#xff0c;为空字符串的时候&…

MySql -数据库进阶

一、约束 1.外键约束 外键约束概念 让表和表之间产生关系&#xff0c;从而保证数据的准确性&#xff01; 建表时添加外键约束 为什么要有外键约束 -- 创建db2数据库 CREATE DATABASE db2; -- 使用db2数据库 USE db2;-- 创建user用户表 CREATE TABLE USER(id INT PRIMARY KEY …

深入理解 Flink(四)Flink Time+WaterMark+Window 深入分析

Flink Window 常见需求背景 需求描述 每隔 5 秒&#xff0c;计算最近 10 秒单词出现的次数 —— 滑动窗口 每隔 5 秒&#xff0c;计算最近 5 秒单词出现的次数 —— 滚动窗口 关于 Flink time 种类 TimeCharacteristic ProcessingTimeIngestionTimeEventTime WindowAssign…

小程序分销商城,打造高效线上购物体验

小程序商城系统&#xff0c;为您带来前所未有的在线购物体验。它不仅提供线上商城购物、在线下单、支付及配送等功能&#xff0c;还凭借其便捷性成为众多商家的首选。 想象一下&#xff0c;商家可以展示琳琅满目的商品&#xff0c;包括图片、文字描述、价格及库存等详尽信息。而…

C++ 模板 map 和 unordered_map 中,访问不存在的key值,对变量的影响以及返回的结果

map 访问前&#xff1a; 访问后&#xff1a; 测试代码&#xff1a; #include<unordered_map> #include<map> #include<iostream>using namespace std; int main() {map<int,int> map;map[1] 2;map[2] 4;map[3] 6;cout << map[4] << e…

【python】内存管理和数据类型问题

一、内存管理 Python有一个自动内存管理机制&#xff0c;但它并不总是按照期望的方式工作。例如&#xff0c;如果创建了一个大的列表或字典&#xff0c;并且没有删除它&#xff0c;那么这个对象就会一直占用内存&#xff0c;直到Python的垃圾回收器决定清理它。为了避免这种情…

Jmeter+ant+jenkins轻量级接口自动化测试

杀猪不用牛刀&#xff0c;工具没有牛逼高大尚之分&#xff0c;每个工具都有存在的理由&#xff1b;关键是看会不会用&#xff0c;怎么用&#xff0c;有没有用在合适的地方。需要安装的工具&#xff1a; jdk1.8 jmeter3.2 ant1.9&#xff08;蚂蚁&#xff09; jenkins2.1&#…

鸿蒙HarmonyOS学习手册_入门篇

鸿蒙HarmonyOS学习手册_入门篇 文章目录 鸿蒙HarmonyOS学习手册_入门篇入门快速入门开发准备基本概念UI框架应用模型工具准备 构建第一个ArkTS应用&#xff08;Stage模型&#xff09;-快速入门-入门创建ArkTS工程ArkTS工程目录结构&#xff08;Stage模型&#xff09;构建第一个…

websocket介绍并模拟股票数据推流

Websockt概念 Websockt是一种网络通信协议&#xff0c;允许客户端和服务器双向通信。最大的特点就是允许服务器主动推送数据给客户端&#xff0c;比如股票数据在客户端实时更新&#xff0c;就能利用websocket。 Websockt和http协议一样&#xff0c;并不是设置在linux内核中&a…

【理论+实战】带你全面了解 RAG,深入探讨其核心范式、关键技术及未来趋势

写在前面 大家好&#xff0c;关于RAG实战文章已经写了三篇了&#xff0c;有兴趣可以自行去看一下。 用通俗易懂的方式讲解&#xff1a;在 Langchain 中建立一个多模态的 RAG 管道用通俗易懂的方式讲解&#xff1a;大模型 RAG 在 LangChain 中的应用实战用通俗易懂的方式讲解&…

安装ubuntu22.04系统,GPU驱动,cuda,cudnn,python环境,pycharm

需要准备一个u盘&#xff0c;需要格式化&#xff0c;且内存不小于8g 1 下载ubuntu镜像 下载链接&#xff1a; https://cn.ubuntu.com/download/desktop 2下载rufus Rufus - 轻松创建 USB 启动盘Rufus: Create bootable USB drives the easy wayhttps://rufus.ie/zh/ 准备好这…

qt图形化界面开发DAY3

作业&#xff1a; 1> 思维导图 2> 完善对话框&#xff0c;点击登录对话框&#xff0c;如果账号和密码匹配&#xff0c;则弹出信息对话框&#xff0c;给出提示”登录成功“&#xff0c;提供一个Ok按钮&#xff0c;用户点击Ok后&#xff0c;关闭登录界面&#xff0c;跳转…

某查查请求头参数加密分析(含JS加密算法与Python爬虫源码)

文章目录 1. 写在前面2. 请求分析3. 断点分析4. 扣加密JS5. Python爬虫代码实现 【作者主页】&#xff1a;吴秋霖 【作者介绍】&#xff1a;Python领域优质创作者、阿里云博客专家、华为云享专家。长期致力于Python与爬虫领域研究与开发工作&#xff01; 【作者推荐】&#xff…

Ubuntu 实时查看显存调用命令 free 及命令详解与原理说明(全)

Ubuntu 实时查看显存调用命令 free 及详解 文章目录 Ubuntu 实时查看显存调用命令 free 及详解1 free 作用1.1 语法&#xff1a;1.2 单独显示例子1.3 组合显示例子 2 输出介绍3 原理解释3.1 buff / cache&#xff08;即 buffer / cache&#xff09;3.1.1 buffer 缓冲区3.1.2 ca…

PYTHON通过跳板机巡检CENTOS的简单实现

实现的细节和引用的文件和以前博客记录的基本一致 https://shaka.blog.csdn.net/article/details/106927633 差别在于,这次是通过跳板机登陆获取的主机信息,只记录差异的部份 1.需要在跳板机相应的路径放置PYTHON的脚本resc.py resc.py这个脚本中有引用的文件(pm.sh,diskpn…

强化学习求解TSP(四):Qlearning求解旅行商问题TSP(提供Python代码)

一、Qlearning简介 Q-learning是一种强化学习算法&#xff0c;用于解决基于奖励的决策问题。它是一种无模型的学习方法&#xff0c;通过与环境的交互来学习最优策略。Q-learning的核心思想是通过学习一个Q值函数来指导决策&#xff0c;该函数表示在给定状态下采取某个动作所获…

Linux驱动学习—输入子系统

1、什么是输入子系统&#xff1f; 输入子系统是Linux专门做的一套框架来处理输入事件的&#xff0c;像鼠标&#xff0c;键盘&#xff0c;触摸屏这些都是输入设备&#xff0c;但是这邪恶输入设备的类型又都不是一样的&#xff0c;所以为了统一这些输入设备驱动标准应运而生的。…

使用FFmpeg+EasyDarwin搭建音视频推拉流测试环境

1. 前言 在上一篇文章《使用VS2017在win10 x64上编译调试FFmpeg&#xff08;附源码和虚拟机下载&#xff09;》中&#xff0c;我们讲解了如何搭建FFmpeg源码编译和调试环境。 调试FFmpeg&#xff0c;还需要搭建流媒体服务器。流媒体服务器的作用是通过网络对外提供音视频服务…

固乔快递查询助手:一键批量查询,省时省力

在快递行业飞速发展的今天&#xff0c;高效、准确地掌握快递信息对于电商卖家、物流公司管理者以及经常需要查询快递信息的消费者来说至关重要。固乔快递查询助手正是为此而生&#xff0c;它的批量查询功能为用户带来前所未有的便利和高效。 首先&#xff0c;如何下载固乔快递查…

Win10子系统Ubuntu实战(二)

在 Windows 10 中安装 Ubuntu 子系统&#xff08;Windows Subsystem for Linux&#xff0c;简称 WSL&#xff09;有几个主要的用途和好处&#xff1a;Linux 环境的支持、跨平台开发、命令行工具、测试和验证、教育用途。总体而言&#xff0c;WSL 提供了一种将 Windows 和 Linux…