Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

передача побайтно

290
05 февраля 2010 года
Patr1ot
458 / / 09.02.2008
Здраствуйте уважаемые форумчане...

у меня к вам небольшой вопрос.
Имеется файл в сети возможен ли такой способ его копирования:
по действиям:
1) узнаем размер файла
2) присваеваем каждому байту свой порядковый номер
3) создаем два потока
4) каждый поток копирует свои номера байт из удаленного файла


Возможно ли организовать такую работу копирования?
Подскажите в какую сторону копать пожалуйста...
Страницы:
386
05 февраля 2010 года
newcss
297 / / 05.04.2005
Если честно, то не вижу в этом смысла).
А в принципе,кажется seek и read тебе в помощь.
9
05 февраля 2010 года
Lerkin
3.0K / / 25.03.2003
Цитата: Patr1ot

2) присваеваем каждому байту свой порядковый номер


Вот тут хотелось бы по-подробнее узнать, как автор себе это представляет.

63
06 февраля 2010 года
Zorkus
2.6K / / 04.11.2006
каждый поток копирует свои номера байт из удаленного файла

Хм. Если это то, что я понял, то копирование номеров байт (!) займет раз так в N больше времени, чем копирование файла. Вообще попахивает бредом и выглядит так же...
5
06 февраля 2010 года
hardcase
4.5K / / 09.08.2005
Цитата: Zorkus
каждый поток копирует свои номера байт из удаленного файла

Хм. Если это то, что я понял, то копирование номеров байт (!) займет раз так в N больше времени, чем копирование файла. Вообще попахивает бредом и выглядит так же...


Это он мультиплексированием хотел заняться. Такой подход используют "качалки" - тянут файл по разным смещениям, как известно, способ может лучше использовать пропускную способность канала.

290
06 февраля 2010 года
Patr1ot
458 / / 09.02.2008
вот код...

Код:
TFileStream * Stream1 = new TFileStream("C:\\123\\restored.exe",Sysutils::fmOpenRead);
 TFileStream * Stream2 = new TFileStream("C:\\Restored.exe",fmCreate|Sysutils::fmOpenRead);
 
 __try
  {
   Stream2->CopyFrom(Stream1,Stream1->Seek(Stream1->Size/2,soFromBeginning));
  }
  __finally{
      Stream2->Free();
  }
  Stream1->Free();


Имеется поток Stream1... Но задача в следующем
всего должно быть 4 потока, и каждый из них должен копировать по
1\4 части размера файла... причем каждый поток свою часть файла...
немогу сообразить как это реализовать даже методом Seek(); этого недобиться.... а очень надо...

_______________________________________________

Не пытайтесь придумывать разные глупости о том: "Че это он там пытается реализовать?"... Отвечу так надо...
1
06 февраля 2010 года
kot_
7.3K / / 20.01.2000
Сказали ведь уже - должно быть смещение от начала файла и размер читаемой области для каждого потока. Для того размер файла делим на количество потоков и получаем искомое
36K
07 февраля 2010 года
sstorm
55 / / 25.03.2009
Кстати интересный вопрос.
Автору: если использовать для файла такое:
FILE* f;
f = fopen(name,"rb");
То можно fseek'ом выставлять маркер и читать из нужных мест. Но я сомневаюсь, что на деле это можно будет осуществить, т.к. система поставит блок на файл и кинет ошибку, если к нему обратятся 2 потока сразу.
Но если найдёшь способ - не забудь отписать
290
07 февраля 2010 года
Patr1ot
458 / / 09.02.2008
Цитата: sstorm
Кстати интересный вопрос.
Автору: если использовать для файла такое:
FILE* f;
f = fopen(name,"rb");
То можно fseek'ом выставлять маркер и читать из нужных мест. Но я сомневаюсь, что на деле это можно будет осуществить, т.к. система поставит блок на файл и кинет ошибку, если к нему обратятся 2 потока сразу.
Но если найдёшь способ - не забудь отписать



