Subversion Repositories spk

Rev

Rev 1 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
1 cycrow 1
#include "File_IO.h"
2
 
3
#ifdef _WIN32
4
#include <windows.h>
5
#endif
6
 
7
#include <locale>
8
 
9
#include "DirIO.h"
10
#include "File.h"
11
 
12
CFileIO::CFileIO ()
13
{
14
	m_bOpened = false;
15
	m_lSize = 0;
16
	m_bBinary = true;
17
	m_fIdOld = NULL;
18
}
19
 
20
CFileIO::CFileIO(CyString filename)
21
{
22
	m_bOpened = false;
23
	m_lSize = 0;
24
	m_bBinary = true;
25
	m_fIdOld = NULL;
26
 
27
	Open ( filename, true );
28
}
29
 
30
CFileIO::CFileIO(C_File *file)
31
{
32
	m_bOpened = false;
33
	m_lSize = 0;
34
	m_bBinary = true;
35
	m_fIdOld = NULL;
36
 
37
	Open ( file->GetFilePointer(), true );
38
}
39
 
40
CFileIO::~CFileIO()
41
{
42
	if ( m_bOpened )
43
	{
44
		if ( m_fIdOld )
45
			fclose(m_fIdOld);
46
		else
47
			m_fId.close();
48
	}
49
}
50
 
51
bool CFileIO::Open ( CyString filename, bool binary )
52
{
53
	m_bBinary = binary;
54
	m_sFilename = filename;
55
	m_sFilename = m_sFilename.FindReplace ( "\\", "/" );
56
 
57
	if ( m_sFilename.IsIn('/') )
58
	{
59
		m_sDirIO.SetDir(m_sFilename.GetToken ( "/", 1, m_sFilename.NumToken ( "/" ) - 1 ));
60
		m_sFile = m_sFilename.GetToken ( "/", m_sFilename.NumToken ( "/" ) );
61
	}
62
	else
63
		m_sFile = filename;
64
 
65
	ReadFileSize();
66
	return true;
67
}
68
bool CFileIO::WritePartFile ( size_t *offsets, size_t numOffset )
69
{
70
	if ( NoFile() )
71
		return false;
72
 
73
	FILE *id = fopen ( m_sFilename.c_str(), (m_bBinary) ? "rb+" : "r+" );
74
	if ( !id )
75
		return false;
76
 
77
	// first find file size
78
	fseek ( id, 0, SEEK_END );
79
	size_t fullsize = ftell ( id ), size = fullsize;
80
	fseek ( id, 0, SEEK_SET );
81
 
82
	FILE *writeId = fopen ( "temp.tmp", (m_bBinary) ? "wb" : "w" );
83
	if ( !writeId )
84
	{
85
		fclose ( id );
86
		return false;
87
	}
88
 
89
	size_t off = 0;
90
 
91
	size_t startPos = 0;
92
	size_t remainingSize = fullsize;
93
	while ( off < numOffset )
94
	{
95
		startPos = ftell(id);
96
		size_t offset = offsets[off++];
97
		size_t size = offset - startPos;
98
		char *data = new char[size];
99
		fread ( data, sizeof(unsigned char), size, id );
100
		fwrite ( data, sizeof(unsigned char), size, writeId );
101
		delete data;
102
		size_t datasize = offsets[off++];
103
		fseek ( id, datasize, SEEK_CUR );
104
		remainingSize = fullsize - offset - datasize;
105
	}
106
 
107
	if ( remainingSize )
108
	{
109
		char data[1000000];
110
		size_t amountLeft = 1000000;
111
		while ( remainingSize )
112
		{
113
			if ( amountLeft > remainingSize )
114
				amountLeft = remainingSize;
115
			fread ( data, sizeof(unsigned char), amountLeft, id );
116
			fwrite ( data, sizeof(unsigned char), amountLeft, writeId );
117
 
118
			remainingSize -= amountLeft;
119
			amountLeft = 1000000;
120
		}
121
	}
122
 
123
	fclose ( writeId );
124
	fclose ( id );
125
 
126
	// now copy to original file
127
	remove ( m_sFilename.c_str() );
128
	rename ( "temp.tmp", m_sFilename.c_str() );
129
 
130
	return true;
131
}
132
 
133
 
