CYFROWY BARON • PROGRAMOWANIE • Zobacz wątek - [BCB C++] Dopisywanie lini \r\n danych do dużych pliku

[BCB C++] Dopisywanie lini \r\n danych do dużych pliku

dział ogólny

[BCB C++] Dopisywanie lini \r\n danych do dużych pliku

Nowy postprzez Darek_C++ » piątek, 31 sierpnia 2012, 09:12

Tym razem chciał bym się dowiedzieć jak najlepiej obsłużyć dopisywanie nowych linii danych \r\n do pliku "tekstowego". Dopisywanie odbywać się będzie "z wątku" w metodzie zsynchronizowanej Synchronize(&DopiszDane); Chodzi o to, że pliki te będą robić się coraz większe powiedzmy 10K - 1M linii danych dlatego o to pytam.
Avatar użytkownika
Darek_C++
Elektrowied
Elektrowied
 
Posty: 454
Dołączył(a): piątek, 25 lipca 2008, 14:33
Podziękował : 66
Otrzymał podziękowań: 4
System operacyjny: Windows XP Pro SP2
Kompilator: Turbo Explorer C++
Gadu Gadu: 0
    Windows XPFirefox

Re: [BCB C++] Dopisywanie lini \r\n danych do dużych pliku

Nowy postprzez polymorphism » piątek, 31 sierpnia 2012, 10:06

Jeśli dopisywanie na końcu, to w czym problem?
C++ Reference - opis wszystkich klas STL-a i funkcji C.
Avatar użytkownika
polymorphism
Doświadczony Programista ● Moderator
Doświadczony Programista ● Moderator
 
Posty: 2156
Dołączył(a): piątek, 19 grudnia 2008, 13:04
Podziękował : 0
Otrzymał podziękowań: 200
System operacyjny: Windows 8.1
Windows 10
Linux Mint 21.1
Kompilator: Visual Studio
Visual Studio Code
MSYS2 (MinGW, clang)
g++
clang
Gadu Gadu: 0
    Windows XPFirefox

Re: [BCB C++] Dopisywanie lini \r\n danych do dużych pliku

Nowy postprzez Darek_C++ » piątek, 31 sierpnia 2012, 10:11

Nie wiem czy to jest problem dlatego pytam tutaj. Wydawało mi się, że jak chcemy dopisać musimy ten plik "otworzyć", więc im większy tym jego "otwarcie" zajmie więcej czasu / zasobów :) Rozumiem, że byłem w błędzie i nie tak sprawa wygląda ?
Avatar użytkownika
Darek_C++
Elektrowied
Elektrowied
 
Posty: 454
Dołączył(a): piątek, 25 lipca 2008, 14:33
Podziękował : 66
Otrzymał podziękowań: 4
System operacyjny: Windows XP Pro SP2
Kompilator: Turbo Explorer C++
Gadu Gadu: 0
    Windows XPFirefox

Re: [BCB C++] Dopisywanie lini \r\n danych do dużych pliku

Nowy postprzez Cyfrowy Baron » piątek, 31 sierpnia 2012, 10:39

Możesz posłużyć się klasą FILE, np:

KOD cpp:     UKRYJ  
 void WriteToEndFile(char * fileName, char *Buf)
{
 FILE *fileStream;
 fileStream = fopen(fileName, "r+");

 fseek(fileStream, 0, SEEK_END);
 fwrite(Buf, sizeof(char), strlen(Buf), fileStream);

 fclose(fileStream);
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button10Click(TObject *Sender)
{
 AnsiString FileName = "c:\\test.txt";
 WriteToEndFile(FileName.c_str(), "przykładowy tekst\r\n" );
}


Podany wyżej kod działa tylko na plikach tekstowych zapisanych w ANSI, ale TEC++ chyba nie obsługuje Unicode.

Jeśli chodzi o Unicode to może to wyglądać tak:

KOD cpp:     UKRYJ  
 void WriteToEndFile(wchar_t * fileName, wchar_t *Buf)
{
 FILE *fileStream;
 fileStream = _wfopen(fileName, L"r+");

 fseek(fileStream, 0, SEEK_END);
 fwrite(Buf, sizeof(wchar_t), wcslen(Buf), fileStream);

 fclose(fileStream);
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button10Click(TObject *Sender)
{
 String FileName = "c:\\test.txt";
 WriteToEndFile(FileName.c_str(), L"Tekst Unicode\x0D" );
}


Niestety tutaj mam problem o ile wprowadzenie znaku CR (x0D) nie jest problemem o tyle nie przyjmuje mi znaku LF (x0A), nie wiem dlaczego, a bez LF nie będzie łamania linii.

Za ten post autor Cyfrowy Baron otrzymał podziękowanie od:
Darek_C++
Avatar użytkownika
Cyfrowy Baron
Administrator
Administrator
 
Posty: 4716
Dołączył(a): niedziela, 13 lipca 2008, 15:17
Podziękował : 12
Otrzymał podziękowań: 442
System operacyjny: Windows 7 x64 SP1
Kompilator: Embarcadero RAD Studio XE2
C++ Builder XE2 Update 4
SKYPE: cyfbar
Gadu Gadu: 0
    Windows XPFirefox

Re: [BCB C++] Dopisywanie lini \r\n danych do dużych pliku

Nowy postprzez Darek_C++ » piątek, 31 sierpnia 2012, 10:52

A dlaczego zapis w C fopen() ?
Avatar użytkownika
Darek_C++
Elektrowied
Elektrowied
 
Posty: 454
Dołączył(a): piątek, 25 lipca 2008, 14:33
Podziękował : 66
Otrzymał podziękowań: 4
System operacyjny: Windows XP Pro SP2
Kompilator: Turbo Explorer C++
Gadu Gadu: 0
    Windows XPFirefox

Re: [BCB C++] Dopisywanie lini \r\n danych do dużych pliku

Nowy postprzez Cyfrowy Baron » piątek, 31 sierpnia 2012, 10:58

Po prostu jedna z możliwości.
Avatar użytkownika
Cyfrowy Baron
Administrator
Administrator
 
Posty: 4716
Dołączył(a): niedziela, 13 lipca 2008, 15:17
Podziękował : 12
Otrzymał podziękowań: 442
System operacyjny: Windows 7 x64 SP1
Kompilator: Embarcadero RAD Studio XE2
C++ Builder XE2 Update 4
SKYPE: cyfbar
Gadu Gadu: 0
    Windows XPFirefox

Re: [BCB C++] Dopisywanie lini \r\n danych do dużych pliku

Nowy postprzez Darek_C++ » piątek, 31 sierpnia 2012, 11:02

Myślałem, że dlatego akurat ta ze względu na jej wyróżniająca się wydajność w stosunku co do innych sposobów zapisu po pliku.
Avatar użytkownika
Darek_C++
Elektrowied
Elektrowied
 
Posty: 454
Dołączył(a): piątek, 25 lipca 2008, 14:33
Podziękował : 66
Otrzymał podziękowań: 4
System operacyjny: Windows XP Pro SP2
Kompilator: Turbo Explorer C++
Gadu Gadu: 0
    Windows XPFirefox

Re: [BCB C++] Dopisywanie lini \r\n danych do dużych pliku

Nowy postprzez Cyfrowy Baron » piątek, 31 sierpnia 2012, 11:14

Myślę, że jest wydajna, gdyż nie wczytuje całego pliku, a jedynie dopisuje do niego.



Mam pytanie do polymorphism: dlaczego nie wprowadza mi prawidłowo znaku LF - \x0A w przypadku kodowania Unicode? W kodzie go nie umieściłem, gdyż nie pojawia się w pliku jako LF lecz jako pusty znak.
Avatar użytkownika
Cyfrowy Baron
Administrator
Administrator
 
Posty: 4716
Dołączył(a): niedziela, 13 lipca 2008, 15:17
Podziękował : 12
Otrzymał podziękowań: 442
System operacyjny: Windows 7 x64 SP1
Kompilator: Embarcadero RAD Studio XE2
C++ Builder XE2 Update 4
SKYPE: cyfbar
Gadu Gadu: 0
    Windows XPFirefox

Re: [BCB C++] Dopisywanie lini \r\n danych do dużych pliku

Nowy postprzez Cyfrowy Baron » piątek, 31 sierpnia 2012, 12:33

Chyba znalazłem rozwiązanie. Plik tekstowy kodowany w Unicode musi być traktowany jako binarny a nie tekstowy:

KOD cpp:     UKRYJ  
void WriteToEndFile(wchar_t * fileName, wchar_t *Buf)
{
 FILE *fileStream;
 fileStream = _wfopen( fileName, L"rb+");

 fseek(fileStream, 0, SEEK_END);
 fwrite(Buf, sizeof(wchar_t), wcslen(Buf), fileStream);

 fclose(fileStream);
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button10Click(TObject *Sender)
{
 String FileName = "c:\\test.txt";
 WriteToEndFile(FileName.c_str(), L"Tekst Unicode\r\n");
}


rb+ lub r+b zamiast r+; rt+; r+t.
Avatar użytkownika
Cyfrowy Baron
Administrator
Administrator
 
Posty: 4716
Dołączył(a): niedziela, 13 lipca 2008, 15:17
Podziękował : 12
Otrzymał podziękowań: 442
System operacyjny: Windows 7 x64 SP1
Kompilator: Embarcadero RAD Studio XE2
C++ Builder XE2 Update 4
SKYPE: cyfbar
Gadu Gadu: 0
    Windows XPFirefox

Re: [BCB C++] Dopisywanie lini \r\n danych do dużych pliku

Nowy postprzez polymorphism » piątek, 31 sierpnia 2012, 12:57

Możesz posłużyć się klasą FILE, np:

FILE to nie jest żadna klasa, to wskaźnik na strukturę definiującą strumień. Z klasami znanymi z C++ nie ma nic wspólnego.

(...) więc im większy tym jego "otwarcie" zajmie więcej czasu / zasobów

A po co co chwilę otwierać ten plik? Z drugiej strony nie sądzę, żeby czas otwierania pliku zależał od jego wielkości.

Myślałem, że dlatego akurat ta ze względu na jej wyróżniająca się wydajność w stosunku co do innych sposobów zapisu po pliku.

Strumienie C to takie same strumienie jak te z C++, jeśli mowa o ich wydajności lub niewydajności. Największą wydajność będziesz miał korzystając z funkcji systemowych... tylko czy Twój problem wymaga optymalizacji na tym poziomie? Nie sądzę.

dlaczego nie wprowadza mi prawidłowo znaku LF - \x0A w przypadku kodowania Unicode?

Być może dlatego, ponieważ używasz funkcji fwrite na strumieniu sformatowanym. Do niesformatowanego zapisu strumień powinien być otwarty w trybie binarnym. Do wyprowadzania ciągów unikodowych masz funkcję fputws, tyle tylko, że ona konwertuje ciąg do kodowania ANSI (nie wiem, czy w windowsie
jest możliwość użycia strumieni w trybie unikod <--> unikod). Ech, spóźniłem się...
C++ Reference - opis wszystkich klas STL-a i funkcji C.
Avatar użytkownika
polymorphism
Doświadczony Programista ● Moderator
Doświadczony Programista ● Moderator
 
Posty: 2156
Dołączył(a): piątek, 19 grudnia 2008, 13:04
Podziękował : 0
Otrzymał podziękowań: 200
System operacyjny: Windows 8.1
Windows 10
Linux Mint 21.1
Kompilator: Visual Studio
Visual Studio Code
MSYS2 (MinGW, clang)
g++
clang
Gadu Gadu: 0
    Windows XPFirefox

Re: [BCB C++] Dopisywanie lini \r\n danych do dużych pliku

Nowy postprzez Cyfrowy Baron » piątek, 31 sierpnia 2012, 13:14

polymorphism napisał(a):FILE to nie jest żadna klasa, to wskaźnik na strukturę definiującą strumień. Z klasami znanymi z C++ nie ma nic wspólnego.


Oh, oczywiście. W C+++Builder wszystkie klasy zaczynają się od T. Takie przejęzyczenie - jak zwykli mawiać politycy... :x

polymorphism napisał(a): Do niesformatowanego zapisu strumień powinien być otwarty w trybie binarnym.


Tak, już sam na to wpadłem, w swoim poprzednim poście.

polymorphism napisał(a):Do wyprowadzania ciągów unikodowych masz funkcję fputws, tyle tylko, że ona konwertuje ciąg do kodowania ANSI (nie wiem, czy w windowsie
jest możliwość użycia strumieni w trybie unikod <--> unikod).


Nie jestem pewien czy zrozumiałem o co Tobie chodzi. Funkcja fwrite działa prawidłowo i wprowadza mi do pliku znaki Unicode, testowałem np. na znaku: - znak dobry jak każdy inny czcionka Arial - i został w tym pliku umieszczony. Wszystko więc już działa mi prawidłowo.

polymorphism napisał(a):Z drugiej strony nie sądzę, żeby czas otwierania pliku zależał od jego wielkości.


Myślę, że Darek_C++ założył, że każde otwarcie pliku wiąże się z jego przetworzeniem, np. u mnie otwarcie pliku tekstowego o rozmiarze 54 MB w Notatniku trwa ~5 sekund, czyli w tym przypadku wielkość pliku ma wpływ na czas jego otwierania, a raczej ładowania.
Avatar użytkownika
Cyfrowy Baron
Administrator
Administrator
 
Posty: 4716
Dołączył(a): niedziela, 13 lipca 2008, 15:17
Podziękował : 12
Otrzymał podziękowań: 442
System operacyjny: Windows 7 x64 SP1
Kompilator: Embarcadero RAD Studio XE2
C++ Builder XE2 Update 4
SKYPE: cyfbar
Gadu Gadu: 0
    Windows XPFirefox

Re: [BCB C++] Dopisywanie lini \r\n danych do dużych pliku

Nowy postprzez polymorphism » piątek, 31 sierpnia 2012, 13:37

Nie jestem pewien czy zrozumiałem o co Tobie chodzi. Funkcja fwrite działa prawidłowo i wprowadza mi do pliku znaki Unicode

Generalnie fwrite służy do wprowadzania danych binarnych, z tą jednak różnicą, że jeśli strumień pracuje w trybie tekstowym, znak \n jest zamieniany na ciąg \r\n (pod windowsem). Funkcja ta traktuje dane jako ciąg bajtów, zatem nie ma mowy, żeby poprawnie interpretowała 16-bitowe unikodowe znaki - unikodowy \u000A potraktuje jako ciąg 0A, 00, po konwersji wyjdzie 0D, 0A, 00, czyli wszystko się rozjedzie.
C++ Reference - opis wszystkich klas STL-a i funkcji C.
Avatar użytkownika
polymorphism
Doświadczony Programista ● Moderator
Doświadczony Programista ● Moderator
 
Posty: 2156
Dołączył(a): piątek, 19 grudnia 2008, 13:04
Podziękował : 0
Otrzymał podziękowań: 200
System operacyjny: Windows 8.1
Windows 10
Linux Mint 21.1
Kompilator: Visual Studio
Visual Studio Code
MSYS2 (MinGW, clang)
g++
clang
Gadu Gadu: 0
    Windows XPFirefox

Re: [BCB C++] Dopisywanie lini \r\n danych do dużych pliku

Nowy postprzez Cyfrowy Baron » piątek, 31 sierpnia 2012, 13:44

Wciąż nie rozumiem. Przecież napisałem, że to działa. Sprawdziłem plik z danymi wprowadzonymi przez podany ostatnio przeze mnie kod i dane w pliku są umieszczane prawidłowo, a \r\n wprowadzają prawidłowo znaczniki CR+LF. W pliku pomocy jest napisane, żeby przy aktualizacji pliku tekstowego używać metod r+t, a przy aktualizacji pliku binarnego r+b. Jeżeli zamiast \r\n dam \x0a\x0d też znaczniki są prawidłowo dodawane. Zawartość pliku z widocznymi znacznikami sprawdzałem w programie Notepad++. Nie ma już chyba nad czym dyskutować, skoro to już działa prawidłowo.
Avatar użytkownika
Cyfrowy Baron
Administrator
Administrator
 
Posty: 4716
Dołączył(a): niedziela, 13 lipca 2008, 15:17
Podziękował : 12
Otrzymał podziękowań: 442
System operacyjny: Windows 7 x64 SP1
Kompilator: Embarcadero RAD Studio XE2
C++ Builder XE2 Update 4
SKYPE: cyfbar
Gadu Gadu: 0
    Windows XPFirefox

Re: [BCB C++] Dopisywanie lini \r\n danych do dużych pliku

Nowy postprzez Cyfrowy Baron » piątek, 31 sierpnia 2012, 13:50

Jeszcze gwoli uzupełnienia:

polymorphism napisał(a):po konwersji wyjdzie 0D, 0A, 00


Gdy plik tekstowy kodowany w Unicode otwierałem metodą r+ r+t, za pomocą funkcji write przy znacznikach \x0d\x0a na końcu pliku otrzymywałem CR . Przy metodzie r+b otrzymuję CRLF. W przypadku plików kodowanych w ANSI przy metodzie r+; r+t funkcja fwrite prawidłowo wstawia znaki końca czyli CRLF.
Avatar użytkownika
Cyfrowy Baron
Administrator
Administrator
 
Posty: 4716
Dołączył(a): niedziela, 13 lipca 2008, 15:17
Podziękował : 12
Otrzymał podziękowań: 442
System operacyjny: Windows 7 x64 SP1
Kompilator: Embarcadero RAD Studio XE2
C++ Builder XE2 Update 4
SKYPE: cyfbar
Gadu Gadu: 0
    Windows XPFirefox

Re: [BCB C++] Dopisywanie lini \r\n danych do dużych pliku

Nowy postprzez Darek_C++ » piątek, 31 sierpnia 2012, 13:53

Cyfrowy Baron napisał(a):Myślę, że Darek_C++ założył, że każde otwarcie pliku wiąże się z jego przetworzeniem, np. u mnie otwarcie pliku tekstowego o rozmiarze 54 MB w Notatniku trwa ~5 sekund, czyli w tym przypadku wielkość pliku ma wpływ na czas jego otwierania, a raczej ładowania.


Tak to nie myślałem, ale faktycznie myślałem, że zasoby związane "otwarciem" znacząco wpływa wielkość pliku. Wiec jak jestem przy tym temacie chciałem się dowiedzieć coś więcej na ten temat czy można to zrobić lepiej tzn szybciej i stąd ten post . Stawiałem na:

KOD cpp:     UKRYJ  
ofstream outfile("C://loggg.txt", ios::app);
outfile <<" linia do zapisu\n";
outfile.close();
Avatar użytkownika
Darek_C++
Elektrowied
Elektrowied
 
Posty: 454
Dołączył(a): piątek, 25 lipca 2008, 14:33
Podziękował : 66
Otrzymał podziękowań: 4
System operacyjny: Windows XP Pro SP2
Kompilator: Turbo Explorer C++
Gadu Gadu: 0
    Windows XPFirefox

Następna strona

  • Podobne tematy
    Odpowiedzi
    Wyświetlone
    Ostatni post

Powrót do Ogólne problemy z programowaniem

Kto przegląda forum

Użytkownicy przeglądający ten dział: Brak zalogowanych użytkowników i 12 gości

cron