Да я с такой проблемой столкнулся... уже...
я немного переделал текст, и решил брать из потока в котором у нас искомый файл( тоесть тот который на надо скопировать)...
до этого я использовал метод CopyFrom(); но оно не подошло, именно по той причине что вы указали, поэтому я рышил, помещать все содержимое в буфер, но столкнулся с другой проблемой... Для примера я одним потоком копировал содержимое файла начиная от 0 байт до 72 байта, а вторым копировал от 72 до 144 (я для примера заранее узнал размер файла, исходя из чего поделил его пополам) , в результате проблема в том как эти данные сохранить в один и тот же файл, получается токо половина от 0 байт до 72 байт а следующие 72 байта при записи из потока в файл вылетает ошибка Stream Read Error .

Вот код:

Код:
TFileStream * Stream1 = new TFileStream("C:\\123\\restored.txt",Sysutils::fmOpenRead);
 TFileStream * Stream2 = new TFileStream("C:\\Restored.txt",fmCreate|Sysutils::fmOpenWrite);
TFileStream * Stream3 = new TFileStream("C:\\Restored2.txt",fmCreate|Sysutils::fmOpenWrite);

 char buf[1024];
 char buf2[1024];
 
 Stream1->Seek(72,0);
 Stream1->ReadBuffer(buf,72);
 Stream1->Seek(72,71);
 Stream1->ReadBuffer(buf2,72);
 Stream2->WriteBuffer(buf,72);
 
 Stream3->WriteBuffer(buf2,144);

Stream2->Free();
 Stream3->Free();
 Stream1->Free();

Вот тут уменя все какбы работает, то есть содержимое файла Restored.txt
забирает первую от начала половину Stream2(записывается в C:\Restored.txt), а вторую от середины забирает Stream3 (записывается в C:\Restored2.txt), и опять же в один файл незаписывается, ненаю что делать..

Может кто подскажет...

А насчет FILE*f;
Я незнаю ничего о маркерах я токо знаю что приведенный вами метод это типизированная работа с файлами, в ней мне кажется меньше возможности чем в нетипизировнной (TFileStream)...
Ну если вашим методом решается такая проблема, то будьте добры поделитесь...
36K
07 февраля 2010 года
sstorm
55 / / 25.03.2009
если не против, то мне как-то проще на "ты".

Имхо, тут о типизированности файлов говорить не приходится. Я тоже читаю байтами. Просто FILE* это С, а вот такие потоки, это уже что-то плюсовое, поэтому мне похуже знакомо.
Маркером я назвал указатель на позицию в файле, откуда читаем/пишем. Ну т.е. seek в твоём коде.

Если не сложно, прокомментируй строки Stream1->Seek(72,71); и Stream3->WriteBuffer(buf2,144);
Мне как-то неочевидны параметры.

И не совсем понятно, что же в итоге хотим получить, т.к. в этом коде не вижу потоков.

Вообще, логика должна быть где-то такой:
Узнаём размер файла.

Делим размер на количество потоков (пусть 2). Получаем сколько байт на поток приходится (пусть M)

Потоки нумеруем с 0.

Для каждого потока устанавливаем маркер на (начало + M*№потока). Читаем М байт в заранее отведённый массив. Но располагаем данные в массиве не абы как, а опять же, начиная с (начало + М*№потока). ТО есть первый поток читает первые 72 байта файла и пишет их в буффер на позиции 0-71. Второй поток читает вторую часть файла и пишет на позиции 72-143. В итоге весь файл лежит в массиве.

Теперь массив надо слить в новый файл. Это либо легко делается одним потоком, либо тоже хотим распараллелить. Но тут опять же сложность. Мы не сможем для 2ого и дальнейших потоков указать маркеру место. Второй должен писать с 73 байта. но seek не позволит встатть на 73, т.к. пока первый поток не отработал, то файл не имеет такого размера. Тут я вижу выход в заведомом создании пустого фейкового файла нужного размера просто из нулей.