134
void CFileIO::SetDir ( CyString dir )
135
{
136
	if ( m_sFile.Empty() )
137
		m_sDirIO.SetDir(dir);
138
	else
139
		Open ( dir + "/" + m_sFile, m_bBinary );
140
}
141
 
142
void CFileIO::ReadFileSize ()
143
{
144
	FILE *id = fopen ( m_sFilename.c_str(), (m_bBinary) ? "rb" : "r" );
145
	if ( !id )
146
	{
147
		m_lSize = 0;
148
		return;
149
	}
150
	fseek ( id, 0, SEEK_END );
151
	m_lSize = ftell ( id );
152
	fseek ( id, 0, SEEK_SET );
153
	fclose ( id );
154
}
155
 
156
bool CFileIO::WipeFile()
157
{
158
	if ( NoFile() )
159
		return false;
160
 
161
	FILE *id = fopen ( m_sFilename.c_str(), (m_bBinary) ? "rb+" : "r+" );
162
	if ( !id )
163
		return false;
164
	fclose(id);
165
 
166
	return true;
167
}
168
int CFileIO::TruncateFile ( size_t offset, size_t datasize )
169
{
170
	if ( NoFile() )
171
		return FILEERR_NOFILE;
172
 
173
	FILE *id = fopen ( m_sFilename.c_str(), (m_bBinary) ? "rb+" : "r+" );
174
	if ( !id )
175
		return FILEERR_NOOPEN;
176
 
177
	// first find file size
178
	fseek ( id, 0, SEEK_END );
179
	size_t fullsize = ftell ( id ), size = fullsize;
180
	fseek ( id, 0, SEEK_SET );
181
 
182
	if ( (offset + datasize) > fullsize )
183
		return FILEERR_TOSMALL;
184
//	char data[500000];
185
 
186
#ifdef _WIN32
187
	FILE *writeId = fopen ( "temp.tmp", (m_bBinary) ? "wb" : "w" );
188
	if ( !writeId )
189
	{
190
		fclose ( id );
191
		return FILEERR_NOWRITE;
192
	}
193
 
194
	char *data = new char[offset];
195
	fread ( data, sizeof(unsigned char), offset, id );
196
	fwrite ( data, sizeof(unsigned char), offset, writeId );
197
	delete data;
198
 
199
	/*
200
	// first write the data before the file
201
	size_t tosize = offset;
202
	while ( tosize )
203
	{
204
		int read = 500000;
205
		if ( read > tosize )
206
			read = tosize;
207
 
208
		fread ( data, sizeof(unsigned char), read, id );
209
		fwrite ( data, sizeof(unsigned char), read, writeId );
210
 
211
		tosize -= read;
212
	}
213
*/
214
	// next fseek after and write
215
	fseek ( id, datasize, SEEK_CUR );
216
	size = fullsize - offset - datasize;
217
	data = new char[size];
218
	fread ( data, sizeof(unsigned char), size, id );
219
	fwrite ( data, sizeof(unsigned char), size, writeId );
220
 
221
	delete data;
222
	/*
223
	while ( size )
224
	{
225
		int read = 500000;
226
		if ( read > size )
227
			read = size;
228
 
229
		fread ( data, sizeof(unsigned char), read, id );
230
		fwrite ( data, sizeof(unsigned char), read, writeId );
231
 
232
		size -= read;
233
	}*/
234
 
235
	fclose ( writeId );
236
	fclose ( id );
237
 
238
	// now copy to original file
239
	remove ( m_sFilename.c_str() );
240
	rename ( "temp.tmp", m_sFilename.c_str() );
241
 
242
#else
243
	// move to beginning of file data to remove
244
	fseek ( id, offset, SEEK_SET );
245
 
246
	size_t writepos = offset;
247
	size_t readpos = offset + datasize;
248
 
249
	size -= readpos;
250
 
251
	while ( size > 0 )
252
	{
253
		int read = 500000;
254
		if ( read > size )
255
			read = size;
256
 
257
		// read data
258
		fseek ( id, readpos, SEEK_SET );
259
		fread ( data, sizeof(unsigned char), read, id );
260
		size -= read;
261
		readpos += read;
262
 
263
		// now seek back and write
264
		fseek ( id, writepos, SEEK_SET );
265
		fwrite ( data, sizeof(unsigned char), read, id );
266
		writepos += read;
267
 
268
	}
269
 
270
	truncate ( m_sFilename.c_str(), fullsize - datasize );
271
	fclose ( id );
272
#endif
273
 
274
	return FILEERR_NONE;
275
}
276
 
