|
음 우선 제글을 읽으시고 "이정도는 알지만 이런건 허접하자나" 라고 생각하실지도 모르겠습니다만.
저같으면 복사할곳의 화일을 전부 열고
버퍼에 저장된 소스를
일정량씩 짤라서 돌아가면서 Write 해주는게 좋을거 같습니다.
-_-;
그러면 자동으로 퍼센테이지도 측정할수 있고 중간중간
메세지 펌프질(Application->ProcessMessage()였던가)해주면
하실수 있겠네요.
물론 화일이 대용량이라면 문제가 있겟지만
잘라서 복사하는 양을 적당히 조절해 주시면
똑같이 끝나고 효율적이지 않을까 생각해 봅니다 ㅡ,.ㅡ; 넘 허접한가요 ㅠ.ㅠ
냉큼이 님이 쓰신 글 :
: 안녕하세요. 언제나 눈팅만 하는 아직은 허접초짜입니다.
:
: 한개의 파일을 여러개의 USB에 복사시켜주는 프로그램을 만들고 있습니다.
: 그런데 테스트로 3개의 USB에 파일을 복사하는 테스트를 하다가
: 어느 한 USB에만 많은 시간이 할당되는 경우가 나타나서 질문하게 되었습니다.
:
: 참고적으로, 스레드 클래스 안에서 메인폼의 리스트뷰를 갱신하고
: 스레드 클래스 안에서 프로그래스바를 생성했다가 소멸하는 루틴이 있기는 합니다만
: 이것이 어느 한쪽으로만 몰리는 이유가 될까요?
:
: 아니면, 한개의 파일을 여러군데에서 오픈하여 사용하기 때문에
: 이런 현상이 나타나는 걸까요?
:
: 이 현상을 해결하고자 고민하다가 예전에 배웠던 자바에서
: 각 스레드들에게 시간(?)을 균등하게 분배해주는 무엇이 있었다는 생각이 어렴풋이 들었습니다.
: 혹시 C++에도 그런게 있지 않을까 해서요.
:
: 아래는 현재의 소스 일부입니다.
:
: [main.cpp]
: -----------------------------------------------------------------------------------
: #include "ThreadUpGrade.h"
:
: ThreadUpGrade *UpThread[16];
: unsigned char DriveBuffer[26];
:
: __fastcall TFormMain::TFormMain(TComponent* Owner)
: : TForm(Owner)
: {
: int i;
:
: for (i = 0; i < 16; i++)
: {
: // 초기화
: UpThread[i] = NULL;
: }
: }
:
: void __fastcall TFormMain::BitBtnCopyClick(TObject *Sender)
: {
: int i;
:
: for (i = 0; i < GetConnectCount(); i++)
: {
: UpThread[i] = new ThreadUpGrade(true);
: UpThread[i]->ThdID = i;
: UpThread[i]->ThdDrive = DriveBuffer[i]; // 연결된 USB의 드라이브 문자 배열
: UpThread[i]->ThdActive = true;
: UpThread[i]->ThdListView = ListViewStat; // 스레드에서 메인폼의 리스트뷰를 컨트롤하기 위하여
: UpThread[i]->Resume();
: }
: }
: -----------------------------------------------------------------------------------
:
: [ThreadUpGrade.cpp]
: -----------------------------------------------------------------------------------
: void __fastcall ThreadUpGrade::Execute()
: {
: //---- Place thread code here ----
: TestFileCopy();
: }
:
: void ThreadUpGrade::TestFileCopy(void)
: {
: AnsiString source, target;
:
: source = "C:\\Test\\Test.DAT";
: target = (AnsiString)ThdDrive + ":\\Test.DAT";
: FileCopying(source, target, "Test.DAT");
: }
:
: bool ThreadUpGrade::FileCopying(AnsiString SourcePath, AnsiString TargetPath, AnsiString msg)
: {
: HANDLE hRead, hWrite;
: char buf[BUF_SIZE];
: DWORD dwret;
: int file_size, result;
: TRect rect;
:
: TListItem *tmpList;
: tmpList = ThdListView->Items->Item[ThdID];
:
: TProgressBar *pProgressBar = new TProgressBar(this);
: pProgressBar->Parent = ThdListView;
:
: // 소스파일을 얻어온다
: hRead = CreateFile(SourcePath.c_str(), GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, (HANDLE) NULL);
: if (hRead == INVALID_HANDLE_VALUE)
: {
: // ThdListView->Items->BeginUpdate();
: tmpList->SubItems->Strings[2] = "소스 파일을 찾을 수 없습니다.";
: // ThdListView->Items->EndUpdate();
: delete pProgressBar;
: CloseHandle(hWrite);
: return false;
: }
:
: // 대상파일을 얻어온다
: hWrite = CreateFile(TargetPath.c_str(), GENERIC_WRITE, FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, (HANDLE) NULL);
: if (hWrite == INVALID_HANDLE_VALUE)
: {
: // ThdListView->Items->BeginUpdate();
: tmpList->SubItems->Strings[2] = "대상 파일을 만들 수 없습니다.";
: // ThdListView->Items->EndUpdate();
: delete pProgressBar;
: CloseHandle(hRead);
: CloseHandle(hWrite);
: return false;
: }
:
: // 메인폼의 리스트뷰 안에 프로그래스바를 표시하기 위함
: rect = ThdListView->Items->Item[ThdID]->DisplayRect(drBounds);
: pProgressBar->Top = rect.Top + BAR_PADDING;
: pProgressBar->Left = rect.Left + ThdListView->Columns->Items[1]->Width + ThdListView->Columns->Items[0]->Width;
: pProgressBar->Width = ThdListView->Columns->Items[2]->Width;
: pProgressBar->Height = rect.Height();
:
: pProgressBar->Min = 0;
: pProgressBar->Max = GetFileSize(hRead, NULL);
: pProgressBar->Position = 0;
:
: // 메세지를 작성한다
: // ThdListView->Items->BeginUpdate();
: tmpList->SubItems->Strings[2] = msg + " 파일을 복사중 입니다";
: // ThdListView->Items->EndUpdate();
:
: // 파일을 복사한다
: while (true)
: {
: memset(&buf, 0x00, BUF_SIZE);
: ReadFile(hRead, &buf, BUF_SIZE, &dwret, NULL);
: pProgressBar->Position += dwret;
:
: if (dwret == BUF_SIZE)
: WriteFile(hWrite, &buf, BUF_SIZE, &dwret, NULL);
: else if (dwret > 0)
: WriteFile(hWrite, &buf, dwret, &dwret, NULL);
: else
: break;
: }
:
: result = pProgressBar->Max - pProgressBar->Position;
: delete pProgressBar;
: CloseHandle(hRead);
: CloseHandle(hWrite);
:
: // 종료 메세지
: if ( !result )
: {
: // ThdListView->Items->BeginUpdate();
: tmpList->SubItems->Strings[1] = "복사 완료";
: tmpList->SubItems->Strings[2] = msg + " 파일을 복사하였습니다.";
: // ThdListView->Items->EndUpdate();
: return true;
: }
: else
: {
: // ThdListView->Items->BeginUpdate();
: tmpList->SubItems->Strings[1] = "복사 실패";
: tmpList->SubItems->Strings[2] = msg + " 파일 복사가 중단되었습니다.";
: // ThdListView->Items->EndUpdate();
: return false;
: }
:
: return false;
: }
: -----------------------------------------------------------------------------------
:
: [ThreadUpGrade.h]
: -----------------------------------------------------------------------------------
: class ThreadUpGrade : public TThread
: {
: private:
:
: protected:
: void __fastcall Execute();
:
: public:
: char ThdID;
: char ThdDrive;
: bool ThdActive;
: TListView *ThdListView;
:
: void TestFileCopy(void);
: bool FileCopying(AnsiString SourcePath, AnsiString TargetPath, AnsiString msg);
:
: __fastcall ThreadUpGrade(bool CreateSuspended);
: };
: -----------------------------------------------------------------------------------
|