RError.com

RError.com Logo RError.com Logo

RError.com Navigation

  • 主页

Mobile menu

Close
  • 主页
  • 系统&网络
    • 热门问题
    • 最新问题
    • 标签
  • Ubuntu
    • 热门问题
    • 最新问题
    • 标签
  • 帮助
主页 / 问题

问题[c#]

Martin Hope
Nikolay Stuff
Asked: 2025-04-29 00:33:15 +0000 UTC

使用 Zenject 在 Unity 中实现装饰器

  • 6

有一个界面:

public interface IUpdatable 
{
    public void Awake();
    public void Start();
    public void Update();
    public void FixedUpdate();
    public void LateUpdate();
}

该接口旨在从不继承自的类中提取 Unity 方法MonoBehaviour。我有一个PlayerController实现该接口的类。

这是装饰器本身。我试图使用接口将所有调用集中在一个地方,但是当我运行它时,它至少List<IUpdatable> updatable有一个后继者。Count = 0;IUpdatable

public class UpdatableDecorator : MonoBehaviour
{
    private List<IUpdatable> _updatables  = new();
    
    [Inject]
    public void Construct(List<IUpdatable> updatable)
    {
        _updatables.AddRange(updatable);
        Debug.Log(_updatables.Count);
    }
    private void Awake()
    {

        foreach (var awake in _updatables)
        {
            awake.Awake();
        }
    }
    void Start()
    {
        foreach (var start in _updatables)
        {
            start.Start();
        }
    }


    void Update()
    {
        foreach (var update in _updatables)
        {
            update.Update();
        }
    }
    private void FixedUpdate()
    {
        foreach (var fixedUpdate in _updatables)
        {
            fixedUpdate.FixedUpdate();
        }

    }

    private void LateUpdate()
    {
        foreach (var lateUpdate in _updatables)
        {
            lateUpdate.LateUpdate();
        }
    }
}

绑定如下所示SceneInstaller:

private void BindDicorator()

{
      Container.Bind<List<IUpdatable>>().AsSingle();
      Container.BindInterfacesAndSelfTo<UpdatableDecorator>().FromComponentInHierarchy().AsSingle();
}

我不知道我做错了什么。我将非常感激您的指导。

c#
  • 1 个回答
  • 64 Views
Martin Hope
Макс Тимашков
Asked: 2025-04-28 03:34:14 +0000 UTC

优化 C# 代码,计算对象之间的距离

  • 6

大家好。有一个代码可以找到物体之间的最小距离并选择该物体以便在游戏中进行进一步的交互。

我看到并知道代码看起来很糟糕,但我不知道如何正确缩短它(例如,使用 foreach)。

请帮助我,但不要冒犯我)

代码:

void Distanse()
{
    if (bots[0] != null)
    {
        if (players[0] != null)
        {
            float tmp1 = Vector3.Distance(players[0].transform.position, bots[0].transform.position);
            if (tmp1 < distance)
            {
                distance = tmp1;
                botNearest = bots[0];
            }
        }

        if (players[1] != null)
        {
            float tmp1 = Vector3.Distance(players[1].transform.position, bots[0].transform.position);
            if (tmp1 < distance)
            {
                distance = tmp1;
                botNearest = bots[0];
            }

        }

        if (players[2] != null)
        {
            float tmp1 = Vector3.Distance(players[2].transform.position, bots[0].transform.position);
            if (tmp1 < distance)
            {
                distance = tmp1;
                botNearest = bots[0];
            }

        }



    }

    if (bots[1] != null)
    {
        if (players[0] != null)
        {
            float tmp1 = Vector3.Distance(players[0].transform.position, bots[1].transform.position);
            if (tmp1 < distance)
            {
                distance = tmp1;
                botNearest = bots[1];
            }
        }

        if (players[1] != null)
        {
            float tmp1 = Vector3.Distance(players[1].transform.position, bots[1].transform.position);
            if (tmp1 < distance)
            {
                distance = tmp1;
                botNearest = bots[1];
            }

        }

        if (players[2] != null)
        {
            float tmp1 = Vector3.Distance(players[2].transform.position, bots[1].transform.position);
            if (tmp1 < distance)
            {
                distance = tmp1;
                botNearest = bots[1];
            }

        }



    }
    if (bots[2] != null)
    {
        if (players[0] != null)
        {
            float tmp1 = Vector3.Distance(players[0].transform.position, bots[2].transform.position);
            if (tmp1 < distance)
            {
                distance = tmp1;
                botNearest = bots[2];
            }
        }

        if (players[1] != null)
        {
            float tmp1 = Vector3.Distance(players[1].transform.position, bots[2].transform.position);
            if (tmp1 < distance)
            {
                distance = tmp1;
                botNearest = bots[2];
            }

        }

        if (players[2] != null)
        {
            float tmp1 = Vector3.Distance(players[2].transform.position, bots[2].transform.position);
            if (tmp1 < distance)
            {
                distance = tmp1;
                botNearest = bots[2];
            }

        }



    }
c#
  • 1 个回答
  • 52 Views
Martin Hope
Urfin Joos
Asked: 2025-04-26 18:42:40 +0000 UTC

滚动列表框到最后一项

  • 5

我的目标是在 ListBox 中显示最新添加的项目。严格来说,我是通过ListBox输出控制台来模拟的。 AvaloniaListBox没有方法ScrollToEnd,但是它有一个方法ScrollIntoView,但不幸的是没有效果。我在 GitHub 上找到了一个关于此问题的问题,其中讨论了通过在 UI 线程中运行方法来解决此问题,但这也没有任何效果。我的搜索让我找到了ScrollViewer具有所需方法的东西ScrollToEnd,但是在加载表单时我无法加载它。可能是因为当内容不适合视口时它就被隐式地创建了。通过这个我可以弄清楚,但我有一个问题:我做的一切都正确吗,或者有没有更简单的方法?

c#
  • 1 个回答
  • 40 Views
Martin Hope
HeAVeN
Asked: 2025-04-22 21:37:54 +0000 UTC

从 ASP.NET 和 Docker 上的分散系统下载文件时出现问题

  • 6

我正在 Docker 容器中的 ASP.NET 上创建分布式分散数据存储系统。使用 Chord (DHT)。在节点之间保存文件可以正常工作 - 它们被分发和存储。尝试从节点上传(下载)文件时出现此问题。我无法从日志中找出问题所在。错误可能出在哪里?

日志:

2025-04-21 15:28:36 2025-04-21 12:28:36 warn: DistributedSystems_Lab4.WorkerController[0] Запрос на скачивание файла Дикая природа Амазонки.mp4
2025-04-21 15:28:36 2025-04-21 12:28:36 info: System.Net.Http.HttpClient.Default.LogicalHandler[100] Start processing HTTP request GET http://worker4:5004/store/%D0%94%D0%B8%D0%BA%D0%B0%D1%8F%20%D0%BF%D1%80%D0%B8%D1%80%D0%BE%D0%B4%D0%B0%20%D0%90%D0%BC%D0%B0%D0%B7%D0%BE%D0%BD%D0%BA%D0%B8.mp4_part_0
2025-04-21 15:28:36 2025-04-21 12:28:36 info: System.Net.Http.HttpClient.Default.ClientHandler[100] Sending HTTP request GET http://worker4:5004/store/%D0%94%D0%B8%D0%BA%D0%B0%D1%8F%20%D0%BF%D1%80%D0%B8%D1%80%D0%BE%D0%B4%D0%B0%20%D0%90%D0%BC%D0%B0%D0%B7%D0%BE%D0%BD%D0%BA%D0%B8.mp4_part_0
2025-04-21 15:28:36 2025-04-21 12:28:36 info: System.Net.Http.HttpClient.Default.ClientHandler[101] Received HTTP response headers after 61.7462ms - 400
2025-04-21 15:28:36 2025-04-21 12:28:36 info: System.Net.Http.HttpClient.Default.LogicalHandler[101] End processing HTTP request after 62.0256ms - 400
2025-04-21 15:28:36 2025-04-21 12:28:36 warn: DistributedSystems_Lab4.WorkerController[0] Не удалось скачать блок Дикая природа Амазонки.mp4_part_0 с http://worker4:5004

代码:

docker-compose.yml:

services:
 
  worker1:
    container_name: worker1
    image: myapp
    environment:
      - NodeRole=worker
      - ASPNETCORE_URLS=http://+:5001
    ports:
      - "5001:5001"
    networks:
      - app_net
    volumes:
      - worker1_storage:/app/storage
      - metadata-volume:/app/metadata_storage
    deploy:
      restart_policy:
        condition: on-failure
 
  worker2:
    container_name: worker2
    image: myapp
    environment:
      - NodeRole=worker
      - ASPNETCORE_URLS=http://+:5002
    ports:
      - "5002:5002"
    networks:
      - app_net
    volumes:
      - worker2_storage:/app/storage
      - metadata-volume:/app/metadata_storage
    deploy:
      restart_policy:
        condition: on-failure
 
  worker3:
    container_name: worker3
    image: myapp
    environment:
      - NodeRole=worker
      - ASPNETCORE_URLS=http://+:5003
    ports:
      - "5003:5003"
    networks:
      - app_net
    volumes:
      - worker3_storage:/app/storage
      - metadata-volume:/app/metadata_storage
    deploy:
      restart_policy:
        condition: on-failure

  worker4:
    container_name: worker4
    image: myapp
    environment:
      - NodeRole=worker
      - ASPNETCORE_URLS=http://+:5004
    ports:
      - "5004:5004"
    networks:
      - app_net
    volumes:
      - worker4_storage:/app/storage
      - metadata-volume:/app/metadata_storage
    deploy:
      restart_policy:
        condition: on-failure

  worker5:
    container_name: worker5
    image: myapp
    environment:
      - NodeRole=worker
      - ASPNETCORE_URLS=http://+:5005
    ports:
      - "5005:5005"
    networks:
      - app_net
    volumes:
      - worker5_storage:/app/storage
      - metadata-volume:/app/metadata_storage
    deploy:
      restart_policy:
        condition: on-failure
 
networks:
  app_net:
    driver: bridge
 
volumes:
  metadata-volume:
    driver: local
  worker1_storage:
  worker2_storage:
  worker3_storage:
  worker4_storage:
  worker5_storage:  

ChordNode.cs:

using DistributedSystems_Lab4;

public class ChordNode
{
    public int Id { get; }
    public string Url { get; }
    public ChordNode? Successor { get; set; }
    public ChordNode? Predecessor { get; set; }
    public List<FingerEntry> FingerTable { get; set; }

    public ChordNode(int id, string url)
    {
        Id = id;
        Url = url;
        FingerTable = new List<FingerEntry>();
    }

    public override string ToString() => $"{Url} ({Id})";
}

ChordRing.cs:

using DistributedSystems_Lab4;
using System.Security.Cryptography;
using System.Text;

public class ChordRing
{
    private readonly List<ChordNode> nodes = new();
    private readonly int m = 32;

    public void InitializeFingerTables()
    {
        foreach (var node in nodes)
        {
            for (int i = 0; i < m; i++)
            {
                int start = (node.Id + (int)Math.Pow(2, i)) % (int)Math.Pow(2, m);
                node.FingerTable.Add(new FingerEntry { Start = start, Node = FindNodeForFingerTable(start) });
            }
        }
    }

    private ChordNode FindNodeForFingerTable(int start)
    {
        foreach (var node in nodes)
        {
            if (node.Id >= start)
                return node;
        }
        return nodes.First();
    }
    public void AddNode(string url)
    {
        int id = Hash(url);
        if (nodes.Any(n => n.Id == id)) return;

        var newNode = new ChordNode(id, url);
        nodes.Add(newNode);
        nodes.Sort((a, b) => a.Id.CompareTo(b.Id));
        UpdateLinks();
    }

    public void RemoveNode(string url)
    {
        nodes.RemoveAll(n => n.Url == url);
        UpdateLinks();
    }

    private void UpdateLinks()
    {
        int count = nodes.Count;
        for (int i = 0; i < count; i++)
        {
            var current = nodes[i];
            current.Successor = nodes[(i + 1) % count];
            current.Predecessor = nodes[(i - 1 + count) % count];
        }
    }

    public ChordNode FindResponsibleNode(string key)
    {
        int keyHash = Hash(key);

        foreach (var node in nodes.OrderBy(n => n.Id))
        {
            if (keyHash <= node.Id)
                return node;
        }

        return nodes.First(); // Если хеш больше всех — вернем первого (кольцо)
    }

    public static int Hash(string input)
    {
        using var sha1 = SHA1.Create();
        var hash = sha1.ComputeHash(Encoding.UTF8.GetBytes(input));
        return Math.Abs(BitConverter.ToInt32(hash, 0));
    }

    public IEnumerable<ChordNode> GetAllNodes() => nodes;
}
FingerEntry.cs:

namespace DistributedSystems_Lab4
{
    public class FingerEntry
    {
        public int Start { get; set; }
        public ChordNode? Node { get; set; }
    }
}

键值控制器.cs:

using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using System.IO;
using System.Threading.Tasks;

namespace DistributedSystems_Lab4
{
    [ApiController]
    [Route("store")]
    public class KeyValueController : ControllerBase
    {
        private readonly WorkerFileStorageService service;
        private readonly ILogger logger;

        public KeyValueController(WorkerFileStorageService service, ILogger<KeyValueController> logger)
        {
            this.service = service;
            this.logger = logger;
        }

        [HttpPut("{key}")]
        public async Task<IActionResult> Store(string key, IFormFile file)
        {
            if (file == null || file.Length == 0)
            {
                logger.LogWarning("Файл не передан или пуст. partName: {partName}", file.FileName);
                return BadRequest("Файл не передан или пуст.");
            }

            logger.LogInformation("Получен запрос на сохранение файла: {FileName} с размером {FileSize} для части: {PartName}",
                file.FileName, file.Length, file.FileName);

            try
            {
                await service.SaveBlockAsync(file.FileName, file);

                service.metadataService.SaveFileName(key, file.FileName);

                logger.LogInformation("Файл {FileName} успешно сохранен.", file.FileName);
                return Ok();
            }
            catch (Exception ex)
            {
                logger.LogError(ex, "Ошибка при сохранении файла {FileName} для части: {PartName}", file.FileName, file.FileName);
                return StatusCode(500, "Ошибка при сохранении файла.");
            }
        }

        [HttpGet("{key}")]
        public async Task<IActionResult> Get(string partName)
        {
            var stream = await service.GetBlockAsync(partName);
            if (stream == null) return NotFound();

            return File(stream, "application/octet-stream", partName);
        }

        [HttpHead("{key}")]
        public IActionResult Exists(string key)
        {
            return service.HasBlock(key) ? Ok() : NotFound();
        }

        [HttpDelete("{key}")]
        public IActionResult Delete(string key)
        {
            return service.DeleteBlock(key) ? Ok() : NotFound();
        }
    }
}

元数据服务.cs:

using Newtonsoft.Json;

public class MetadataService
{
    private readonly string metadataPath = "/app/metadata_storage/"; 

    private Dictionary<string, string> fileNames = new();
    private Dictionary<string, List<(string partName, string WorkerUrl)>> fileMetadata = new();

    public MetadataService()
    {
        if (!Directory.Exists(metadataPath))
        {
            Directory.CreateDirectory(metadataPath);
        }

        LoadMetadata();
    }

    public void SaveFileName(string key, string fileName)
    {
        fileNames[key] = fileName;
        SaveMetadata();
    }

    public void SaveFileMetadata(string key, List<(string partName, string WorkerUrl)> metadata)
    {
        fileMetadata[key] = metadata;
        SaveMetadata();
    }

    public string GetFileName(string key)
    {
        return fileNames.ContainsKey(key) ? fileNames[key] : null;
    }

    public List<(string partName, string WorkerUrl)> GetFileMetadata(string key)
    {
        return fileMetadata.ContainsKey(key) ? fileMetadata[key] : null;
    }

    public void DeleteFileMetadata(string key)
    {
        if (fileMetadata.ContainsKey(key))
        {
            fileMetadata.Remove(key);
            fileNames.Remove(key);
            SaveMetadata();
        }
    }

    private void SaveMetadata()
    {
        if (!Directory.Exists(metadataPath))
        {
            Directory.CreateDirectory(metadataPath);
        }

        var filePath = Path.Combine(metadataPath, "metadata.json");

        var metadata = new
        {
            Files = fileNames,
            Metadata = fileMetadata
        };

        var json = JsonConvert.SerializeObject(metadata, Formatting.Indented);
        File.WriteAllText(filePath, json);
    }

    private void LoadMetadata()
    {
        var filePath = Path.Combine(metadataPath, "metadata.json");

        if (File.Exists(filePath))
        {
            var json = File.ReadAllText(filePath);
            var metadata = JsonConvert.DeserializeObject<dynamic>(json);

            if (metadata?.Files != null)
                fileNames = JsonConvert.DeserializeObject<Dictionary<string, string>>(metadata.Files.ToString());

            if (metadata?.Metadata != null)
                fileMetadata = JsonConvert.DeserializeObject<Dictionary<string, List<(string partName, string WorkerUrl)>>>(metadata.Metadata.ToString());
        }
    }

    public bool KeyExists(string key)
    {
        if (fileNames[key] != null)
            return true;
        else return false;
    }
}

程序.cs:

using DistributedSystems_Lab4;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.DataProtection;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Http.Features;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using System;

var builder = WebApplication.CreateBuilder(args);

builder.Logging.ClearProviders();
builder.Logging.AddSimpleConsole(options =>
{
    options.IncludeScopes = false; 
    options.SingleLine = true;    
    options.TimestampFormat = "yyyy-MM-dd HH:mm:ss ";  
});

builder.Services.AddMvc();
builder.Services.Configure<Microsoft.AspNetCore.Http.Features.FormOptions>(options =>
{
    options.MultipartBodyLengthLimit = 10L * 1024 * 1024 * 1024; // 10GB
});

builder.WebHost.ConfigureKestrel(serverOptions =>
{
    serverOptions.Limits.MaxRequestBodySize = 10L * 1024 * 1024 * 1024; // 10GB
});

builder.Services.Configure<FormOptions>(o =>
{
    o.MultipartBodyLengthLimit = 10L * 1024 * 1024 * 1024; // 50 MB
});
builder.Services.AddControllers();
builder.Services.AddHttpClient();
builder.Services.AddSingleton<HttpClient>();
builder.Services.AddSingleton<WorkerFileStorageService>();
builder.Services.AddSingleton<ChordNode>();
builder.Services.AddSingleton<ChordRing>();
builder.Services.AddSingleton<FingerEntry>();
builder.Services.AddSingleton<KeyValueController>();
builder.Services.AddSingleton<MetadataService>(); 

var app = builder.Build();

app.Logger.LogInformation("Start");

app.MapGet("/", () => Results.Redirect("/index.html"));

app.UseStaticFiles();

app.UseRouting();
app.UseAuthorization();
app.MapControllers();

app.Run();

WorkerController.cs:

using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using System.IO;
using System.Net.Http;
using System.Threading.Tasks;
using System.Linq;
using System.Collections.Generic;
using System;

namespace DistributedSystems_Lab4
{
    [Route("api/worker")]
    [ApiController]
    public class WorkerController : ControllerBase
    {
        private readonly WorkerFileStorageService workerStorage;
        private readonly ILogger logger;
        private readonly MetadataService metadataService;
        private readonly IHttpClientFactory httpClientFactory;

        public WorkerController(
            WorkerFileStorageService workerStorage,
            ILogger<WorkerController> logger,
            MetadataService metadataService,
            IHttpClientFactory httpClientFactory)
        {
            this.workerStorage = workerStorage;
            this.logger = logger;
            this.metadataService = metadataService;
            this.httpClientFactory = httpClientFactory;
        }

        [HttpPut("save/{key}")]
        public async Task<IActionResult> Save(string key, [FromForm] IFormFile file)
        {
            if (file == null || file.Length == 0)
                return BadRequest("Файл не передан или пуст.");

            const int blockSize = 5 * 1024 * 1024;
            List<(string blockName, string WorkerUrl)> metadata = new();
            var chord = workerStorage.getChordRing();

            using var stream = file.OpenReadStream();
            int index = 0;
            byte[] buffer = new byte[blockSize];
            int bytesRead;

            while ((bytesRead = await stream.ReadAsync(buffer, 0, buffer.Length)) > 0)
            {
                var partName = $"{file.FileName}_part_{index}";
                var node = chord.FindResponsibleNode(partName);

                var client = httpClientFactory.CreateClient();
                using var content = new MultipartFormDataContent();
                using var blockStream = new MemoryStream(buffer, 0, bytesRead);

                // Гарантируем, что поток начинает чтение с первого байта
                blockStream.Position = 0;

                content.Add(new StreamContent(blockStream), "file", partName);

                var response = await client.PutAsync($"{node.Url}/store/{key}", content);
                if (response.IsSuccessStatusCode)
                {
                    metadata.Add((partName, node.Url));
                    logger.LogInformation($"Блок {index} успешно сохранен на {node.Url}");
                }
                else
                {
                    logger.LogWarning($"Не удалось сохранить блок {index} на {node.Url}. Код ответа: {response.StatusCode}");
                }

                index++;
            }

            if (metadata.Count == index)
            {
                try
                {
                    metadataService.SaveFileName(key, file.FileName);
                    metadataService.SaveFileMetadata(key, metadata);
                    logger.LogInformation($"Метаданные для файла {key} успешно сохранены.");
                }
                catch (Exception ex)
                {
                    logger.LogError($"Ошибка при сохранении метаданных для файла {key}: {ex.Message}");
                    return StatusCode(500, "Ошибка при сохранении метаданных.");
                }
            }

            return Ok("Файл сохранён.");
        }



        [HttpGet("download/{key}")]
        public async Task<IActionResult> Download(string key)
        {
            string fileName = metadataService.GetFileName(key);
            logger.LogWarning($"Запрос на скачивание файла {fileName}");
            var parts = metadataService.GetFileMetadata(key);
            if (parts == null || parts.Count == 0)
                return NotFound("Файл не найден.");

            var client = httpClientFactory.CreateClient();
            var memoryStream = new MemoryStream();

            foreach (var (partName, url) in parts.OrderBy(p => p.partName))
            {
                var response = await client.GetAsync($"{url}/store/{partName}");
                if (!response.IsSuccessStatusCode)
                {
                    logger.LogWarning($"Не удалось скачать блок {partName} с {url}");
                    continue;
                }

                var blockStream = await response.Content.ReadAsStreamAsync();
                await blockStream.CopyToAsync(memoryStream);
            }

            memoryStream.Position = 0;
            return File(memoryStream, "application/octet-stream", fileName);
        }

        [HttpGet("has/{key}")]
        public IActionResult HasBlock(string key)
        {
            bool exists = metadataService.KeyExists(key);
            if (exists)
            {
                logger.LogInformation($"Блок с ключом {key} существует.");
                return Ok($"Блок с ключом {key} существует.");
            }
            else
            {
                logger.LogInformation($"Блок с ключом {key} не найден.");
                return NotFound($"Блок с ключом {key} не найден.");
            }
        }

        [HttpDelete("delete/{key}")]
        public async Task<IActionResult> Delete(string key)
        {
            var parts = metadataService.GetFileMetadata(key);
            if (parts == null || parts.Count == 0)
                return NotFound("Файл не найден.");

            var client = httpClientFactory.CreateClient();
            bool allDeleted = true;

            foreach (var (part, url) in parts)
            {
                var response = await client.DeleteAsync($"{url}/store/{key}_part_{part}");
                if (!response.IsSuccessStatusCode)
                {
                    logger.LogWarning($"Не удалось удалить блок: {key}_part_{part} на {url}");
                    allDeleted = false;
                }
                else
                {
                    logger.LogInformation($"Блок {key}_part_{part} успешно удалён с {url}");
                }
            }

            try
            {
                metadataService.DeleteFileMetadata(key);
                logger.LogInformation($"Метаданные для файла {key} успешно удалены.");
            }
            catch (Exception ex)
            {
                logger.LogError($"Ошибка при удалении метаданных для файла {key}: {ex.Message}");
                return StatusCode(500, "Ошибка при удалении метаданных.");
            }

            return allDeleted ? Ok("Файл удалён.") : StatusCode(500, "Удаление выполнено частично.");
        }

        [HttpGet("listFiles")]
        public IActionResult ListFiles()
        {
            var files = workerStorage.ListAllKeys();
            return Ok(files);
        }
    }
    }

WorkerFileStorageService.cs:

using DistributedSystems_Lab4;

public class WorkerFileStorageService
{
    private readonly ILogger logger;
    private readonly HttpClient httpClient;
    private readonly ChordRing chordRing;
    public readonly MetadataService metadataService;
    private readonly string storagePath = "/app/storage/";

    public WorkerFileStorageService(
        HttpClient httpClient,
        ILogger<WorkerFileStorageService> logger,
        MetadataService metadataService)
    {
        this.httpClient = httpClient;
        this.logger = logger;
        this.chordRing = new ChordRing();
        this.metadataService = metadataService;

        if (!Directory.Exists(storagePath))
            Directory.CreateDirectory(storagePath);

        InitializeChordRing();
    }

    public ChordRing getChordRing()
    {
        return chordRing;
    }

    private void InitializeChordRing()
    {
        var nodeUrls = new[]
        {
            "http://worker1:5001",
            "http://worker2:5002",
            "http://worker3:5003",
            "http://worker4:5004",
            "http://worker5:5005"
        };

        foreach (var url in nodeUrls)
        {
            chordRing.AddNode(url);
            logger.LogInformation($"Добавлен узел в ChordRing: {url}");
        }

        chordRing.InitializeFingerTables();
    }

    public async Task SaveBlockAsync(string partName, IFormFile file)
    {
        var path = Path.Combine(storagePath, partName);
        using var stream = new FileStream(path, FileMode.Create);
        await file.CopyToAsync(stream);

        logger.LogInformation($"Блок {partName} сохранён локально.");
    }

    public async Task<Stream?> GetBlockAsync(string partName)
    {
        var path = Path.Combine(storagePath, partName);
        if (!File.Exists(path))
        {
            logger.LogWarning($"Файл {partName} не найден");
            return null;
        }

        return new FileStream(path, FileMode.Open, FileAccess.Read);
    }

    public bool DeleteBlock(string key)
    {
        var path = Path.Combine(storagePath, key);
        if (!File.Exists(path)) return false;

        try
        {
            File.Delete(path);
            logger.LogInformation($"Блок {key} успешно удалён");
            return true;
        }
        catch (Exception ex)
        {
            logger.LogError($"Ошибка при удалении блока {key}: {ex.Message}");
            return false;
        }
    }
    public bool HasBlock(string key)
    {
        return File.Exists(Path.Combine(storagePath, key));
    }
    public List<string> ListAllKeys()
    {
        var files = Directory.GetFiles(storagePath)
                             .Select(Path.GetFileName)
                             .Where(name => !string.IsNullOrEmpty(name))
                             .ToList();

        return files!;
    }
}
c#
  • 1 个回答
  • 35 Views
Martin Hope
VaNoo00
Asked: 2025-04-19 15:49:39 +0000 UTC

给出了一个一维整数数组。将数字 k 插入到所有包含数字 1 的元素之前。这必须使用右移来完成

  • 5

我找不到代码中的错误,改变时数组输出不正确。

在此处输入图片描述

static void Main(string[] args)
{
    Console.WriteLine("Введите размерность массива");
    int n = Convert.ToInt32(Console.ReadLine());
    int[] m = new int[n * 2];
    int k = 0;
    Random r = new Random();
    Console.WriteLine("Начальный массив");

    for (int i = 0; i < n; i++)
    {
        m[i] = r.Next(-100, 100);
        Console.Write("{0,5}", m[i]);
    }
    Console.WriteLine();

    int a = 0;
    int count = 0;
    for (int i = 0; i < n; i++)  
    {
        int d = 0;
        a = Math.Abs(m[i]);
        while (a > 0)
        {
            if (a % 10 == 1)
            {
                d = 1;
            }
            a /= 10;
        }
        if (d == 1)
        {
            count++;

            for (int p = n + count - 1; p > i + count - 1; p--)
            {
                m[p] = m[p - 1];
            }

            m[i + count - 1] = k;
            i++;

        }
    }

    Console.WriteLine("Измененный массив");
    for (int i = 0; i < n + count; i++)
    {
        Console.Write("{0,5}", m[i]);
    }
    Console.WriteLine();
}
c#
  • 2 个回答
  • 76 Views

Sidebar

Stats

  • 问题 10021
  • Answers 30001
  • 最佳答案 8000
  • 用户 6900
  • 常问
  • 回答
  • Marko Smith

    我看不懂措辞

    • 1 个回答
  • Marko Smith

    请求的模块“del”不提供名为“default”的导出

    • 3 个回答
  • Marko Smith

    "!+tab" 在 HTML 的 vs 代码中不起作用

    • 5 个回答
  • Marko Smith

    我正在尝试解决“猜词”的问题。Python

    • 2 个回答
  • Marko Smith

    可以使用哪些命令将当前指针移动到指定的提交而不更改工作目录中的文件?

    • 1 个回答
  • Marko Smith

    Python解析野莓

    • 1 个回答
  • Marko Smith

    问题:“警告:检查最新版本的 pip 时出错。”

    • 2 个回答
  • Marko Smith

    帮助编写一个用值填充变量的循环。解决这个问题

    • 2 个回答
  • Marko Smith

    尽管依赖数组为空,但在渲染上调用了 2 次 useEffect

    • 2 个回答
  • Marko Smith

    数据不通过 Telegram.WebApp.sendData 发送

    • 1 个回答
  • Martin Hope
    Alexandr_TT 2020年新年大赛! 2020-12-20 18:20:21 +0000 UTC
  • Martin Hope
    Alexandr_TT 圣诞树动画 2020-12-23 00:38:08 +0000 UTC
  • Martin Hope
    Air 究竟是什么标识了网站访问者? 2020-11-03 15:49:20 +0000 UTC
  • Martin Hope
    Qwertiy 号码显示 9223372036854775807 2020-07-11 18:16:49 +0000 UTC
  • Martin Hope
    user216109 如何为黑客设下陷阱,或充分击退攻击? 2020-05-10 02:22:52 +0000 UTC
  • Martin Hope
    Qwertiy 并变成3个无穷大 2020-11-06 07:15:57 +0000 UTC
  • Martin Hope
    koks_rs 什么是样板代码? 2020-10-27 15:43:19 +0000 UTC
  • Martin Hope
    Sirop4ik 向 git 提交发布的正确方法是什么? 2020-10-05 00:02:00 +0000 UTC
  • Martin Hope
    faoxis 为什么在这么多示例中函数都称为 foo? 2020-08-15 04:42:49 +0000 UTC
  • Martin Hope
    Pavel Mayorov 如何从事件或回调函数中返回值?或者至少等他们完成。 2020-08-11 16:49:28 +0000 UTC

热门标签

javascript python java php c# c++ html android jquery mysql

Explore

  • 主页
  • 问题
    • 热门问题
    • 最新问题
  • 标签
  • 帮助

Footer

RError.com

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

帮助

© 2023 RError.com All Rights Reserve   沪ICP备12040472号-5