Всё. но остались 2 проблемы, решения которых я придумать не могу. Представим ситуацию, что первый поток при чтении исходного файла делает seek на начало. Тут происходит прерывание и второй поток делает seek на 73ий байт. Второй поток читает свою половину файла и пишет в нужные места массива. тут снова прерывание и первый поток, считая что маркер seek на начале, читает свои 72 байта. Только вот на самом деле seek уже на конце...
И если решить проблему мьютексами, то это убьёт все плюсы многопоточности
290
08 февраля 2010 года
Patr1ot
458 / / 09.02.2008
Цитата: sstorm
если не против, то мне как-то проще на "ты".

Имхо, тут о типизированности файлов говорить не приходится. Я тоже читаю байтами. Просто FILE* это С, а вот такие потоки, это уже что-то плюсовое, поэтому мне похуже знакомо.
Маркером я назвал указатель на позицию в файле, откуда читаем/пишем. Ну т.е. seek в твоём коде.

Если не сложно, прокомментируй строки Stream1->Seek(72,71); и Stream3->WriteBuffer(buf2,144);
Мне как-то неочевидны параметры.

И не совсем понятно, что же в итоге хотим получить, т.к. в этом коде не вижу потоков.

Вообще, логика должна быть где-то такой:
Узнаём размер файла.

Делим размер на количество потоков (пусть 2). Получаем сколько байт на поток приходится (пусть M)

Потоки нумеруем с 0.

Для каждого потока устанавливаем маркер на (начало + M*№потока). Читаем М байт в заранее отведённый массив. Но располагаем данные в массиве не абы как, а опять же, начиная с (начало + М*№потока). ТО есть первый поток читает первые 72 байта файла и пишет их в буффер на позиции 0-71. Второй поток читает вторую часть файла и пишет на позиции 72-143. В итоге весь файл лежит в массиве.

Теперь массив надо слить в новый файл. Это либо легко делается одним потоком, либо тоже хотим распараллелить. Но тут опять же сложность. Мы не сможем для 2ого и дальнейших потоков указать маркеру место. Второй должен писать с 73 байта. но seek не позволит встатть на 73, т.к. пока первый поток не отработал, то файл не имеет такого размера. Тут я вижу выход в заведомом создании пустого фейкового файла нужного размера просто из нулей.

Всё. но остались 2 проблемы, решения которых я придумать не могу. Представим ситуацию, что первый поток при чтении исходного файла делает seek на начало. Тут происходит прерывание и второй поток делает seek на 73ий байт. Второй поток читает свою половину файла и пишет в нужные места массива. тут снова прерывание и первый поток, считая что маркер seek на начале, читает свои 72 байта. Только вот на самом деле seek уже на конце...
И если решить проблему мьютексами, то это убьёт все плюсы многопоточности



Вот сматри размер файла хранится в Stream1->Size; (Это и есть размер файла в байтах);

Stream1->seek(x,y) - где x - это количество считываемых байт, а y - это начало отсчета, то есть с какого байта начинать считывать, ну тот же самы маркер как ты сказал...

Stream1->ReadBuffer(buf,72);
Это мы считываем в буфер содержимое потока Stream1 данные от 0 до 72 байта, а
Stream2->WriteBuffer(buf,72);
Это мы записываем содержимое буфера buf в новый поток для далнейшего сохранения на жесткий диск...

Проблема в том что, раздельно считанные данные неполучается обьединить в той же последовательности , да и не токо в той же последовательности вообще никак неполучается их обьединить...

То есть как у меня в коде написано я записал в поток Stream2 - содержимое копируемого файла с 0 по 72 байт, а в поток Stream3 - тоже содержимое копируемого файла токо с 72 по 144 байт ( общий размер файла 144 байта)...
И тут возникла проблема, как эти потоки сохранить в один и тот же файл...
Удается сохранить токо один поток, а не оба, то есть либо Stream2 либо Stream3, при попытки записать второй поток вылетает ошибка Stream read error... но при сохранение потоков в разные файлы тоесть Stream2 сохраняю в Restored.txt а Stream3 сохраняю в Restored2.txt в обоих файлах содержимое соответствует половине начального файла ( тот что загружен в Stream1)

Впринцепе проблема токо в этом как сохранить два потока в один файл...
Ну как бы содержимое потоков еще и в буферах Buf, и buf2 Хранится пробовал в поток добавить сначало buf потом buf2 но чет нече не получилось...