277
char *CFileIO::ReadToData ( size_t *size )
278
{
279
	*size = 0;
280
 
281
	if ( NoFile() )
282
		return NULL;
283
 
284
	if ( !m_lSize )
285
		ReadFileSize();
286
 
287
	if ( !m_lSize )
288
		return NULL;
289
 
290
	FILE *id = fopen ( m_sFilename.c_str(), (m_bBinary) ? "rb" : "r" );
291
	if ( !id )
292
		return NULL;
293
 
294
	char *data = new char[m_lSize];
295
 
296
	fread ( data, sizeof(char), m_lSize, id );
297
	if ( ferror (id) )
298
	{
299
		fclose ( id );
300
		return NULL;
301
	}
302
 
303
	*size = m_lSize;
304
	fclose ( id );
305
 
306
	return data;
307
}
308
 
309
bool CFileIO::WriteData ( const char *data, size_t size )
310
{
311
	if ( NoFile() )
312
		return false;
313
 
314
	FILE *id = fopen ( m_sFilename.c_str(), (m_bBinary) ? "wb" : "w" );
315
	if ( !id )
316
		return false;
317
 
318
	fwrite ( data, size, sizeof(char), id );
319
	fclose ( id );
320
 
321
	ReadFileSize();
322
 
323
	return true;
324
}
325
 
326
bool CFileIO::WriteString ( CyString data )
327
{
328
	return WriteData ( data.c_str(), data.Length() );
329
}
330
 
331
bool CFileIO::Exists ()
332
{
333
	FILE *id = fopen ( m_sFilename.c_str(), (m_bBinary) ? "rb" : "r" );
334
	if ( !id )
335
		return false;
336
 
337
	fclose ( id );
338
	return true;
339
}
340
 
341
bool CFileIO::StartReadOld()
342
{
343
	if ( !m_sFilename.Empty() )
344
	{
345
		if ( m_bOpened )
346
			StopRead();
347
 
348
		m_fIdOld = fopen(m_sFilename.c_str(), "rb");
349
		if ( !m_fIdOld )
350
			return false;
351
		m_bOpened = true;
352
		return true;
353
	}
354
	return false;
355
}
356
 
357
bool CFileIO::StartRead()
358
{
359
	if ( !m_sFilename.Empty() )
360
	{
361
		if ( m_bOpened )
362
			StopRead();
363
 
364
		m_fId.open(m_sFilename.c_str(), std::ios_base::in);
365
		if ( m_fId.is_open() )
366
		{
367
			m_bOpened = true;
368
			return true;
369
		}
370
	}
371
	return false;
372
}
373
 
374
std::vector<CyString> *CFileIO::ReadLines()
375
{
376
	if ( m_sFilename.Empty() )
377
		return 0;
378
 
379
	std::vector<CyString> *file = new std::vector<CyString>;
380
	std::string line;
381
	file->clear();
382
	std::ifstream infile (m_sFilename.c_str(), std::ios_base::in);
383
	while (getline(infile, line, '\n'))
384
	{
385
		CyString l = line;
386
		l.RemoveChar((char)0);
387
		file->push_back(l);
388
	}
389
 
390
	infile.close();
391
 
392
	return file;
393
}
394
 
395
CyStringList *CFileIO::ReadLinesStr()
396
{
397
	if ( m_sFilename.Empty() )
398
		return 0;
399
 
400
	CyStringList *file = new CyStringList;
401
	std::string line;
402
	std::ifstream infile (m_sFilename.c_str(), std::ios_base::in);
403
	while (getline(infile, line, '\n'))
404
	{
405
		CyString l = line;
406
		l.RemoveChar((char)0);
407
		file->PushBack(l);
408
	}
409
 
410
	infile.close();
411
 
412
	return file;
413
}
414
 
415
void CFileIO::StopRead()
416
{
417
	if ( m_bOpened )
418
	{
419
		if ( m_fIdOld )
420
			fclose(m_fIdOld);
421
		else
422
			m_fId.close();
423
	}
424
	m_fIdOld = NULL;
425
	m_bOpened = false;
426
}
427
 
428
bool CFileIO::IsOpened()
429
{
430
	if ( !m_bOpened )
431
		return false;
432
	if ( m_fIdOld )
433
		return true;
434
	if ( m_fId.is_open() )
435
		return true;
436
	return false;
437
}
438
 
