分布式冗余存储系统,MATLAB R2023b,Matlab版

分布式冗余存储系统,MATLAB R2023b,Matlab版

主函数

    while true  
        fprintf('这是一个文件存储的程序:\n');  
        fprintf('存文件输入1,取文件输入2,查看输入3,删除输入4, 退出程序输入0\n');  
        choice = input('您想进行什么操作? ');  
          
        switch choice  
            case 0  
                fprintf('下次再见!\n');  
                return;  
            case 1  
                storage();  
            case 2  
                read();  
            case 3  
                look();  
            case 4  
                dismiss();  
            otherwise  
                fprintf('不是哥们\n');  
                fprintf('存文件输入1,取文件输入2,查看输入3,删除输入4, 退出程序输入0\n');  
        end  
          

    end  
 

存储模块

function storage()
    % Load or initialize .mat data
    data = load_mat('save.mat');

    % Input disk locations
    disk0 = input('请确定存储位置(1/3),以斜杠结尾:', 's');
    disk1 = input('请确定存储位置(2/3),以斜杠结尾:', 's');
    disk2 = input('请确定存储位置(3/3),以斜杠结尾:', 's');

    while true
        file_location = input('输入文件地址(输入#退出): ', 's');
        if strcmp(file_location, '#')
            break;
        end

        if ~exist(file_location, 'file')
            disp('文件不存在,请重试!');
            continue;
        end

        % Get file suffix and size
        [~, filename, ext] = fileparts(file_location);
        suffix = ext;
        file_size = dir(file_location).bytes;
        disp(['文件后缀名为: ', suffix]);
        disp(['文件大小为: ', num2str(file_size), ' 字节']);

        % Open the file to split it into chunks
        fid = fopen(file_location, 'rb');
        buffer_size = 16 * 1024 * 1024;  % 16 MB
        num_chunks = ceil(file_size / buffer_size);

        big_file = struct();  % Structure to store file chunk paths
        big_file.original_path = file_location;  % Store the original path

        for i = 1:num_chunks
            chunk_size = buffer_size;
            if i == num_chunks
                chunk_size = file_size - (num_chunks - 1) * buffer_size;
            end
            buffer = fread(fid, chunk_size, '*uint8');

            % Get two random storage locations for redundancy, pass data to confirm_location
            [c, d] = confirm_location(suffix, disk0, disk1, disk2, data);

            % Save buffer to the two locations
            fid_c = fopen(c, 'wb');
            fwrite(fid_c, buffer, 'uint8');
            fclose(fid_c);

            fid_d = fopen(d, 'wb');
            fwrite(fid_d, buffer, 'uint8');
            fclose(fid_d);

            % Save chunk file paths in metadata
            big_file.(sprintf('chunk_%d', i)) = {c, d};
        end

        fclose(fid);

        % Save file chunk metadata into the data structure
        valid_name = matlab.lang.makeValidName(file_location);
        data.(valid_name) = big_file;

        % Save updated data to .mat file
        save_mat('save.mat', data);

        disp('存储成功!');
    end
end



function [location_str1, location_str2] = confirm_location(input_str, disk0, disk1, disk2, data)
    locations = {disk0, disk1, disk2};
    selected_locs = randperm(3, 2);  % Randomly select two locations

    % Generate a unique filename using the input data
    file_name = generate_unique_random(data, input_str);  

    % Create the full paths for the two selected locations
    location_str1 = fullfile(locations{selected_locs(1)}, file_name);
    location_str2 = fullfile(locations{selected_locs(2)}, file_name);
end

function file_name = generate_unique_random(data, suffix)
    while true
        % Generate a random number and convert to string
        file_name = num2str(randi([0, 2023011000]));
        
        % Check if this file name is already used in the data structure
        is_unique = true;
        for k = fieldnames(data)'
            if ~isempty(data.(k{:}).original_path)%对于每个字段,检查其 original_path 是否非空。如果非空,则进一步检查该字段下所有以 chunk_ 开头的子字段
                chunk_fields = fieldnames(data.(k{:}));
                for i = 1:numel(chunk_fields)
                    if startsWith(chunk_fields{i}, 'chunk_')  % Use MATLAB's built-in startsWith
                        chunk_paths = data.(k{:}).(chunk_fields{i});
                        for j = 1:numel(chunk_paths)
                            % Extract the base file name from the path
                            [~, base_name, ~] = fileparts(chunk_paths{j});
                            % Compare the base file name without the extension
                            if strcmp(base_name, file_name)
                                is_unique = false;
                                break;
                            end
                        end
                        if ~is_unique
                            break;
                        end
                    end
                end
                if ~is_unique
                    break;
                end
            end
        end
        
        % If unique, append the suffix and break the loop
        if is_unique
            file_name = [file_name, suffix];
            break;
        end
    end