290
08 февраля 2010 года
Patr1ot
458 / / 09.02.2008
Проблема решена но не доконца....
Вот рабочий код все работает...
Код:
#include <vcl.h>
#include <fstream>
#pragma hdrstop

#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;

//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
    : TForm(Owner)
{
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
 TFileStream * Stream1 = new TFileStream("C:\\123\\restored.txt",Sysutils::fmOpenRead);
 TFileStream * Stream2 = new TFileStream("C:\\Restored.txt",fmCreate|Sysutils::fmOpenWrite);

 char buf[1024];
 char buf2[1024];
 ////////////////////////////////////////////////////////////////////////////
 Stream1->Seek(72,145);
 Stream1->ReadBuffer(buf,72);
 Stream2->WriteBuffer(buf,72);
 Stream1->Free();
 Stream2->Free();
 ///////////////////////////////////////////////////////////////////////////
 TFileStream * Stream4 = new TFileStream("C:\\123\\restored.txt",Sysutils::fmOpenRead);
 TFileStream * Stream3 = new TFileStream("C:\\Restored.txt",Sysutils::fmOpenWrite);
 Stream4->Seek(72,0);
 Stream4->ReadBuffer(buf2,72);
 Stream3->Seek(72,0);
 Stream3->WriteBuffer(buf2,72);

 Stream3->Free();

 Stream4->Free();







}


Но теперь другая проблема, возможноли одновременное выполнение считывания байт обоими потоками?
290
08 февраля 2010 года
Patr1ot
458 / / 09.02.2008
Я моленько автоматизировал код))

Код:
#include <vcl.h>
#include <fstream>
#pragma hdrstop

#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;

//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
    : TForm(Owner)
{
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
 TFileStream * Stream1 = new TFileStream("C:\\123\\Restored.txt",Sysutils::fmOpenRead);
 TFileStream * Stream2 = new TFileStream("C:\\Restored.txt",fmCreate|Sysutils::fmOpenWrite);

 char buf[1024];
 char buf2[1024];
 ////////////////////////////////////////////////////////////////////////////
 Stream1->Seek(Stream1->Size/2,Stream1->Size+1);
 Stream1->ReadBuffer(buf,Stream1->Size/2);
 Stream2->WriteBuffer(buf,Stream1->Size/2);
 Stream1->Free();
 Stream2->Free();
 ///////////////////////////////////////////////////////////////////////////
 TFileStream * Stream4 = new TFileStream("C:\\123\\restored.txt",Sysutils::fmOpenRead);
 TFileStream * Stream3 = new TFileStream("C:\\Restored.txt",Sysutils::fmOpenWrite);
 Stream4->Seek(Stream4->Size/2,0);
 Stream4->ReadBuffer(buf2,Stream4->Size/2);
 Stream3->Seek(Stream4->Size/2,0);
 Stream3->WriteBuffer(buf2,Stream4->Size/2);

 Stream3->Free();

 Stream4->Free();







}



Столкнулся с еще одной проблемой, при выполнение копирования файла размером до 1000 байт все работает отлично, но при копирование большего размера файла, вылетает ошибка чтения потока (Stream read error). Пробовал размер буффера увеличить но почемуто при налаче выполнения выше указанного кода при увеличение размера буфера, программа закрывается...
290
09 февраля 2010 года
Patr1ot
458 / / 09.02.2008
че никто незнает как размер буфера корректно увеличить?
246
09 февраля 2010 года
GIZMO
1.8K / / 30.07.2004
Цитата: Patr1ot
че никто незнает как размер буфера корректно увеличить?



никогда так не делай

 
Код:
Stream3->Free();

для этого есть - delete;
36K
09 февраля 2010 года
sstorm
55 / / 25.03.2009
Чтобы распараллелить, создавай новые нити выполнения. В винапи это CreateThread. Список параметров точно не помню, но туда внутрь передаётся указатель на функцию, которую поток и исполнит.
DWORD WINAPI func(LPVOID param) { тут второй поток читает вторую часть файла}

