Возможно ли скопировать файл в несколько потоков? Если да, то как? Я пытаюсь сделать что-то подобное, но оно ожидаемо не работает:
using System;
using System.IO;
using System.IO.Compression;
using System.Threading;
namespace MyProgramm
{
class Copymaker
{
private int v_buffer_size;
FileStream input;
FileStream output;
public Thread thread1;
public Thread thread2;
public Copymaker(int buffer_size)
{
this.v_buffer_size = buffer_size;
}
public void Copy(FileInfo fileToCopy)
{
using (FileStream originalFileStream = fileToCopy.OpenRead())
{
using (FileStream copiedFileStream = File.Create(fileToCompress.FullName + ".new"))
{
input = originalFileStream;
output = copiedFileStream;
thread1 = new Thread(CopyBuffer);
thread1.Start();
}
Console.WriteLine("End?");
}
}
private void CopyBuffer()
{
byte[] buffer = new byte[v_buffer_size];
int bytesRead;
while ((bytesRead = input.Read(buffer, 0, buffer.Length)) > 0)
{
output.Write(buffer, 0, bytesRead);
}
}
}
}
В таком виде, конечно, не работает. Даже поток не запускается (говорит, нет доступа к закрытому потоку). Что я понимаю не верно?
Возможно ли скопировать файл в несколько потоков? Если да, то как?
Возможно. Например, именно так и делает Utorrent. Он сначала резервирует область памяти на винчестере а потом в куче потоков скачивает его из интернета когда это становится возможным (когда на раздаче кто-то появляется) и потом на определенную область зарезервированной памяти вносит изменения в виде бинарного кода с этой же области у оригинального файла из интернета.
А теперь перейдем к НЕЗАДАННОМУ вопросу: Имеет ли это смысл?
Распараллеливание дает прирост скорости исключительно на работе с CPU/GPU. Т.к. поток имеет свои ограничения, но незадействованного ресурса у CPU/GPU еще достаточно.
Но копирование, это работа с HDD. Работа с HDD не станет быстрее если копировать файл в несколько потоков. Она станет МЕДЛЕННЕЕ.
Почему?
Да потому, что HDD работает на основе физики и ты упрешься в возможности механики винчестера. Там есть читающая головка и есть "блин" который крутится с некоей скоростью. Именно по этому у HDD самая высокая скорость записи или чтения -- последовательная. То есть если на блине записаны данные последовательно -- чтение будет быстрым(относительно рандомно размещенных данных). Если нет -- головку нужно перемещать из одной позиции на другую. Распараллеливание задачи копирования сделает так, что головку нужно будет перемещать чаще(логично, не так ли?).
В случае с SSD ты не получишь замедления копирования. Но так же и прироста не получишь. Там нету механики, а это дает высокую скорость чтения/записи рандомно размещенных данных. Зато все равно есть ограничение по скорости. То есть точно так же... Ты хоть последовательно копируй данные, хоть параллельно -- ты получишь идентичную скорость.
А что если копировать через сеть? Например через Ethernet-кабель, получим ли мы желаемый профит? Снова таки нет. Мы упремся в ограничения скорости кабеля. Как упирались в скорость SSD.
А теперь когда мы выяснили что это возможно, но бессмысленно....
Стоит ли решать данную задачу тобой или кем-либо в принципе?)
Резервируешь место под будущий файл нужного размера https://stackoverflow.com/questions/8416413/create-new-file-with-specific-size
Создаешь метод для считывания: адрес файла, начальный байт, конечный байт. Ну или читалку которая считывает с оффсетом. Например такую: https://stackoverflow.com/questions/5208592/reading-parts-of-large-files-from-drive
Метод для обработки данных (что там тебе нужно с ними сделать я не знаю, но ты писал что это не просто копирование). Стоит учесть что я не знаю изменяется ли количество данных или нет, если изменяется хотя бы на один байт -- это стоит учитывать при записи в конечный файл.
метод для записи в конечный файл (адрес файла, начальный байт). https://stackoverflow.com/questions/9529313/write-byte-array-to-middle-of-an-existing-file-in-c-net
Вызываешь нужное количество потоков с вызовом этих методов. Можно попробовать как через таски так и через трэды.
Возможно ли скопировать файл в несколько потоков? Если да, то как?
Не вижу смысла в нескольких потоках на запись. Пусть даже вы и параллельно делаете какую-то работу, но пишущий поток должен быть только 1. Исключение, если вы пишите на разные физические диски.
Реализуйте логику через паттерн Производитель/Потребитель, где производитель- это множество вычислительных потоков, которые результаты своей работы ставят в какую-то потокобезопасную очередь, а потом потребитель- это пишущий поток, который поочередно извлекает блоки данных и пишет их на диск.
Виртуальный выделенный сервер (VDS) становится отличным выбором
Программа, написанная на С# 2013 Express, прекрасно работает на моем ПК (W 81) и у заказчика (W 7)
Есть пакет для работы с астериском под laravel - https://githubcom/enniel/ami Никак не получается настроить
Подскажите пожалуйста как указать границу регулярками в phpНеобходимо спарсить 12 ячеек начиная со слова bet365