end

function data = load_mat(filename)
    if exist(filename, 'file')
        data = load(filename);
    else
        data = struct();
    end
end

function save_mat(filename, data)
    save(filename, '-struct', 'data');
end

恢复模块

function read()
    if exist('save.mat', 'file')
        data = load('save.mat');
    else
        disp('这里什么也没有');
        return;
    end

    while true
        file_location = input('请输入要恢复的文件原始地址,输入#结束恢复操作:', 's');
        if strcmp(file_location, '#')
            break;
        end

        valid_name = matlab.lang.makeValidName(file_location);
        if ~isfield(data, valid_name)
            disp(['文件 ', file_location, ' 无法在记录中找到']);
            continue;
        end

        save_location = input('请输入恢复文件存储位置,以斜杠结尾:', 's');
        full_save_path = fullfile(save_location, get_filename_from_path(file_location));

        % 打开输出文件以恢复数据
        fid_out = fopen(full_save_path, 'wb');
        file_data = data.(valid_name);

        % 恢复文件的每个块
        chunk_names = fieldnames(file_data);
        for i = 1:length(chunk_names)
            if strcmp(chunk_names{i}, 'original_path')
                continue;  % 跳过 original_path 字段
            end
            chunk_paths = file_data.(chunk_names{i});
            for j = 1:length(chunk_paths)
                chunk_path = chunk_paths{j};
                if exist(chunk_path, 'file')
                    fid_in = fopen(chunk_path, 'rb');
                    buffer = fread(fid_in, '*uint8');
                    fwrite(fid_out, buffer, 'uint8');
                    fclose(fid_in);
                    break;  % 只恢复每个块的一个有效副本
                else
                    disp(['小文件 ', chunk_path, ' 找不到了,已跳过']);
                end
            end
        end
        fclose(fid_out);

        disp(['文件 ', file_location, ' 已保存至 ', save_location, '.']);
    end
end

function filename = get_filename_from_path(filepath)
    [~, filename, ext] = fileparts(filepath);
    filename = [filename, ext];
end

查看模块

function look()
    % Load .mat data
    data = load_mat('save.mat');
    
    if isempty(data)
        disp('这里什么也没有');
        return;
    end

    % Display stored files
    disp('已存储的文件有:');
    file_names = fieldnames(data);
    for i = 1:length(file_names)
        % Replace underscores back to original characters like slashes
        original_path = data.(file_names{i}).original_path;
        disp(original_path);
    end
end

function data = load_mat(filename)
    if exist(filename, 'file')
        data = load(filename);
    else
        data = struct();
    end
end

function save_mat(filename, data)
    save(filename, '-struct', 'data');
end

删除模块

function dismiss()
    if exist('save.mat', 'file')
        data = load('save.mat');
    else
        disp('这里什么也没有');
        return;
    end

    while true
        file_location = input('请输入要删除的文件原始地址,输入#结束:', 's');
        if strcmp(file_location, '#')
            break;
        end

        valid_name = matlab.lang.makeValidName(file_location);
        if ~isfield(data, valid_name)
            disp(['文件 ', file_location, ' 没有记录']);
            continue;
        end

        file_data = data.(valid_name);

        % 删除文件块
        chunk_names = fieldnames(file_data);
        for i = 1:length(chunk_names)
            if strcmp(chunk_names{i}, 'original_path')
                continue;  % 跳过 original_path 字段
            end
            chunk_paths = file_data.(chunk_names{i});
            for j = 1:length(chunk_paths)
                path = chunk_paths{j};
                if exist(path, 'file')
                    delete(path);
                    disp(['删除 ', path]);
                else
                    disp([path, ' 没找到,跳过']);
                end
            end
        end

        % 从数据中删除此文件
        data = rmfield(data, valid_name);

        % 保存更新后的数据
        save('save.mat', '-struct', 'data');

        disp(['文件 ', file_location, ' 已从记录里清除.']);
    end
end

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值