в первом потоке прям в начале мэйна запустить второй
HANDLE th2 = CreateThread(..,&func,..);
а тут уже самому читать первую часть файла


Проблема буфера в том, что ты создаёшь их на 1024 байта только char buf[1024];
290
10 февраля 2010 года
Patr1ot
458 / / 09.02.2008
Цитата: sstorm
Чтобы распараллелить, создавай новые нити выполнения. В винапи это CreateThread. Список параметров точно не помню, но туда внутрь передаётся указатель на функцию, которую поток и исполнит.
DWORD WINAPI func(LPVOID param) { тут второй поток читает вторую часть файла}

в первом потоке прям в начале мэйна запустить второй
HANDLE th2 = CreateThread(..,&func,..);
а тут уже самому читать первую часть файла


Проблема буфера в том, что ты создаёшь их на 1024 байта только char buf[1024];



А можеш поподробней обьяснить про метод CreateThread(..,&func,..);
Как я понял он при выполнение процесса копирования в токок первой половины файла, запустит копирование в поток вторую полофину файла...

А про буфер, я же делал например char buf[5000000] но при начале
чтения в поток прога просто закрывалась, причем безо всяких на то сообщений.

290
10 февраля 2010 года
Patr1ot
458 / / 09.02.2008
Все равно неполучается....
Увеличиваю буфер до 1мб... (char buf[1000000];)
При начале чтения файла в буфер программа просто закрывается полностью...
Но при чтение в буфер файла с меньшим размером все работает нормально... в чем проблема немогу понять... подскажите пожалусто...

Код:
#include <vcl.h>
#include <fstream>
#pragma hdrstop

#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;

//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
    : TForm(Owner)
{
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
 TFileStream * Stream1 = new TFileStream("C:\\123\\1.txt",Sysutils::fmOpenRead); //Создаем поток Stream1
 TFileStream * Stream2 = new TFileStream("C:\\Restored2.exe",fmCreate|Sysutils::fmOpenWrite); //Создаем поток Stream2

 char buf[1000000]; //Указываем буфер
 
 
 ////////////////////////////////////////////////////////////////////////////
 Stream1->Seek(Stream1->Size,Stream1->Size+1); //Устанавливаем маркер считывания файла (Поток->Seek(Общий считываемый размер,Начало считывания)
 Stream1->ReadBuffer(buf,Stream1->Size); //Считываем данные в буфер buf
 Stream2->WriteBuffer(buf,Stream1->Size); //записываем данные из буфера buf в поток Stream2




 Stream1->Free(); //Закрываем поток Stream1
 Stream2->Free(); //Закрываем поток Stream2

 }
290
11 февраля 2010 года
Patr1ot
458 / / 09.02.2008
Решил проблему, с буфером...
данные из файла вроде как правильно считываются потому что в коннечном итоге мы имеем аналогичный файл, из которого считывали данные... но по окончание считывания почему все равно вылетает ошибка Stream read error...

Может кто подскажет из-за чего?

Код:
#include <vcl.h>
#include <fstream>
#pragma hdrstop

#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;

//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
    : TForm(Owner)
{
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
 TFileStream * Stream1 = new TFileStream("C:\\123\\r.txt",Sysutils::fmOpenRead);
 TFileStream * Stream2 = new TFileStream("C:\\Restored2.mp3",fmCreate|Sysutils::fmOpenWrite);
 int i;
 char buf[1024];
 __try
 {
      for (i = 0; i < Stream1->Size; i++)
       {
       if(buf=="80")
       {
         buf==0;
         i=i-1;
       }
       else
       {

       Stream1->ReadBuffer(buf,80);
       Stream2->WriteBuffer(buf,80);
       Label1->Caption=i;
       }
       if (i==Stream1->Size)
        {
         Stream2->Free();
         Stream1->Free();
       }
        {

       }
      }


 }
 __finally
 {
     Stream2->Free();
 }
 Stream1->Free();


}
290
12 февраля 2010 года
Patr1ot
458 / / 09.02.2008
Всем спасибо... вопрос с побайтным копированием решен...

Есть другой вопрос...