439
CyString CFileIO::ReadToEndLine(bool autoclose)
440
{
441
	if ( !this->IsOpened() )
442
	{
443
		if ( !StartRead() )
444
			return "";
445
	}
446
 
447
	int pos = 0;
448
	char sLine[10000];
449
	char cur = 0;
450
 
451
	if ( m_fIdOld )
452
	{
453
		while ( !feof(m_fIdOld) )
454
		{
455
			cur = fgetc(m_fIdOld);
456
			if ( cur == '\n' || cur == '\r' )
457
				break;
458
			sLine[pos++] = cur;
459
		}
460
	}
461
	else
462
	{
463
		while ( !m_fId.eof() )
464
		{
465
			cur = m_fId.get();
466
			if ( cur == '\n' || cur == '\r' )
467
				break;
468
			sLine[pos++] = cur;
469
		}
470
	//	m_fId.getline(sLine, 255, '\n');
471
 
472
 
473
		std::string line;
474
		if ( getline(m_fId, line, '\n') )
475
			return CyString(line);
476
	}
477
 
478
	sLine[pos] = 0;
479
	if ( pos )
480
		return CyString(sLine);
481
 
482
	if ( autoclose )
483
		StopRead();
484
	return "";
485
}
486
 
487
bool CFileIO::AtEnd()
488
{
489
	if ( !m_bOpened )
490
		return true;
491
 
492
	if ( m_fIdOld )
493
	{
494
		if ( feof(m_fIdOld) )
495
			return true;
496
	}
497
	else
498
	{
499
		if ( m_fId.eof() )
500
			return true;
501
	}
502
 
503
	return false;
504
}
505
 
506
bool CFileIO::AppendFile ( CyString filename )
507
{
508
	FILE *id = fopen ( filename.c_str(), (m_bBinary) ? "rb" : "r" );
509
	if ( !id )
510
		return false;
511
 
512
	FILE *aid = fopen ( m_sFilename.c_str(), (m_bBinary) ? "ab" : "a" );
513
	if ( !aid )
514
	{
515
		return false;
516
		fclose ( id );
517
	}
518
 
519
	// move to the end of the file
520
	fseek ( aid, 0, SEEK_END );
521
 
522
	// get size of file
523
	fseek ( id, 0, SEEK_END );
524
	size_t size = ftell ( id );
525
	fseek ( id, 0, SEEK_SET );
526
 
527
	char data[500000];
528
	while ( size > 0 )
529
	{
530
		size_t read = 500000;
531
		if ( read > size )
532
			read = size;
533
 
534
		size -= read;
535
 
536
		fread ( data, sizeof(char), read, id );
537
		fwrite ( data, sizeof(char), read, aid );
538
	}
539
 
540
	fclose ( aid );
541
	fclose ( id );
542
	return true;
543
}
544
 
545
 
546
bool CFileIO::AppendData ( const char *d, size_t size )
547
{
548
	FILE *aid = fopen ( m_sFilename.c_str(), (m_bBinary) ? "ab" : "a" );
549
	if ( !aid )
550
		return false;
551
 
552
	// move to the end of the file
553
	fseek ( aid, 0, SEEK_END );
554
 
555
	char *pos = (char *)d;
556
	while ( size > 0 )
557
	{
558
		size_t read = 500000;
559
		if ( read > size )
560
			read = size;
561
 
562
		size -= read;
563
 
564
		fwrite ( pos, sizeof(char), read, aid );
565
		pos += read;
566
	}
567
 
568
	fclose ( aid );
569
	return true;
570
}
571
 
572
bool CFileIO::AppendDataToPos ( const char *d, size_t size, size_t start )
573
{
574
	FILE *aid = fopen ( m_sFilename.c_str(), (m_bBinary) ? "ab" : "a" );
575
	if ( !aid )
576
		return false;
577
 
578
	// move to the end of the file
579
	fseek ( aid, 0, SEEK_END );
580
	size_t end = ftell(aid);
581
	if ( start > end )
582
	{
583
		fclose ( aid);
584
		return false;
585
	}
586
 
587
	fseek ( aid, start, SEEK_SET );
588
 
589
	char *pos = (char *)d;
590
	while ( size > 0 )
591
	{
592
		size_t read = 500000;
593
		if ( read > size )
594
			read = size;
595
 
596
		size -= read;
597
 
598
		fwrite ( pos, sizeof(char), read, aid );
599
		pos += read;
600
	}
601
 
602
	fclose ( aid );
603
	return true;
604
}
605
 
