< 返回版块

duzhaosongyue 发表于 2022-01-12 11:29

Tags:输出流、输出流

需求描述

有个一个老的oa系统上传存储的文件的格式是纯粹的二进制文件,现在需要把二进制文件还原成原本的文件格式(就是不带有文件格式的二进制文件,还原成带有格式的文件)。

代码实现

1.使用java代码实现:

    /****
     * 翻译二进制文件
     * @param inPath     输入二进制文件
     * @param outPath    输出文件
     */
    private static void translateBinaries(String inPath, String outPath) {
        try (
                //读取文件
                BufferedInputStream inputStream = new BufferedInputStream(new FileInputStream(inPath));
                //输出文件
                DataOutputStream outputStream = new DataOutputStream(new FileOutputStream(outPath))
        ) {
            int temp;
            while ((temp = inputStream.read()) != -1) {
                outputStream.write(temp);
            }
        } catch (IOException e) {
            System.out.println("翻译失败,文件路径错误!");
        }
    }

2.使用rust实现:

use std::fs::File;
use std::io::{BufWriter, Read, Write};

fn main() {
    let in_path = "/Users/fuping/Desktop/junyeda/ad75ff7b-059d-49c3-b768-925fe5157dcc";
    let out_path = "/Users/fuping/Desktop/after/2.jpg";
    //翻译二进制文件
    translate_binaries(in_path, out_path);
}

/****
 * 翻译二进制文件
 * @param inPath     输入二进制文件
 * @param outPath    输出文件
 */
fn translate_binaries(in_path: &str, out_path: &str) {
    //打开一个文件
    let mut in_file = File::open(in_path).unwrap();
    //读取文件获取的字节
    let mut bytes: Vec<u8> = Vec::new();
    //设置缓冲区大小
    let len = 0x4000;
    //每次读取的长度
    let mut red_len = len;
    //循环读取文件
    while red_len == len {
        //缓冲区
        let mut buffer = Vec::with_capacity(len);
        //读取文件并把内容写入到缓冲区  take 设置读取长度 read_to_end写入到缓冲区
        red_len = Read::by_ref(&mut in_file).take(len as u64).read_to_end(&mut buffer).unwrap();
        //把缓冲区的内容添加到读取结果中
        bytes.extend(buffer.iter());
    }
    //创建一个文件
    let out_file = File::create(out_path).unwrap();
    //创建一个写入流 将读取到结果写入到文件
    BufWriter::new(out_file).write_all(&*bytes).unwrap();
}

示例测试文件 链接: https://pan.baidu.com/s/1sHTHxsqjo5KwuhZ8Mb3dVA 提取码: ba6q

问题

下面的rust代码是我东拼西凑实现的,对比java代码总觉得不满意,各位大佬可有更简单的实现方式,求指点一下。

评论区

写评论
作者 duzhaosongyue 2022-01-14 15:20

和std::fs::copy(in_path, out_path).expect("复制失败") 有什么区别吗

👇
我心飞翔: use std::fs::File;

fn main() {

let mut r = File::open("1.zip").unwrap();
let mut w = File::create("2.zip").unwrap();

std::io::copy(&mut r, &mut w);

}

我心飞翔 2022-01-13 16:55

use std::fs::File;

fn main() {

let mut r = File::open("1.zip").unwrap();
let mut w = File::create("2.zip").unwrap();

std::io::copy(&mut r, &mut w);

}

作者 duzhaosongyue 2022-01-13 08:39

这就是我要找的感谢

--
👇
johnmave126: 看了一下,首先文件的格式其实靠的是文件头的magic number,后缀名其实只是windows上用来区分文件格式的方式。我看你想要的只是给原来的文件改个名,加上.jpg的后缀。

--
👇
duzhaosongyue: 说翻译有点描述不清楚,就是存储文件的时候把它存成不带格式的字节文件,根据记录还原成原本的格式。

--
👇
johnmave126: 没看出来哪里在翻译,就是读一个byte写一个byte?

johnmave126 2022-01-12 14:49

你要找的是不是

pub fn main() {
    let in_path = "/Users/fuping/Desktop/junyeda/ad75ff7b-059d-49c3-b768-925fe5157dcc";
    let out_path = "/Users/fuping/Desktop/after/2.jpg";
    std::fs::copy(in_path, out_path).expect("复制失败");
}
johnmave126 2022-01-12 14:45

看了一下,首先文件的格式其实靠的是文件头的magic number,后缀名其实只是windows上用来区分文件格式的方式。我看你想要的只是给原来的文件改个名,加上.jpg的后缀。

--
👇
duzhaosongyue: 说翻译有点描述不清楚,就是存储文件的时候把它存成不带格式的字节文件,根据记录还原成原本的格式。

--
👇
johnmave126: 没看出来哪里在翻译,就是读一个byte写一个byte?

作者 duzhaosongyue 2022-01-12 14:30

😄

--
👇
caedmonx: 刚发现你的文件是图片,我以为你是要解析像 .dat 这类文件。。。可以忽略我的回复。。。

--
👇
duzhaosongyue: 看了半天没看懂

--
👇
caedmonx: ```rust // 翻译数据逻辑,供参考 fn i32(f: &mut File) -> Result<i32, std::io::Error> { let mut buffer = [0u8; 4]; f.read(&mut buffer)?; Ok(i32::from_le_bytes(buffer)) }



caedmonx 2022-01-12 14:26

刚发现你的文件是图片,我以为你是要解析像 .dat 这类文件。。。可以忽略我的回复。。。

--
👇
duzhaosongyue: 看了半天没看懂

--
👇
caedmonx: ```rust // 翻译数据逻辑,供参考 fn i32(f: &mut File) -> Result<i32, std::io::Error> { let mut buffer = [0u8; 4]; f.read(&mut buffer)?; Ok(i32::from_le_bytes(buffer)) }


作者 duzhaosongyue 2022-01-12 14:12

看了半天没看懂

--
👇
caedmonx: ```rust // 翻译数据逻辑,供参考 fn i32(f: &mut File) -> Result<i32, std::io::Error> { let mut buffer = [0u8; 4]; f.read(&mut buffer)?; Ok(i32::from_le_bytes(buffer)) }

caedmonx 2022-01-12 13:48
// 翻译数据逻辑,供参考
fn i32(f: &mut File) -> Result<i32, std::io::Error> {
    let mut buffer = [0u8; 4];
    f.read(&mut buffer)?;
    Ok(i32::from_le_bytes(buffer))
}
作者 duzhaosongyue 2022-01-12 13:35

说翻译有点描述不清楚,就是存储文件的时候把它存成不带格式的字节文件,根据记录还原成原本的格式。

--
👇
johnmave126: 没看出来哪里在翻译,就是读一个byte写一个byte?

johnmave126 2022-01-12 13:11

没看出来哪里在翻译,就是读一个byte写一个byte?

1 共 11 条评论, 1 页