Вновь воспользуюсь мои примером, который я указывал выше...
проблема в том что, например потоки Stream1 и Stream2 уже выполняют считывание в программе, и тут новое обращение на считывание нового файла, тоесть нужно чтобы программа как то (даж незнаю как это назвать) сама создала с рандомным названием новых потоков для выполнения новой задачи считывания байт...

Возможно ли вообще такое? И если кто знает в какую сторону капать?

За помощ я обязательно добавлю вес репутации...
14
12 февраля 2010 года
Phodopus
3.3K / / 19.06.2008
Цитата: Patr1ot

Возможно ли вообще такое? И если кто знает в какую сторону капать?


массив потоков?

 
Код:
TFileStream* stream_arr[100];
stream[0] = new TFileStream(...)
36K
12 февраля 2010 года
sstorm
55 / / 25.03.2009
А что значит "ещё 1 запрос" ?

Запрос - это, видимо, вызов конкретной функции из потока. Тогда если сделать FileStream локальными внутри функции, то это решает проблему. Т.е. при каждом вызове Stream1, stream2 свои.

зы: а проблему с многопоточным чтением/записью как решил?
290
12 февраля 2010 года
Patr1ot
458 / / 09.02.2008
Вот блин незадача, еще с одной проблемой сталкнулся...

Код:
TFileStream * Stream1 = new TFileStream(Patch,Sysutils::fmOpenRead);
 TFileStream * Stream2 = new TFileStream(Output,fmCreate|Sysutils::fmOpenWrite);

 char buf[1024];
 __try
 {

      for (i = 0; i < Stream1->Size/32; i++) {

       Stream1->Seek(i*32,Stream1->Size);
       Stream1->ReadBuffer(buf,32);
       Stream2->WriteBuffer(buf,32);


     }
   }
 __finally
 {
     Stream2->Free();
 }
 Stream1->Free();


Попробую правильно сформулировать...
Выше указанный код считывает данные из файла указанного в потоке Stream1 переменной Patch(путь к файлу), в Stream2 и сохраняет в Output(путь к файлу), проблема в том что, предположим действия по коду...
по условию for цикл будет идти столько раз скольки равняется размер файла деленного на 32...
Для примера у нас имеется файл размером 100 байт...
то после разделения его на 32 получится 3,1.

но проблема в том что из этих 100 байт выполнится(скопируется, считается) токо 96 байт...

Я так понимаю что это из за того что i является переменной типа int, но я указывал и i типа float и тем не менее была таже проблема...

В чем моя ошибка подскажите пожалуйста знающие люди...
14
12 февраля 2010 года
Phodopus
3.3K / / 19.06.2008
Вообще обычно, при копировании, файл читают до того места с которого он перестает читаться...
290
12 февраля 2010 года
Patr1ot
458 / / 09.02.2008
Цитата: Phodopus
Вообще обычно, при копировании, файл читают до того места с которого он перестает читаться...



Но почему, если размер файла 100 байт, он и после даже неоднократного копирования будет оставаться равным 100 байт...

Мне кажется просто в моем коде считывание файла побайтно организовано неправильно, ведь цикл for несможет выполниться например 3,5 раза а токо 3.Поэтому остаток равный меньшему такту считывания за цикл( у меня это 32) будет оставаться не считанным. А как заставить этот код считать все до конца. Конечно можно установить такт считывания равным 1 то тогда само считывание данных из файла очень долго длится. Я вот вообще его делал 1кб, скорость копирования при этом была быстрее чем тот же файл копировала Винда.

Люди подскажите что не так в моем коде...

36K
12 февраля 2010 года
sstorm
55 / / 25.03.2009
int ostatok = Size%32;
получаешь сколько байт не влезло в копирование циклом. (в твоём случае 4)


соответственно, ставишь маркер чтения за 4 байта до окончания файла и читаешь эти 4 байта.

Только весь этот код - однопоточное чтение файла, просто в несколько приёмов
290
12 февраля 2010 года
Patr1ot
458 / / 09.02.2008
Да ты прав это капирование просто в несколько приемов, просто я еще не дошол до распеределения по разбитию на разные потоки...
хотел доработать этот пример доконца...