606
CyString CFileIO::GetBaseName()
607
{
608
	return m_sFile.GetTokenRev(".", 1, -1);
609
}
610
CyString CFileIO::GetFileExtension ()
611
{
612
	if ( m_sFilename.Empty() )
613
		return NullString;
614
 
615
	CyString ext = m_sFilename.GetToken ( ".", m_sFilename.NumToken ( "." ) );
616
	return ext;
617
}
618
 
619
CyString CFileIO::ChangeFileExtension ( CyString ext )
620
{
621
	if ( m_sFilename.Empty() )
622
		return NullString;
623
 
624
	CyString noext = m_sFilename.GetToken ( ".", 1, m_sFilename.NumToken ( "." ) - 1 );
625
	return noext + "." + ext;
626
}
627
 
628
bool CFileIO::Remove()
629
{
630
	if ( !Exists() )
631
		return false;
632
 
633
	if ( remove(m_sFilename.c_str()) == 0 )
634
		return true;
635
 
636
	return false;
637
}
638
 
639
bool CFileIO::WriteFileUTF(std::vector<CyString> *lines)
640
{
641
	if ( !lines || m_sFilename.Empty() )
642
		return false;
643
 
644
	// we need to create the directory
645
	if ( !m_sDirIO.Exists() )
646
	{
647
		if ( !m_sDirIO.Create() )
648
			return false;
649
	}
650
 
651
#ifdef _WIN32
652
	TCHAR buf[5000];
653
	wsprintf(buf, L"%hs", m_sFilename.c_str());
654
	FILE *id = _wfopen(buf, L"wt+,ccs=UTF-8");
655
	if ( !id )
656
		return false;
657
 
658
	// write the rest
659
	for ( int i = 0; i < (int)lines->size(); i++ )
660
	{
661
		CyString l = lines->at(i);
662
		if ( l.IsIn('\n') )
663
		{
664
			int max;
665
			CyString *strs = l.SplitToken("\n", &max);
666
			if ( strs && max )
667
			{
668
				for ( int i = 0; i < max; i++ )
669
				{
670
					CyString line = strs[i];
671
					line += "\n";
672
					int size = wsprintf(buf, L"%hs", line.c_str());
673
					fwrite(buf, sizeof(TCHAR), wcslen(buf), id);
674
				}
675
 
676
				CLEANSPLIT(strs, max);
677
			}
678
		}
679
		else
680
		{
681
			l += "\n";
682
			int size = wsprintf(buf, L"%hs", l.c_str());
683
			fwrite(buf, sizeof(TCHAR), wcslen(buf), id);
684
		}
685
	}
686
 
687
	fclose(id);
688
 
689
	return true;
690
#else
691
    //TODO: write utf8 file writing function
692
    return false;
693
#endif
694
}
695
 
696
bool CFileIO::WriteFile(std::vector<CyString> *lines)
697
{
698
	if ( !lines || m_sFilename.Empty() )
699
		return false;
700
 
701
	// we need to create the directory
702
	if ( !m_sDirIO.Exists() )
703
	{
704
		if ( !m_sDirIO.Create() )
705
			return false;
706
	}
707
 
708
 
709
	std::ofstream out(m_sFilename.c_str());
710
	if ( !out )
711
		return false;
712
 
713
	for ( int i = 0; i < (int)lines->size(); i++ )
714
	{
715
		CyString l = lines->at(i);
716
		out << l.c_str() << std::endl;
717
	}
718
 
719
	out.close();
720
 
721
	return true;
722
}
723
 
724
bool CFileIO::WriteFile(CyStringList *lines)
725
{
726
	if ( !lines || m_sFilename.Empty() )
727
		return false;
728
 
729
	// we need to create the directory
730
	if ( !m_sDirIO.Exists() )
731
	{
732
		if ( !m_sDirIO.Create() )
733
			return false;
734
	}
735
 
736
	std::ofstream out(m_sFilename.c_str());
737
	if ( !out )
738
		return false;
739
 
740
	/*
741
	if ( utf )
742
	{
743
		unsigned char smarker[4];
744
		smarker[0] = 0xEF;
745
		smarker[1] = 0xBB;
746
		smarker[2] = 0xBF;
747
		smarker[3] = 0x00;
748
 
749
		out << smarker;
750
	}
751
*/
752
	for ( int i = 0; i < (int)lines->Count(); i++ )
753
	{
754
		CyString l = lines->StringAt(i);
755
		out << l.c_str() << std::endl;
756
	}
757
 
758
	out.close();
759
 
760
	return true;
761
}
762
 
