Czyszczenie pliku lokalnego po wysłaniu kopii na FTP

0

Witam.
Od dwóch dni próbuję rozwiązać pewien problem, jednak bezskutecznie. W programie pobieram dane od użytkownika i zapisuję do pliku. Następnie sprawdzam rozmiar pliku, powiedzmy jeśli jest większy niż 200 b, rozpoczynam transmisję danych przez FTP. Operacja ta jest w pętli. Wygląda to mniej więcej tak:

....
          FILE * file;
          std::string path;
          path = "C:\\Program Files\\MyApp\\usage.txt";

          file = fopen(path.c_str(),"a+");
          fputs(data,file);
          fclose(file);

          TCHAR *param=new TCHAR[path.size()+1];
          param[path.size()]=0;
          std::copy(path.begin(),path.end(),param);

          UploadFTP upload;

          if (upload.GetFileSize(param) > 200)
            if (!upload.SubmitFile(path.c_str()))
                remove(path.c_str());

          break;
....

Jak dla mnie kod wydaje się logiczny, ale działa w ten sposób: po podaniu pierwszych danych, zostaje utworzony plik usage.txt. Dane są zapisywane po kilka/kilkanaście bajtów. Gdy rozmiar pliku przekroczy 200 b, zgodnie z kodem, plik zostaje wysłany na FTP i usunięty z dysku, od razu przy próbie wprowadzenia kolejnych danych, tworzy się kolejny plik. Również dochodzi on do 200 b, zostaje wysłany, z dysku plik zostaje usunięty i na tym koniec - dalej użytkownik wprowadza dane, które nigdzie już nie są zapisywane, plik z danymi się już nie tworzy. Jaka może być tego przyczyna? Dzięki za wskazówki :)

Dodam, że pod Windows XP wszystko działa prawidłowo. Problem występuje na Windows 7.

0
fopen( Path, "w")

I nie musisz usuwać pliku. Wtedy windows nie ma prawa robić dziwnych rzeczy :)

0

Dzięki za odpowiedź, ale nie mogę ustawić "w" w fopen(), bo za każdym razem tracę wcześniejsze dane. Nie wysyłam pliku z każdą nową daną, lecz dopiero po osiągnięciu pewnego rozmiaru przez plik. Wtedy chcę wysłać plik i go wyczyścić, żeby potem nie wysyłać tego samego co wcześniej wraz z nowymi danymi.

1

Możesz tak, ale pozostaje problem - co jeśli poprzednie dane były większe niż aktualne. Niestety coś mi wypadło i nie mam czasu do kończyć. W każdym razie najlepiej by było wczytać plik do pamięci i z pamięci go wysyłać. (proste operacje na wskaźniku do zapisu i pobierania rozmiaru).

FILE * file;
std::string path;
path = "C:\\Program Files\\MyApp\\usage.txt";
 
  //Otwarcie pliku
file = fopen(path.c_str(),"a+");
//fseek( file, 0, SEEK_END );  //dla "a+" powinno być zbędne.

  //Zapisane pozycji końca
int WritePos = ftell (file);

TCHAR *param=new TCHAR[path.size()+1];
param[path.size()]=0;
std::copy(path.begin(),path.end(),param);

....
          fseek( file, WritePos, SEEK_SET);
          fputs(data,file);
 
          UploadFTP upload;
 
          if (upload.GetFileSize(param) > 200)
            if (!upload.SubmitFile(path.c_str()))
                //remove(path.c_str()); //nie potrzebne
                int j = 3; //zeby zamknac if. Nie wiem co chcesz tu osiągnąć. Powinno być odwrotnie i raportować błędy
 
          break; //co to za break? Pętla wykonuje się tylko raz!
....

fclose(file);
0

prawdopodobnie nie masz uprawnień do modyfikowania zawartości w program files

0

Hm. Napisałem zgodnie z Twoim zaleceniem, jednak dane są zapisywane do czasu osiągnięcia 200 b przez usage.txt. Dalej nic się nie dzieje. Ani plik się nie wysyła, ani się nie uzupełnia. Może istnieje jakiś inny sposób?
Odnośnie komentarzy ten break na końcu zamyka switcha. Dane przekazuję w innym miejscu programu przez

data->save(data);

a tutaj to wygląda tak:

void Data::save(char* data)
{
     switch(choice)
     {
     case DEBUG:
          std::cout << data;
          break;
     case LOCAL_FILE:
          FILE * file;
          std::string path;
          path = "C:\\Program Files\\MyApp\\usage.txt";
 
          file = fopen(path.c_str(),"a+");
          fputs(data,file);
          fclose(file);

          UploadFTP upload;

          TCHAR *param=new TCHAR[path.size()+1];
          param[path.size()]=0;
          std::copy(path.begin(),path.end(),param);
          
          if (upload.GetFileSize(param) > 200)
            upload.SubmitFile(path.c_str());
            
          break;
     }
}

@ szopenfx
Myślę, że mam, gdyż program działa jako Administrator :) Zresztą bez tego, w Program Files powinien równie sprawnie działać?

1

Chodziło mi o to, żebyś otwierał plik przed pętlą, żeby nie alokować pamięci milion razy. Poza tym nie masz żadnej kontroli błędów. Nie sprawdzasz, czy udało się otworzyć plik.

(fopen) Return value:
If the file is successfully opened, the function returns a pointer to a FILE object that can be used to identify the stream on future operations.
Otherwise, a null pointer is returned.
On most library implementations, the errno variable is also set to a system-specific error code on failure.

Sprawdź czy plik się otwiera i jeśli nie to dlaczego.

0

Dopisałem kontrolę błedów podobną do tej: Perror
I jakoś teraz śmiga jak na razie wszystko poprawnie.. aż dziwne :D raz mi się zdarzyło coś takiego w miejscu:

file = fopen(path.c_str(),"a+");
if (!file) perror("Blad przy otwieraniu pliku:");

Wyświetlił mi "No such file or directory." Trochę nielogiczne, skoro otwieram plik z warunkiem a+. Ale tylko raz takie coś odwalił, na razie działa w miarę ogarnięcie. Dzięki za pomoc. Jakby coś się sypało, to napiszę :)

1 użytkowników online, w tym zalogowanych: 0, gości: 1