ща попробую... твое предложение... по выходу из ситуации...
290
13 февраля 2010 года
Patr1ot
458 / / 09.02.2008
Цитата: sstorm

Только весь этот код - однопоточное чтение файла, просто в несколько приёмов



Для одновременного выполнения одной и тойже функцией тебе нужно добавить в проект Thread Object, внем описать функцию считывания потока.

36K
14 февраля 2010 года
sstorm
55 / / 25.03.2009
ну как, получилось, что пытался сделать?
290
16 февраля 2010 года
Patr1ot
458 / / 09.02.2008
Цитата: sstorm
ну как, получилось, что пытался сделать?



Я столкнулся с еще одной проблемой...

При создание потока нужно сделать открытие файла не в монопольном режиме.. Посколку из-за етого второй паралельно запущенный поток не может получить доступ к файлу...
Я знаю что в функции TFileStream есть флаги которае указывают на способ открытия файла - fmOpenRead - открыть файл для чтения, fmOpenWrite - открыть файл для записи, fmCreate - создать файл..
я знаю это не все флаги, должен быть флаг открывающий файл не в монопольном режиме, но какой чета пока немогу найти...

кто знает подскажите пожалуста...

36K
16 февраля 2010 года
sstorm
55 / / 25.03.2009
я не знаю таких классов и констант, соответствено. Вероятно, это что-то борландовское. Но, по крайней мере в студии, есть возмжность нажать правой кнопкой на футоде/константе/макросе и посмотреть её определение. Типа файл откроется, где описно. Попробуй так айти файл с описанем fmOpenRead. Вероятно, в этом же файле описаны все способы открытия
290
18 февраля 2010 года
Patr1ot
458 / / 09.02.2008
Цитата: sstorm
я не знаю таких классов и констант, соответствено. Вероятно, это что-то борландовское. Но, по крайней мере в студии, есть возмжность нажать правой кнопкой на футоде/константе/макросе и посмотреть её определение. Типа файл откроется, где описно. Попробуй так айти файл с описанем fmOpenRead. Вероятно, в этом же файле описаны все способы открытия



Я перепробовал все флаги... толку нет... выполняется токо один паток, а второй пишет нет доступа к файлу, или файл занят другим процессом...
Я думаю дело в методе TFileStream наверное надо поискать какой то другой метод который будет обращаться к файлу не в монопольном режиме....
Кто знает подскажите пожалуйста..

1
18 февраля 2010 года
kot_
7.3K / / 20.01.2000
 
Код:
TFileStream* stream=new TFileStream(FilePath,fmOpenRead|fmShareCompat)

разве не работает?
290
19 февраля 2010 года
Patr1ot
458 / / 09.02.2008
Цитата: kot_
 
Код:
TFileStream* stream=new TFileStream(FilePath,fmOpenRead|fmShareCompat)

разве не работает?



Я так пробовал, нет так неработает...

Вообще С.Бобровский пишет ...

Цитата:

Пока программа не прекратит обработку файла, его содержимое в определенный момент времени невозможно предсказать - информация может постоянно модифицироваться. Когда файл открывается на чтение, его внутренняя структура неизменяется. Поэтому несколько программ могут открыть файл на чтение. Другие варианты открытия файла подразумевают монопольную работу одной программы с ним.



Так вот как он пишет я так понял ето просто fmOpenRead, но
все равно токо один поток может работать с этим файлом...

14
19 февраля 2010 года
Phodopus
3.3K / / 19.06.2008
fmShareDenyWrite или fmShareDenyNone. Применять по смыслу.

Кстати:
static const Shortint fmShareCompat = 0x0;
так что...
290
19 февраля 2010 года
Patr1ot
458 / / 09.02.2008
Цитата: Phodopus
fmShareDenyWrite или fmShareDenyNone. Применять по смыслу.

Кстати:
static const Shortint fmShareCompat = 0x0;
так что...



