نمایش نتایج 1 تا 19 از 19

نام تاپیک: چند مشکل در رابطه با تابع CopyFile

  1. #1
    کاربر دائمی آواتار A_Salimi
    تاریخ عضویت
    شهریور 1386
    محل زندگی
    North khorasan-Esfarayen
    پست
    372

    چند مشکل در رابطه با تابع CopyFile

    با سلام :

    قبل از عنوان کردن این سوال ، CopyFile رو جستجو کردم ولی در موارد جستجو متاسفانه نتونستم مشکل رو برطرف کنم و به جواب برسم :

    من سعی میکنم تا از این تابع برای کپی کردن یک فایل (در اینجا فایل عکس ) از یک دایرکتوری به دایرکتوری دیگر و یا به فولدری در همان دایرکتوری استفاده کنم مشکلاتی رو که برای من بوجود اومدند رو در زیر میارم :

    1) در ابتدا بجای کپی کردن عکس سعی کردم یک فایل متنی رو کپی کنم به صورت زیر :

    LPCTSTR a="C:\\test.txt";
    LPCTSTR b="C:\\New Folder";
    BOOL h=CopyFile(a,b,FALSE);
    if(h==0)
    MessageBox(_T("function fail"));


    که در درایو c هم فولدر New Folder هم موجود بود اما جالب اینجاست که بدونید بعد از اجرای خطوط فوق یک فایل به نام New Folder در درایو c بوجود می اومد !!! بعضی ها گفتند که برای مسیر دوم دوم باید دو بک اسلش دیگه هم بذارم یعنی به این صورت :

    LPCTSTR b="C:\\New Folder\\”;

    که البته فرقی نکرد.

    2) در ادامه همان کارها را برای فایل jpg انجام دادم که نمیدونم چرا تابع fail میشد ؟
    یعنی به این صورت :

    LPCTSTR a="C:\\mypic.jpg";

    3) من برای انتخاب عکسم از دیالوگ file browser و برای مسیر فولدرم از folder browser استفاده میکنم و آدرس های نهایی رو در یک edit box چاپ میکنم اما مشکلی که وجود داره اینه که آدرس رو با یک بک اسلش ( \ ) برمیگردونن (در حالی که در ویژوال سی باید از دو تا استفاده شه) و زمانی که اون آدرس ها رو در تابع قرار میدم تابع fail میشه . برای رفع این مشکل باید چکار کنم ؟

    با تشکر

  2. #2
    شما باید برای مسیر مقصد هم نام کامل فایل را بنویسید.مثلا

    LPCTSTR a="C:\\test.txt";
    LPCTSTR b="C:\\New Folder\\text.txt";
    BOOL h=CopyFile(a,b,FALSE);
    if(h==0)
    MessageBox(_T("function fail"));


    برای همین این تابع برای rename هم به کار میره
    در مورد بک اسلاش هم فکر نکنم این طور باشه.شما آدرس رو از کجا استخراج می کنید. m_OFN یکی از اعضای file browser هست.از اون می تونی استفاده کنی
    این کد رو ببین:

    #include <windows.h>
    #include <stdio.h>

    void main()
    {
    WIN32_FIND_DATA FileData;
    HANDLE hSearch;
    DWORD dwAttrs;
    TCHAR szDirPath[] = TEXT("c:\\TextRO\\");
    TCHAR szNewPath[MAX_PATH];

    BOOL fFinished = FALSE;

    // Create a new directory.

    if (!CreateDirectory(szDirPath, NULL))
    {
    printf("Could not create new directory.\n");
    return;
    }

    // Start searching for text files in the current directory.

    hSearch = FindFirstFile(TEXT("*.txt"), &FileData);
    if (hSearch == INVALID_HANDLE_VALUE)
    {
    printf("No text files found.\n");
    return;
    }

    // Copy each .TXT file to the new directory
    // and change it to read only, if not already.

    while (!fFinished)
    {
    lstrcpy(szNewPath, szDirPath);
    lstrcat(szNewPath, FileData.cFileName);
    if (CopyFile(FileData.cFileName, szNewPath, FALSE))
    {
    dwAttrs = GetFileAttributes(FileData.cFileName);
    if (dwAttrs==INVALID_FILE_ATTRIBUTES) return;

    if (!(dwAttrs & FILE_ATTRIBUTE_READONLY))
    {
    SetFileAttributes(szNewPath,
    dwAttrs | FILE_ATTRIBUTE_READONLY);
    }
    }
    else
    {
    printf("Could not copy file.\n");
    return;
    }

    if (!FindNextFile(hSearch, &FileData))
    {
    if (GetLastError() == ERROR_NO_MORE_FILES)
    {
    printf("Copied all text files.\n");
    fFinished = TRUE;
    }
    else
    {
    printf("Could not find next file.\n");
    return;
    }
    }
    }

    // Close the search handle.

    FindClose(hSearch);
    }

  3. #3
    کاربر دائمی آواتار A_Salimi
    تاریخ عضویت
    شهریور 1386
    محل زندگی
    North khorasan-Esfarayen
    پست
    372
    ممنونم ، همونطوری که گفتید هستش

    اما باید بگم اگه از یک بک اسلش استفاده کنیم تابع fail میشه . در هر حال مشکلی که گفتم در مورد file browser و folder browser همچنان وجود دارند در همون تابع اگه a توسط یک file browser و b توسط یک folder browser ایجاد بشه دو تا مشکل بوجود می آید :

    1) آدرس ها دارای یک بک اسلش هستند.
    2) قسمتی رو که در پست اول گفتید که باید به انتهای آدرس دوم اضافه بشه تا تابع به درستی عمل کند رو چطور به آدرس حاصل از folder browser اضافه کنم ؟

    با تشکر

  4. #4
    کاربر دائمی آواتار A_Salimi
    تاریخ عضویت
    شهریور 1386
    محل زندگی
    North khorasan-Esfarayen
    پست
    372
    سلام

    اگه واسه کسی مقدوره به دو سوال قبلی من پاسخ بده ممنون میشم.

  5. #5
    نقل قول نوشته شده توسط eshgh_82 مشاهده تاپیک
    1) آدرس ها دارای یک بک اسلش هستند.
    2) قسمتی رو که در پست اول گفتید که باید به انتهای آدرس دوم اضافه بشه تا تابع به درستی عمل کند رو چطور به آدرس حاصل از folder browser اضافه کنم ؟
    مسیر فولدر اگر به صورت یک slash باشد درست عمل خواهد کرد، همان مسیر را بدون تغییر به توابع دیگر ارسال کنید، چرا که در بسیاری از پروژه ها به همین شکل دیدم.
    اگر هم جواب نمی دهد با نوشتن یک الگوریتم \ را با \\ جایگزین کنید

    برای مورد دوم هم وقتی نام مسیر یا فولدر را دریافت کردید، به راحتی با نام و پسوند مورد نظر از طریق strcat آن را به انتهای رشته (مسیر) اضافه کنید.
    آخرین ویرایش به وسیله Nima_NF : شنبه 17 فروردین 1387 در 16:38 عصر دلیل: اصلاح مورد اول

  6. #6
    کاربر دائمی آواتار A_Salimi
    تاریخ عضویت
    شهریور 1386
    محل زندگی
    North khorasan-Esfarayen
    پست
    372
    در مورد file browser از روش زیر استفاده میکنم :

    در ابتدا تابعی رو به صورت زیر تعریف میکنم :


     char* openfile(char filter[],char defuext[],char title[])



    {

    char filename[500]={0};

    char filetitle[100];

    OPENFILENAME of;

    memset(&of,0,sizeof(of));
    of.lStructSize=sizeof(OPENFILENAME);
    of.hwndOwner=NULL;
    of.hInstance=NULL;
    of.lpstrFilter=TEXT(filter);
    of.lpstrCustomFilter=NULL;
    of.nMaxCustFilter=0;
    of.nFilterIndex=1;
    of.lpstrFile=filename;
    of.nMaxFile=1000;
    of.nMaxFileTitle=99;
    of.lpstrFileTitle=filetitle;
    of.lpstrTitle=title;
    of.Flags=OFN_NOREADONLYRETURN;
    of.lpstrDefExt=defuext;
    of.lCustData=NULL;
    of.lpfnHook=NULL;
    of.lpTemplateName=NULL;
    GetOpenFileName(&of);
    return(filename);
    }











    و در جایی مثلا به صورت زیر عمل میکنم :



    UpdateData();


    strcpy(filename,openfile("Picture files (*.jpg;*.bmp;*.png)\0*.jpg;*.bmp;*.png","jpg;bmp;p ng","Choose pictures..."));


    if(filename[0]!='\0'){


    filen=filename;


    filen.MakeUpper();


    CString ext=filen.Right(3);}


    UpdateData(FALSE);






    که filen یک متغیر CString برای edit box است .

    در مورد folder browser هم به این صورت عمل میکنم :



    void CFolderBrowserDlg::OnButtonBrowse()


    {


    // TODO: Add your control notification


    // handler code here


    LPMALLOC pMalloc = NULL;


    LPITEMIDLIST pidl = NULL;


    BROWSEINFO bi;


    ZeroMemory(&bi, sizeof(BROWSEINFO));



    // set the bi's default values


    bi.hwndOwner = m_hWnd;


    bi.lpszTitle = _T("Current folder is:");


    bi.ulFlags = BIF_RETURNONLYFSDIRS | BIF_STATUSTEXT;


    bi.lpfn = BrowseCallbackProc;


    pidl = SHBrowseForFolder(&bi);


    if(pidl != NULL)


    {


    SHGetPathFromIDList(pidl,


    m_strFolderPath.GetBuffer(


    m_strFolderPath.GetLength()));


    UpdateData(FALSE);


    // free memory


    if(SUCCEEDED(SHGetMalloc(&pMalloc)) && pMalloc);


    pMalloc->Free(pidl);


    pMalloc->Release();


    }


    }







    int CALLBACK BrowseCallbackProc(


    HWND hwnd, UINT uMsg, LPARAM lParam, LPARAM lpData)


    {


    switch(uMsg)


    {


    case BFFM_INITIALIZED:


    {


    // add your initialization code here


    }


    break;


    case BFFM_SELCHANGED:


    {


    TCHAR szText[MAX_PATH] = {0};


    SHGetPathFromIDList(


    reinterpret_cast<LPITEMIDLIST>(lParam), szText);


    SendMessage(hwnd, BFFM_SETSTATUSTEXT, 0,


    reinterpret_cast<LPARAM>(szText));


    }


    break;


    }


    return 0;


    }






    که در نهایت به این صورت عمل میکنم :



    BOOL h=CopyFile(filen,m_strFolderPath,TRUE);

    if(h==0)

    MessageBox(_T("function fail"));



    که با MessageBox مواجه میشم.
    آخرین ویرایش به وسیله A_Salimi : شنبه 17 فروردین 1387 در 16:54 عصر دلیل: خطا در قرار دادن تگ کد

  7. #7
    نگاه کنید درست هست که شما از \\ در هنگام تعریف مسیر استفاده می کنید ولی در هنگام ذخیره شدن فقط یک کارکتر \ در رشته ذخیره می شود چرا که در غیر این صورت کارکتر دیگری به جای \ ذخیره می شود.
    پس این مورد یعنی رشته های دریافتی از توابع فوق درست هستند و باید یک \ را نشان دهند و مشکلی در این باره وجود ندارد.

    اما در مورد این خط:

    BOOL h=CopyFile(filen, m_strFolderPath, TRUE);
    در این خط عمل debug را انجام دهید و بادقت دو رشته را با تک تک کارکتر هایش بررسی کنید که آیا مسیر در این مرحله کاملا درست هست یا نه ، و هر دو باید دارای نام فایل و پسوند آن هم باشند.
    از انجایی که به پروژه دسترسی نداریم نمی توانیم بررسی دقیق کنیم. در یکی از خطوط از MakeUpper استفاده کردید که این کار بر روی تمامی کارکتر ها تاثیر می گذارد و حتی \ را به کارکتر دیگری تبدیل می کند و مسیر اشتباه خواهد شد.

    پس خودتان در این مرحله نیز می توانید از GetLastError استفاده کنید تا متوجه شوید چه خطایی رخ می دهد.

  8. #8
    کاربر دائمی آواتار A_Salimi
    تاریخ عضویت
    شهریور 1386
    محل زندگی
    North khorasan-Esfarayen
    پست
    372
    مسیر ها رو کاملا چک کردم (در مد دیباگ) که درست بودند (البته با یک \ ) .
    در مورد MakeUpper هم ، رشته رو قبل از اینکه به این دستورات برسه در متغیر دیگری ذخیره کردم و سپس به CopyFile فرستادم . . . اما باز هم تابع fail شد.
    در مورد GetLastError دقیقا چه کاری رو انجام میده ؟ و چطور باید ازش استفاده کنم ؟
    در نهایت فکر کنم باید همون نظریه شما رو پیاده سازی کنم یعنی تابعی بنویسم که \ رو به \\ تبدیل کنه و در ضمن رشته ها رو به هم بچسپونه !

  9. #9
    GetLastError را بعد اجزای تابع copy قرار دهید و مقدار برگشتی آن را ذخیره کنید،

    سپس شماره خطای برگشتی را در MSDN چک کنید تا ببینید چه خطایی رخ داده است.

  10. #10
    کاربر دائمی آواتار A_Salimi
    تاریخ عضویت
    شهریور 1386
    محل زندگی
    North khorasan-Esfarayen
    پست
    372
    از GetLastError استفاده کردم و این تابع مقدار 5 رو برگردوند و این در msdn یعنی :

    Access is denied.

    به نظر شما این میتونه از همون آدرس دهی با یک \ باشه ؟

  11. #11
    نقل قول نوشته شده توسط eshgh_82 مشاهده تاپیک
    به نظر شما این میتونه از همون آدرس دهی با یک \ باشه ؟
    3 خط اول پست شماره 7 من را دوباره بخوانید، در رشته مسیر شما فقط یک \ ذخیره خواهد شد نه دو تا ، پس اشکال جای دیگری است.
    یا مسیر ها به همراه نام فایل اشتباه هستند یا فایل مورد نظر در حال اجرا است و توسط تابع قابل دسترسی نیست یا ...

    برای اینکه به نتیجه برسید به صورتی دستی، مانند پاراگراف اول پست شماره 2 BitMap دو مسیر را تعریف و تابع را اجرا کنید تا با مسیر دهی خوب آشنا شوید و بتوانید مشکل را حل کنید (حتما با debug در هملن خط دو مسیر را مشاهده کنید تا ببینید که فقط یک \ در مسیر دستی شما ذخیره شده است و سپس آن را با مسیر های برنامه ای که خودتان نوشتید مقایسه کنید)

  12. #12
    کاربر دائمی آواتار A_Salimi
    تاریخ عضویت
    شهریور 1386
    محل زندگی
    North khorasan-Esfarayen
    پست
    372
    در رشته مسیر شما فقط یک \ ذخیره خواهد شد نه دو تا

    خوب درسته ، منظورتون رشته های برگردانده شده توسط filebrowser و folderbrowser هست دیگه ؟


    پس اشکال جای دیگری است.

    چرا ؟ اتفاقا اشکال همین جاست چون همونطوری که قبلا هم گفته بودم به صورت دستی و با \\ کاملا به جواب رسیده بودم . ولی با \ و به صورت دستی تابع fail شد .(پس فکر نمیکنم مقایسه فایده ای داشته باشه )


    در هر حال من یک تابع نوشتم که \ رو به \\ تبدیل میکنه فقط یکسری اشکال داره که نمیدونم چطور باید برطرفش کنم ببینید من به این شکل برنامه ای نوشتم :


    void CtestDlg::myfunction(CString str1){
    int len1=strlen(str1);
    char k[]="\\\\\\";
    int j=0;
    for(int i=0;i <len1 ;i++){
    str3[j]=str1[i];
    if(str1[i]==k[1]){
    str3[j+1]=k[1];
    j++;
    }
    j++;
    }
    }


    در نهایت در str3[200] مسیر با \\ ذخیره خواهد شد اما خوب خانه هایی که در آن هیچ کاراکتری ذخیره نشده اند خالی خواهند ماند که مسلما درست نیست در ضمن من خواستم از تابع Mid استفاده کنم که مشکل داشت . . . یه چیزی شبیه این :

    Str3[200]. Mid(0,j);

    استفاده از متغیر k به این شکل هم شاید تا حدی خنده دار باشه (هرچند درست عمل میکرد) چون خط زیر با مشکل مواجه میشد :

    if(str1[i]==’\’)

    در هر حال اگه مشکل این تابع رو برطرف کنید و یا تابع بهتری رو بیارید ممنون میشم .

  13. #13
    کاربر دائمی آواتار A_Salimi
    تاریخ عضویت
    شهریور 1386
    محل زندگی
    North khorasan-Esfarayen
    پست
    372
    حرفم رو پس میگیرم حرف شما درسته من کاملا متوجه منظور شما نشده بودم در حقیقت زمانی که از \\ استفاده میکنیم ، در حالت دیباگwatch )) آدرسها به صورت \ دیده میشوند. (پس اشکال جای دیگری است)

    من فایل رو به صورت کامپایل نشده در زیر قرار داده ام ، اگه لطف کنید و بگید که چطور می تونم مشکل Fail شدن تابع CopyFile رو بر طرف کنم.

    با تشکر
    فایل های ضمیمه فایل های ضمیمه

  14. #14
    من به شما گفتم.
    پارامتر دو این تابع مسیر کامل فایل مقصد همراه نام فایل است.بعنی این اشتباهه:
    CopyFile("C:\\001.txt","C:\\",TRUE);

    این درسته:
    CopyFile("C:\\001.txt","C:\\002.txt",TRUE);


    که شما در کدتون از نوع اول استفاده کرده اید.با یک debug ساده میشه فهمید

  15. #15
    کاربر دائمی آواتار A_Salimi
    تاریخ عضویت
    شهریور 1386
    محل زندگی
    North khorasan-Esfarayen
    پست
    372
    حرف شما کاملا درسته و من هم در اون پستی که داشتید به اون نکته دقت کردم و به جواب هم رسیدم .
    اما در مورد استفاده از browser ها :
    دو راه هست که این دو آدرس رو به هم بچسپونیم :

    1)استفاده از StrCat با header : shlwapi.h
    2)استفاده از strcat

    )به بزرگی و کوچکی حروف دقت کنید)
    و یک چیز دیگه هم هست :
    فرض کنید آدرس اول ما این باشه :

    C:\a.txt

    و آدرس دوم این باشه :

    C:\New Folder

    چیزی که در آرگومان دوم نیاز داریم باید اینجور چیزی باشه :

    C:\New Folder\a.txt

    پس برای رشته دوم این اتفاق افتاد :C حذف شده . . . درسته ؟

    پس من قبل از چسپاندن رشته ها باید این دو کاراکتر رو در ابتدا از رشته حذف کنم که من از Mid استفاده کردم اما نمیدونم چرا رشته خروجی خالیه ؟ یه چیزی شبیه زیر :

    Str2.mid(2,strlen(str2))

    اما خروجیش همیشه خالیه !
    ضمنا StrCat ورودی از نوع LPTSTR می خواد چطور میشه CString رو به این نوع تبدیل کرد ؟
    در مورد strcat هم که یکی از ورودیهاش char* هستش که البته روش تبدیلش به CString در msdn هست .

    یه روش برای درست چسپاندن رشته ها میخوام

    با تشکر

  16. #16
    وقتی از CString استفاده می کنید امکانات زیادی برای کار با رشته ها دارید (متد های کلاس آن و کلاس های که از آن مشتق شده است را مشاهده کنید)، مثلا برای اضافه کردن رشته CString دیگر به جای strcat از Append می توانید استفاده کنید:

    CString str1;

    str1.Append(str2);
    و یا اگر بخواهید از توابع استاندارد C استفاده کنید از GetBuffer استفاده کنید تا اشاره گری به رشته را برای char برگرداند، برای مثال:

    CString str1_Folder;

    strcat( str1_Folder.GetBuffer(str1_Folder.GetLength()) , _T("\\xxx.jpg"));
    امیدوارم مطالب را با دقت بیشتری مطالعه کنید، مخصوصا وقتی که راهکار اولیه چندین مرتبه تکرار شده است.

  17. #17
    شما می تونید علاوه بر گرفتن مسیر فایل انتخاب شده ، فقط نام آن را هم بگیرید
    از آن استفاده کنید

  18. #18
    کاربر دائمی آواتار A_Salimi
    تاریخ عضویت
    شهریور 1386
    محل زندگی
    North khorasan-Esfarayen
    پست
    372
    سلام
    نیما جان از این که وقت شما رو گرفتم معذرت میخوام همینطور شما bitmap عزیز .

    من در نهایت با کمک شما کدی نوشتم که عملیات کپی رو انجام میده اما نه برای تمام مسیرها : یعنی در کل برای بعضی از مسیرها با اشکالی با این مضمون مواجه میشه : حافظه در یک آدرس خاص قابل خواندن نیست !

    اما کد من :
     

    CString a=str1;
    str1=str1.Mid(2);
    char * b=strcat( m_strFolderPath.GetBuffer(m_strFolderPath.GetLengt h()) ,str1);
    BOOL h=CopyFile(a,b,FALSE);
    DWORD n=GetLastError();
    if(h==0)
    MessageBox(_T("function fail"));


    چرا این کد همه جا درست عمل نمیکنه ؟

  19. #19
    کاربر دائمی آواتار A_Salimi
    تاریخ عضویت
    شهریور 1386
    محل زندگی
    North khorasan-Esfarayen
    پست
    372
    مشکل اینجا بود که مسیر فایل رو به مسیر فولدر می چسپاندم که این غلطه و به همون حرف bitmap در پست 17 رسیدم . یعنی در آرگومان دوم تابع بایستی اول مسیر فولدر و سپس فقط نام فایل رو ذکر کنیم .

قوانین ایجاد تاپیک در تالار

  • شما نمی توانید تاپیک جدید ایجاد کنید
  • شما نمی توانید به تاپیک ها پاسخ دهید
  • شما نمی توانید ضمیمه ارسال کنید
  • شما نمی توانید پاسخ هایتان را ویرایش کنید
  •