763
bool CFileIO::Rename(CyString toFile)
764
{
765
	if ( rename(m_sFilename.c_str(), toFile.c_str()) == 0 )
766
		return true;
767
	return false;
768
}
769
 
770
CyString CFileIO::GetWindowsFilename()
771
{
772
	CyString returnString = m_sFilename;
773
	returnString = returnString.FindReplace("/", "\\");
774
	return returnString;
775
}
776
 
777
void CFileIO::SetCreationTime(time_t time)
778
{
779
#ifdef _WIN32
780
	// Note that LONGLONG is a 64-bit value
781
    LONGLONG ll;
782
 
783
	FILETIME ft;
784
    ll = Int32x32To64(time, 10000000) + 116444736000000000;
785
    ft.dwLowDateTime = (DWORD)ll;
786
    ft.dwHighDateTime = ll >> 32;
787
 
788
	HANDLE filename = CreateFile((LPCWSTR)GetWindowsFilename().c_str(), FILE_WRITE_ATTRIBUTES, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
789
	// Set the file time on the file
790
	SetFileTime(filename,(LPFILETIME) NULL,(LPFILETIME) NULL,&ft);
791
	// Close our handle.
792
	CloseHandle(filename);
793
#endif
794
}
795
 
796
time_t CFileIO::GetCreationTime()
797
{
798
#ifdef _WIN32
799
	WIN32_FILE_ATTRIBUTE_DATA wfad;
800
	GetFileAttributesEx((LPCWSTR)GetWindowsFilename().c_str(), GetFileExInfoStandard, &wfad);
801
 
802
	LARGE_INTEGER date, adjust;
803
	date.HighPart = wfad.ftCreationTime.dwHighDateTime;
804
	date.LowPart = wfad.ftCreationTime.dwLowDateTime;
805
 
806
	// 100-nanoseconds = milliseconds * 10000
807
	adjust.QuadPart = 11644473600000 * 10000;
808
 
809
	// removes the diff between 1970 and 1601
810
	date.QuadPart -= adjust.QuadPart;
811
 
812
	// converts back from 100-nanoseconds to seconds
813
	return (time_t)(date.QuadPart / 10000000);
814
#else
815
	struct stat fileStat;
816
	if ( !stat(GetWindowsFilename().c_str(), &fileStat) )
817
		return (time_t)fileStat.st_atime;
818
#endif
819
	return 0;
820
}
821
/**
822
 * Copys the contents of a file to another
823
 *
824
 * Reads and writes the files in block
825
 */
826
bool CFileIO::Copy(CyString toFile, bool keepTime)
827
{
828
	//open both files
829
	FILE *id = fopen(GetWindowsFilename().c_str(), "rb");
830
	if ( !id )
831
		return false;
832
	FILE *toID = fopen(toFile.c_str(), "wb");
833
	if ( !toID )
834
	{
835
		fclose(id);
836
		return false;
837
	}
838
 
839
	time_t time = GetCreationTime();
840
 
841
	// get length of file
842
	fseek(id, 0, SEEK_END);
843
	size_t remainingLen = ftell(id);
844
	fseek(id, 0, SEEK_SET);
845
 
846
	if ( remainingLen <= 0 )
847
	{
848
		fclose(id);
849
		fclose(toID);
850
		return false;
851
	}
852
 
853
 
854
	// read then write a block
855
	char block[100000];
856
	while ( remainingLen )
857
	{
858
		size_t amt = 100000;
859
		if ( amt > remainingLen )
860
			amt = remainingLen;
861
 
862
		fread(block, amt, sizeof(char), id);
863
		fwrite(block, amt, sizeof(char), toID);
864
 
865
		remainingLen -= amt;
866
	}
867
 
868
	fclose(id);
869
	fclose(toID);
870
 
871
	if ( keepTime )
872
		CFileIO(toFile.c_str()).SetCreationTime(time);
873
 
874
 
875
	return true;
876
}