Тоже неподошло пишет Stream read error...(((

А у вас разве этот флаг сработал?

290
20 февраля 2010 года
Patr1ot
458 / / 09.02.2008
Цитата: Phodopus
fmShareDenyWrite или fmShareDenyNone. Применять по смыслу.

Кстати:
static const Shortint fmShareCompat = 0x0;
так что...



Ссори, Все работает, вчера вчера чет не то делал...))))

16K
22 февраля 2010 года
asmforce
186 / / 05.01.2010
Цитата: sstorm

То можно fseek'ом выставлять маркер и читать из нужных мест. Но я сомневаюсь, что на деле это можно будет осуществить, т.к. система поставит блок на файл и кинет ошибку, если к нему обратятся 2 потока сразу.



"Сразу" два потока обратиться к файлу не могут. Оба потока пренадлежат одной ОС (и одному приложению), значит. Вы можете передавать потоку при его создании дескриптор файла и смещение. И потоки будут по-очереди читать и передавать!

Так что stdio.h:fseek или io.h:seek Вам в руки! Если хотите сделать потоки независимыми, можете открыть файл с Share Access - io.h:sopen (или подобные) в помощь.

290
23 февраля 2010 года
Patr1ot
458 / / 09.02.2008
Цитата: asmforce
"Сразу" два потока обратиться к файлу не могут. Оба потока пренадлежат одной ОС (и одному приложению), значит. Вы можете передавать потоку при его создании дескриптор файла и смещение. И потоки будут по-очереди читать и передавать!

Так что stdio.h:fseek или io.h:seek Вам в руки! Если хотите сделать потоки независимыми, можете открыть файл с Share Access - io.h:sopen (или подобные) в помощь.



Вы ошибаетесь... Я создал многопоточное прилошение, и использовал выше указанные флаги для открытия файла... все прекрасно работает... одновременно считывается информация 2 потоками. Первый считывает от 0 до половины байт, а второй от половины и до конца, но я использовал не seek а Position, мне показалось это удобней, чем использовать смещения seek.
Ток проблема.. оба потока одновременно считывают свою половину в свой буфер(buf1,buf2). Например в buf1 - от0 до 50байт, а в buf2 - от50 до 100 байт (весь файл 100байт). Как записатб это все в один буфер...
вот с этим проблема , пробовал сохранить каждый своим потоком но получается таким образом, что записывается токо какой то один поток, это скорее всего потому что в новый файл они записываться оба от 0 байта... и поэтому друг друга затирают...

7
23 февраля 2010 года
@pixo $oft
3.4K / / 20.09.2006
А какая проблема?Располагайте buf1 и buf2 друг за другом,1й поток считает в 1й буфер,а 2й–во 2й.Это же очевидно!
Не понимаю,что вызвало у вас проблему

Ну или код в студию
290
23 февраля 2010 года
Patr1ot
458 / / 09.02.2008
Цитата: @pixo $oft
А какая проблема?Располагайте buf1 и buf2 друг за другом,1й поток считает в 1й буфер,а 2й–во 2й.Это же очевидно!
Не понимаю,что вызвало у вас проблему

Ну или код в студию



Я так пробовал... Записываю buf1 тоесть

 
Код:
TFileStream * Fi = new TFileStream("C:\\1.txt",fmCreate|fmShareDanyNone);
Fi->WriteBuffer(buf1,100);

А потом и точно так же второй буфер buf2..
 
Код:
TFileStream * Fi = new TFileStream("C:\\1.txt",fmShareDanyNone);
Fi->WriteBuffer(buf2,100);

Обе записи выполняются паралельно, и после выполнения в файле токо половина всего файла, то есть либо содержимое buf1 ли бо buf2.

Вычитал, что для того чтобы записать информацию в файл без удаления уже имеющейся в ней записи необходимо открыть файл не на запись а на дозапись, в этом случае данные токо добавятся... но опять же вопрос каким флагом открыть файл на дозапись?
пробовал флаг fmOpenReadWrite, но происходит тоже самое, тоесть в файле, либо информация буфера buf1 ли бо buf2.

Если делать запись в файл последовательно, то последующие записи тоесть в данном примере buf2 должен открывать файл на дозапись, а первый создает файл и записывает в него первую половину информации от 0 байта до половины.
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог