怎么判断文件 fileoutPutStream已经拷贝成功? 项目需求是判断fileInputStream已经拷贝

要判断文件 `fileoutPutStream` 已经拷贝成功,可以通过以下几个步骤来实现:

1. **确保所有数据都已写入**:
   使用 `FileOutputStream` 的 `getFD().sync()` 方法,这会强制将所有未写的数据写入到磁盘上。

2. **检查流是否关闭成功**:
   在关闭流之后检查是否有异常抛出。如果流关闭时没有抛出异常,这通常意味着数据已经被成功写入。

3. **比较文件大小**:
   在拷贝之前和拷贝之后比较源文件和目标文件的大小。如果它们相等,这可能意味着文件已经被成功拷贝。但请注意,这并不是一个完全可靠的方法,因为文件大小相同并不一定意味着内容完全相同。

4. **使用校验和(Checksum)**:
   在拷贝文件之前和之后计算文件的校验和(例如,MD5、SHA-1等)。如果拷贝前后的校验和相同,则可以认为文件内容相同。

5. **捕获异常**:
   在拷贝过程中捕获可能发生的任何异常。如果没有任何异常被抛出,这可能意味着拷贝操作成功。

6. **使用Java NIO的`FileChannel`**:
   使用 `FileChannel` 的 `transferFrom` 方法进行文件拷贝。如果 `transferFrom` 方法返回了预期的字节数,这可能意味着拷贝成功。

7. **确认操作完成**:
   在执行删除源文件 `src.delete()` 之前,确保所有上述检查都已通过。

以下是修改后的代码示例,展示了如何实现这些步骤:

```java
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.security.MessageDigest;

public class FileCopyExample {
    public static void main(String[] args) {
        Path srcPath = Paths.get("source.txt");
        Path dstPath = Paths.get("destination.txt");
        boolean srcDelete = true;

        try (FileInputStream fileInputStream = new FileInputStream(srcPath.toFile());
             FileOutputStream fileoutPutStream = new FileOutputStream(dstPath.toFile());
             FileChannel inputChannel = fileInputStream.getChannel();
             FileChannel outputChannel = fileoutPutStream.getChannel()) {

            long size = inputChannel.size();
            long position = 0;
            long transferredBytes = 0;

            // 拷贝文件内容
            while (position < size) {
                transferredBytes = outputChannel.transferFrom(inputChannel, position, size - position);
                position += transferredBytes;
            }

            // 确保所有数据都已写入磁盘
            fileoutPutStream.getFD().sync();

            // 检查校验和是否相同
            if (checkChecksums(srcPath, dstPath)) {
                System.out.println("文件拷贝成功,校验和匹配。");
                // 如果需要删除源文件
                if (srcDelete) {
                    boolean deleteResult = srcPath.toFile().delete();
                    if (deleteResult) {
                        System.out.println("源文件删除成功。");
                    } else {
                        System.err.println("源文件删除失败。");
                    }
                }
            } else {
                System.err.println("文件拷贝失败,校验和不匹配。");
            }

        } catch (IOException e) {
            System.err.println("文件拷贝过程中发生错误:" + e.getMessage());
        }
    }

    private static boolean checkChecksums(Path file1, Path file2) throws IOException {
        // 这里使用MD5算法计算校验和,你可以根据需要使用其他算法
        MessageDigest digest;
        try {
            digest = MessageDigest.getInstance("MD5");
        } catch (Exception e) {
            throw new IOException("MD5摘要算法不可用。", e);
        }

        return calculateChecksum(file1, digest).equals(calculateChecksum(file2, digest));
    }

    private static String calculateChecksum(Path path, MessageDigest digest) throws IOException {
        try (FileInputStream fis = new FileInputStream(path.toFile())) {
            byte[] byteArray = new byte[1024];
            int bytesCount = 0;
            while ((bytesCount = fis.read(byteArray)) != -1) {
                digest.update(byteArray, 0, bytesCount);
            }
            byte[] bytes = digest.digest();
            return bytesToHex(bytes);
        }
    }

    private static String bytesToHex(byte[] bytes) {
        StringBuilder sb = new StringBuilder();
        for (byte b : bytes) {
            sb.append(String.format("%02x", b));
        }
        return sb.toString();
    }
}
```

