U
U
uuuu2021-04-03 18:01:12
C++ / C#
uuuu, 2021-04-03 18:01:12

How to split a large file?

I have a 4gb file but I can only store 2gb on the server.
How can I split, download and merge a file into one?

Answer the question

In order to leave comments, you need to log in

3 answer(s)
G
ge, 2021-04-04
@gedev

You can do it with split and cat .

D
Diman89, 2021-04-05
@Diman89

In the same total commander: file / split (collect)

V
Vasily Bannikov, 2021-04-17
@vabka

using System;
using System.IO;
using System.Linq;

var command = args[0];
if (command == "split")
{
   // Чтобы разбить файл, нужно передать команду split ./path/to/file/test
    // В итоге в текущей папке появится папка result с чанками по 2кб, которые будут называться, как оригинальный файл, но с номером на конце.
   // например ./result/test1
   // ./result/test2 итд
    var filePath = args[1];
    const int chunkSize = 2 * 1024; // 2 KB
    await using var src = File.OpenRead(filePath);
    var fileName = Path.GetFileName(filePath);
    var chunkNo = 0;
    var buffer = new Memory<byte>(new byte[1024]); // 1 KB buffer

    Directory.CreateDirectory("result");
    var bytesInChunkWritten = 0;
    var currentChunk = File.OpenWrite(Path.Combine(Directory.GetCurrentDirectory(), "result", fileName + chunkNo));

    while (true)
    {
        var bytesRead = await src.ReadAsync(buffer);
        await currentChunk.WriteAsync(buffer[..bytesRead]);
        if (bytesRead < buffer.Length)
            break;
        bytesInChunkWritten += bytesRead;
        if (bytesInChunkWritten >= chunkSize)
        {
            await currentChunk.DisposeAsync();
            chunkNo += 1;
            currentChunk = File.OpenWrite(Path.Combine(Directory.GetCurrentDirectory(), "result", fileName + chunkNo));
            bytesInChunkWritten = 0;
        }
    }
}
else if (command == "merge")
{
    // Чтобы склеить файлы - нужно передать команду merge с путём к папке со всеми чанками и оригинальным названием файла
   // Например если оригинальный файл назывался test, то нужно дать команду merge ./result/test
  // В итоге в папке ./result появится оригнальный файл test
    var filePath = Path.GetFullPath(args[1]);
    var dir = Path.GetDirectoryName(filePath);
    var fileName = Path.GetFileName(filePath);
    // Сортируем все чанки в правильном порядке
    var chunks = Directory.GetFiles(dir!, fileName + "*")
        .Where(x => x.Length > filePath.Length)
        .OrderBy(x => int.Parse(x[filePath.Length..]));
    // Создаём файл
    var dest = File.OpenWrite(Path.Combine(dir, fileName));
    // Перекладываем всё в него
    foreach (var chunk in chunks)
    {
        await using var file = File.OpenRead(chunk);
        await file.CopyToAsync(dest);
    }
}

In a couple of minutes, I threw an example that quite successfully divides files into pieces of 2kb each and glues them back together.
The code is not perfect, and the algorithm itself can be improved - for example, add a hash of the original file so that you can check the integrity, or split into arbitrary pieces.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question