|
[ Goran Arandjelovic @ 30.08.2005. 15:18 ] @
| U sta da smestim neki otvoreni binarni fajl? Npr, hocu binarno da otorim neki png... pokusao sam tako nesto da smestim u char*, ali to nije to to...znaci, hteo bih da smestim sadrzaj tog fajla negde, a onda da ga upisem binarno opet...i da novi fajl funkcionise bez problema...
Neka ideja?
Hvala unapred. |
[ X Files @ 30.08.2005. 15:43 ] @
U kom jeziku programiras, C ili C++?
Koji kompajler ili biblioteku(e) koristis?
Na C++ jeziku se ista stvar moze uraditi na nekoliko nacina...
Na primer, na C++ Builder-u, tvoj 'problem' bih zapoceo klasama:
TMemoryStream ili
TFileStream
... one opet imaju *skoro sve* sto ti je neophodno za manipulaciju podacima
nad kojima rade.
// NETESTIRANO
Code:
TMemoryStream *MS = NULL;
try
{
try
{
MS = new TMemoryStream;
MS->LoadFromFile( "C:\\nekifajl.png" );
// TMemoryStream ima sve sto je neophodno za...
// manipulaciju podacima: pomera blokove memorije, kopira, uklanja, ...
// skracuje velicinu buffera, povecava velicinu buffera, pristupa pojedinacnim...
// elementima... itd ...
MS->SaveToFile( "C:\\nekifajl.png" );
}
catch ( const Exception &e )
{
// Greska pri otvaranju datoteke...
}
}
__finally
{
if ( MS )
delete MS;
}
... inace sve si to mogao da uradis i preko char*, ali uz mnogo vise muke,
sto se narocito odnosi na povecavanje buffer-a... Dakle, mnoge metode bi
morao da uradis sam - za cije babe zdravlje?
P.S. Sto se tice otvaranja PNG fajla... Ne znam kako PNG format belezi podatke,
ali pazi, neke izmene na jednom mestu mozda moraju i negde drugde da se zabeleze kao nekavi checksum-i i sl..
Zato pogledaj
http://www.wotsit.org
...da proucis prvo format...
[ Goran Arandjelovic @ 30.08.2005. 15:51 ] @
Moja greska sto nisam naveo... da C++ je u pitanju, a koristim samo gcc...
E sada, zar se velicina buffera ne odredjuje unapred pre samog punjenja odredjivanjem velicine fajla? Hm..mislio sam da nije toliko bitno da li je PNG ili ma koji izvrsni fajl. Kako bi se to resilo samo sa fstream klasom?
[ Goran Arandjelovic @ 30.08.2005. 15:56 ] @
Dakle, evo kako bi to otprilike islo, ali postoji problem...
Code:
long size;
char *buffer;
fstream file("nekiizvrsnifajl",ios::in|ios::binary);
file.seekg(0,ios::end);
size = file.tellg();
file.seekg(0,ios::beg);
buffer = new char[size];
file.read(buffer,size);
file.close();
Medjutim, i posle ovoga buffer nije ispunjen celim sadrzajem i njegova velicina definitivno nije ista kao velicina fajla...
[Ovu poruku je menjao Goran Arandjelovic dana 30.08.2005. u 16:56 GMT+1]
[ Dragi Tata @ 30.08.2005. 16:14 ] @
Code: std::vector<unsigned char>
[ X Files @ 30.08.2005. 16:33 ] @
Tvoj kod mi deluje OK, i onako odokativno - siguran sam da sve lepo radi, jedino
ponekad je pametnije smestati podatke u 'unsigned char'...
Zasto mislis da velicina buffer-a ne odgovara velicini fajla?
Jesi li probao sa nekim probnim ispisom na ekran, da uporedis?
Inace TMemoryStream moze da menja velicinu buffer-a i to mu je jedana od
lepsih osobina...
[ Goran Arandjelovic @ 30.08.2005. 16:34 ] @
Aha... ali jel opet treba da kastujem u char*?
Code:
vector<unsigned char>fajl;
file.read((char*)&fajl, size);
ili sam pogresno shvatio...
[Ovu poruku je menjao Goran Arandjelovic dana 30.08.2005. u 17:35 GMT+1]
[ bzero @ 30.08.2005. 17:00 ] @
Citat:
Code:
long size;
char *buffer;
fstream file("nekiizvrsnifajl",ios::in|ios::binary);
file.seekg(0,ios::end);
size = file.tellg();
file.seekg(0,ios::beg);
buffer = new char[size];
file.read(buffer,size);
file.close();
Medjutim, i posle ovoga buffer nije ispunjen celim sadrzajem i njegova velicina definitivno nije ista kao velicina fajla...
Kako si odredio velicinu buffera i da nije ispunjen celim sadrzajem fajla?
Sta se desi kada odmah ispod gornjeg koda dodas sledece:
Code:
fstream outfile("copy_of_file", ios::out|ios::binary);
outfile.write(buffer,size);
outfile.close();
Trebao bi da dobijes kopiju originalnog fajla. Mozda si koristio neku string funkciju za rad sa buffer-om, kao strlen, sto nece raditi kako treba, jer ce one da rade samo do prvog null karaktera u bufferu.
[ Dragi Tata @ 30.08.2005. 17:06 ] @
Ne tako. U stvari, ja bih koristio funkciju get da čitam jedan po jedan bajt i dodajem ga u vektor. Ako se ispostavi da je to sporo, možeš da probaš da čitaš "na komade" sa npr funkcijom readsome pa da kopiraš u vektor.
[ Goran Arandjelovic @ 30.08.2005. 17:47 ] @
Citat: bzero:
Trebao bi da dobijes kopiju originalnog fajla. Mozda si koristio neku string funkciju za rad sa buffer-om, kao strlen, sto nece raditi kako treba, jer ce one da rade samo do prvog null karaktera u bufferu.
Ne dobija se kopija originalno fajla. Znam da je moglo da se desi nesto sa null karakterom...
Ovaj kod odozgo je sasim ok...ali probaj da ucinis nesto sa binarnim fajlom i videces sta ce se desiti.
@Dragi Tata
Razmisljao sam i ja da to cinim sa get, ali mi je zaista delovalo kao ekstremno sporo resenje...mada ne znam ni kako tacno radi read da bih sa sigurnoscu mogao da tvrdim kolika je razlika u brzini. E sada, mozda malo van teme, ali..mozes mi reci mozda na koji nacin funcionise vector kada se dodaje element...Da li negde tamo brise ceo niz pa pravi niz nove velicine(za jedan veci)...da li to radi u odredjenim koracima od po nekoliko elemenata ili nekako drugacije? Posto bi i to onda eventualno uticalo na brzinu ako su veci fajlovi u pitanju...
[ bzero @ 30.08.2005. 18:08 ] @
Citat: Ne dobija se kopija originalno fajla. Znam da je moglo da se desi nesto sa null karakterom...
Ovaj kod odozgo je sasim ok...ali probaj da ucinis nesto sa binarnim fajlom i videces sta ce se desiti.
Probao sam naravno, sledeci kod kopira originalni fajl (sliku, exe, bilo sta):
Code:
#include <iostream>
#include <fstream>
using namespace std;
int main() {
long size;
char *buffer;
fstream file("beep.exe", ios::in|ios::binary);
file.seekg(0,ios::end);
size = file.tellg();
file.seekg(0,ios::beg);
buffer = new char[size];
file.read(buffer,size);
file.close();
fstream outfile("copy_of_file", ios::out|ios::binary);
outfile.write(buffer,size);
outfile.close();
return 0;
}
[ Goran Arandjelovic @ 30.08.2005. 18:19 ] @
To je isto kao i ono sto ja napisah gore...pa zaista ne znam..jesi proverio? Taj exe fajl se pokrece bez ikakvih problema?
[ Dragi Tata @ 30.08.2005. 18:34 ] @
Citat: Goran Arandjelovic: ali..mozes mi reci mozda na koji nacin funcionise vector kada se dodaje element...Da li negde tamo brise ceo niz pa pravi niz nove velicine(za jedan veci)...da li to radi u odredjenim koracima od po nekoliko elemenata ili nekako drugacije? Posto bi i to onda eventualno uticalo na brzinu ako su veci fajlovi u pitanju...
Vektor raste eksponencijalno, a uvek možeš i da udariš jedan reserve na početku da izbegneš nepotrebne realokacije.
[ _VampiR_ @ 31.08.2005. 11:45 ] @
U prethodnom primjeru jedino sto bih ja jos dodao jeste alociranje buffera na velicinu fajla + 1, prije nego sto se sadrzaj datoteke kopira u buffer, to bi trebalo da radi kako treba, posto sam imao more takvih primjera u praksi.
[ Goran Arandjelovic @ 31.08.2005. 14:55 ] @
Ma da...ali nije poenta u tome. Tacno je da je mozda neophodno size povecati za jedan zbog \0 karaktera, ali je problem sto ucitavanje ne radi ni tada kako valja...Nisam bas imao vremena, ali probacu onako kako Tata rece, da punim vector bajt po bajt pa cu videti sta se desava...
[Ovu poruku je menjao Goran Arandjelovic dana 31.08.2005. u 15:55 GMT+1]
[ bzero @ 31.08.2005. 16:07 ] @
Meni samo jos uvek nije jasno sta ne radi kako valja, jer gornji kod radi sigurno sasvim ok (slika je slika, iskopirani exe radi i isti je kao original).
[ Goran Arandjelovic @ 01.09.2005. 18:23 ] @
Radi...opet sam sve prekucao pazljivo i sada funkcionise, ne znam sta je tacno bio problem. Moracu vise da pazim sledeci put. Moguce da se negde potkrao neki bajt, ali nije sigurno...
[ leka @ 02.09.2005. 10:20 ] @
Slike nema smisla "ucitavati" ni u sta drugo osim u nekakav (unsigned) char[] ili u gotovo, alocirano parce memorije (sto se opet svodi na gomilu bajtova (unsigned char)).
[ X Files @ 02.09.2005. 10:49 ] @
Da, slike nema smisla "ucitavati" ni u sta drugo osim u nekakav (unsigned) char[] ili
u gotovo, alocirano parce memorije...
Medjutim, ponekad, kada se radi o *ekstremno* velikim fajlovima, kao sto su na
primer video zapisi (>700MB), tada dinamicko alociranje celokupnog sadrzaja po
svoj prilici nece uspeti, jer nema dovoljno RAM-a, a i 'virtuelna' RAM nije
svemoguc...
Tada (umesto TMemoryStream) postoje posebne klase kao na primer kod Borland-a:
TFileStream
... koja je 'rastegljiva', i korisnik nece imati pojma da nije bas sve ucitano, a imaces
mogucnost da menjas velicinu Buffer-a, pomeras/kopiras parcice memorije
levo/desno, itd...
Pretpostavljam da sve ovo moze i sa STL, pa ako neko poznaje ovu oblast neka
baci neki link da procitam...
[ Goran Arandjelovic @ 02.09.2005. 16:16 ] @
Jasno... X Files..ne bi bilo lose da se postavi neki link o tome...resenje sa STL-om ako postoji ili neko “from scratch” resenje.
Leka je pomenuo...a ja bih da pitam..da li onda postoje specijalne strukture u koje bi se mogao ucitati neki jpg, png ili nesto drugo.. Drugim recima, kako napraviti sliku ako bi bio poznat samo RGB za jedan piksel..?
[ X Files @ 02.09.2005. 19:46 ] @
Citat:
da li onda postoje specijalne strukture u koje bi se mogao ucitati neki jpg, png ili
nesto drugo..
Zna se, za graficke formate kod Borlanda je TImage...
Citat:
Drugim recima, kako napraviti sliku ako bi bio poznat samo RGB za jedan piksel..?
Ovo bas nisam razumeo, pojasni...
Mozda si na ovo mislio:
// NETESTIRANO !!!
Code:
TImage *Image1 = new TImage(NULL);
Image1->Picture->LoadFromFile( PUTANJA DO GRAF.FAJLA NEPOZNATE EXTENZ. );
AnsiString PictType = Image1->Picture->Graphic->ClassName();
if ( PictType == "TBitmap" )
{
Image1->Picture->SaveToFile( "test.bmp" );
}
else if ( PictType == "TIcon" )
{
Image1->Picture->SaveToFile( "test.ico" );
}
else if ( PictType == "TMetafile" )
{
if ( Image1->Picture->Metafile->Enhanced == true )
{
Image1->Picture->SaveToFile( "test.emf" );
}
else
{
Image1->Picture->SaveToFile( "test.wmf" );
}
}
[ X Files @ 02.09.2005. 20:14 ] @
Mislim da sam sada razumeo, postoje neke specijalizovane klase, npr kod
Borlanda postoji i klasa:
TMetafileCanvas
U koju mozes da crtas tackice odredjene boje, ispisujes tekst TextOut() i sl,
i na kraju svoj rad snimis...
[ Goran Arandjelovic @ 03.09.2005. 18:16 ] @
Kod Borlanda...Ipak sam mislio samo na gcc... neka “standardnija” biblioteka/klasa...
[ X Files @ 03.09.2005. 19:16 ] @
Znam da si mislio na GCC... Cisto ti napominjem kao ideju i nacin kako i sta da trazis
po Helpu. Jer cim nesto postoji kod 'jednih' sigurno ima (mozda i novije, bolje) kod
drugih...
Nego, izgleda da su godisnji odmori jos u toku pa je i frekventnost na ovom forumu
slaba... Nista ti ne preostaje nego da sacekas nekoga ko ozbiljnije radi sa GCC-om
ili da sam 'bucas' po dokumentaciji...
Inace Borlandova VCL biblioteka (Delphi, C++Builder) je poprilicno dobro bila
osmisljena za ono vreme... Rekao bih da i neka njegova praistorijska verzija moze
da zadovolji vecinu danasnjih potreba koje vidim da se javljaju na ovoj diskusiji.
Medjutim, cenim da ce ipak u neko u dogledno vreme .NET da zagospodari... Bio
sam na nekim M$ kursevima i konceptualno sam prijatno izmenadjen...
[ Goran Arandjelovic @ 04.09.2005. 10:28 ] @
Naisao sam na ovaj link koji svima moze da posluzi...usput sam nasao i klase za razlicite formate slika...
http://www.thefreecountry.com/sourcecode/cpp.shtml
Copyright (C) 2001-2025 by www.elitesecurity.org. All rights reserved.
|