请注意,`checkChecksums` 方法用于比较两个文件的校验和。如果校验和相同,可以认为文件内容相同,即拷贝成功。如果不同,则拷贝失败。此外,`calculateChecksum` 方法用于计算单个文件的校验和。这里使用了MD5算法,但您可以根据需要选择其他算法。

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

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

相关文章

一文讲解什么是内容可寻址寄存器(Content-Addressable Register)

内容可寻址寄存器&#xff08;Content-Addressable Register&#xff0c;CAR&#xff09;是一种根据内容而非地址来存取数据的存储单元。这种寄存器可以通过指定的数据值来查找对应的存储位置&#xff0c;显著提高了数据匹配和检索的效率&#xff0c;尤其适用于需要快速数据查找…

MLX5_SET_TO_ONES宏解析

看代码时&#xff0c;遇到一个非常复杂的宏MLX5_SET_TO_ONES&#xff0c;这个宏的主要作用是对特定的数据结构置位&#xff0c;宏的上下文如下&#xff1a; #define __mlx5_nullp(typ) ((struct mlx5_ifc_##typ##_bits *)0) #define __mlx5_bit_off(typ, fld) (offsetof(struc…

[程序员] 表达的能力

之前看CSDN的问答区&#xff0c;很多时候&#xff0c;感觉问题的描述所要表达的意思非常模糊&#xff0c;或者说描述不清。如果是想回答问题的人想回答问题&#xff0c;首先要搞清楚是什么问题&#xff0c;就需要再问问题主很多细节的东西。三来四去&#xff0c;才能搞清楚具体…

C++ 代码实现鼠标右键注册菜单,一级目录和二级目录方法

最近做的一个项目, 在使用windows的时候,我希望在右键菜单中添加一个自定义的选项, 该选项下有我经常使用的多个程序快捷方式, 直接上代码 头文件 #pragma once #include <Windows.h> #include <iostream> #include <string> using namespace std; …

面向服务的架构(Service-Oriented Architecture, SOA)

目录 前言1. SOA的基本概念1.1 定义和特点1.2 核心原则 2. SOA的优势与挑战2.1 优势2.2 挑战 3. SOA的实现技术3.1 Web服务3.2 微服务架构3.3 企业服务总线&#xff08;ESB&#xff09; 4. SOA在现代企业中的应用4.1 金融行业4.2 电子商务4.3 政府和公共服务4.4 医疗健康 结语 …

EE trade:炒伦敦金的注意事项及交易指南

在贵金属市场中&#xff0c;伦敦金因其高流动性和全球认可度&#xff0c;成为广大投资者的首选。然而&#xff0c;在炒伦敦金的过程中&#xff0c;投资者需要注意一些关键点。南华金业小编带您一起来看看。 国际黄金报价 一般国际黄金报价会提供三个价格&#xff1a; 买价(B…

LeetCode 1-两数之和

LeetCode第1题 两数之和 给定一个整数数组 nums 和一个整数目标值 target&#xff0c;请你在该数组中找出 和为目标值 target 的那 两个 整数&#xff0c;并返回它们的数组下标。 你可以假设每种输入只会对应一个答案。但是&#xff0c;数组中同一个元素在答案里不能重复出现…

力扣SQL50 各赛事的用户注册率 分组计数 双排序字段

Problem: 1633. 各赛事的用户注册率 &#x1f468;‍&#x1f3eb; 参考题解 Code select contest_id, ROUND(COUNT(user_id) * 100 / (select count(*) from users),2) as percentage from register group by contest_id order by percentage desc, contest_id asc

vue3自动导入---组件库elements-ui,vuetify以及scss样式的自动导入

自动导入 我们在使用第三方组件库和css样式文件时&#xff0c;都需要进行引入&#xff0c;可以在单个组件内单独引用&#xff0c;也可以在全局引入或一次引入所有组件&#xff1b;但是&#xff0c;一般情况下我们都不会全部引入&#xff0c;这会是打包的结果变大&#xff0c;而…

linux挂载硬盘(解决linux不显示硬盘问题)

目录 1.查看系统有几块硬盘2.查看挂载情况3.格式化硬盘4.创建挂载目录用于挂载硬盘5.将硬盘挂载到指定的挂载目录6.随系统自启动挂载查看配置文件&#xff0c;看是否已经把这条命令加入配置 帮同门解决挂载失败问题记录 参考视频&#xff1a;只要6步&#xff01;Linux系统下挂载…

人工智能在影像组学与放射组学中的最新进展|顶刊速递·24-06-22

小罗碎碎念 本期文献速递的主题——人工智能在影像组学中的最新进展。 小罗一直以来的观点&#xff0c;是把大问题分模块拆解——既然我们想做多模态&#xff0c;那么就先了解单模态的研究套路&#xff0c;再去研究不同模态提取的特征如何融合&#xff0c;搞科研的过程也是管理…

获取泛型,泛型擦除,TypeReference 原理分析

说明 author blog.jellyfishmix.com / JellyfishMIX - githubLICENSE GPL-2.0 获取泛型&#xff0c;泛型擦除 下图中示例代码是一个工具类用于生成 csv 文件&#xff0c;需要拿到数据的类型&#xff0c;使用反射感知数据类型的字段&#xff0c;来填充表字段名。可以看到泛型…

JavaStringBuffer与StringBuilder

StringBuffer、StringBuilder 文章目录 StringBuffer、StringBuilderStringBuffer和StringBuilder的理解可变性分析对于String对于StringBuilder 常用方法执行效率对比 StringBuffer和StringBuilder的理解 String 不可变的字符序列 StringBuffer 可变的字符序列 JDK1.0声明&…

miniconda安装教程以及pip换源【Windows版本】

Anaconda包含内容较多&#xff0c;这边采用miniconda进行安装演示。 下载安装包 官网链接&#xff1a;https://docs.anaconda.com/miniconda/ 蓝奏云加速链接&#xff1a;https://wwt.lanzoue.com/i6ts3225vuef 开始安装 配置conda 在Windows开始菜单中&#xff0c;找到刚安…

ktv及歌曲笔记

文章目录 关于唱歌唱歌是个技巧活找对适合自己唱的歌投入感情去唱歌针对性的去练“一首歌”找准自己的音域其他技巧 手机点歌毁嗓子的习惯高峰时间段和常规时间段小包、中包还是大包麦克风的使用 和小伙伴们聚聚&#xff0c;吃个饭&#xff0c;k个歌&#xff0c;盘恒下兄弟时光…

python计算所有进程所占用内存大小之和

#!/usr/bin/env python # -*- coding:utf-8 -*- #参考&#xff1a;https://www.cnblogs.com/zhou2019/p/10864079.html ps 可以查看进程的内存占用大小&#xff0c;写一个脚本计算一下所有进程所占用内存大小的和。 &#xff08;提示&#xff0c;使用ps aux 列出所有进程&…

graalvm jdk和openjdk

下载地址:https://github.com/graalvm/graalvm-ce-builds/releases 官网: https://www.graalvm.org

VBA学习(18):VBA制作任意工作表均可使用的聚光灯

在需要制作聚光的工作簿&#xff0c;按<ALTF11>组合键&#xff0c;打开VBE编辑器。在右侧[工程资源管理器窗格]选中ThisWorkbook模块&#xff0c;将以下代码复制粘贴到该模块的代码窗口。 Private Sub Workbook_SheetSelectionChange(ByVal Sh As Object, ByVal Target …

MLP多层感知器:AI人工智能神经网络的基石

MLP 是指多层感知器&#xff08;Multilayer Perceptron&#xff09;&#xff0c;是一种基础人工神经网络模型&#xff08;ANN&#xff0c;Artificial Neural Network&#xff09;。MLP 的核心是通过深度学习从大量数据中学习特征和模式&#xff0c;并训练参数。通过参数与激活函…

3.XSS-DOM型(基础和进阶)

DOM XSS&#xff08;基础&#xff09; 不与后台服务器产生数据交互,通过前端的dom节点形成的XSS漏洞。 进行测试一下&#xff0c;输入111&#xff0c;会显示what do you see 查看元素代码&#xff0c;看到What do you see 根据前端页面语句进行编写弹窗攻击代码 <a hr…