Subversion Repositories spk

Rev

Go to most recent revision | Details | 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
		std::string line;
464
		if ( getline(m_fId, line, '\n') )
465
			return CyString(line);
466
	}
467
 
468
	sLine[pos] = 0;
469
	if ( pos )
470
		return CyString(sLine);
471
 
472
	if ( autoclose )
473
		StopRead();
474
	return "";
475
}
476
 
477
bool CFileIO::AtEnd()
478
{
479
	if ( !m_bOpened )
480
		return true;
481
 
482
	if ( m_fIdOld )
483
	{
484
		if ( feof(m_fIdOld) )
485
			return true;
486
	}
487
	else
488
	{
489
		if ( m_fId.eof() )
490
			return true;
491
	}
492
 
493
	return false;
494
}
495
 
496
bool CFileIO::AppendFile ( CyString filename )
497
{
498
	FILE *id = fopen ( filename.c_str(), (m_bBinary) ? "rb" : "r" );
499
	if ( !id )
500
		return false;
501
 
502
	FILE *aid = fopen ( m_sFilename.c_str(), (m_bBinary) ? "ab" : "a" );
503
	if ( !aid )
504
	{
505
		return false;
506
		fclose ( id );
507
	}
508
 
509
	// move to the end of the file
510
	fseek ( aid, 0, SEEK_END );
511
 
512
	// get size of file
513
	fseek ( id, 0, SEEK_END );
514
	size_t size = ftell ( id );
515
	fseek ( id, 0, SEEK_SET );
516
 
517
	char data[500000];
518
	while ( size > 0 )
519
	{
520
		size_t read = 500000;
521
		if ( read > size )
522
			read = size;
523
 
524
		size -= read;
525
 
526
		fread ( data, sizeof(char), read, id );
527
		fwrite ( data, sizeof(char), read, aid );
528
	}
529
 
530
	fclose ( aid );
531
	fclose ( id );
532
	return true;
533
}
534
 
535
 
536
bool CFileIO::AppendData ( const char *d, size_t size )
537
{
538
	FILE *aid = fopen ( m_sFilename.c_str(), (m_bBinary) ? "ab" : "a" );
539
	if ( !aid )
540
		return false;
541
 
542
	// move to the end of the file
543
	fseek ( aid, 0, SEEK_END );
544
 
545
	char *pos = (char *)d;
546
	while ( size > 0 )
547
	{
548
		size_t read = 500000;
549
		if ( read > size )
550
			read = size;
551
 
552
		size -= read;
553
 
554
		fwrite ( pos, sizeof(char), read, aid );
555
		pos += read;
556
	}
557
 
558
	fclose ( aid );
559
	return true;
560
}
561
 
562
bool CFileIO::AppendDataToPos ( const char *d, size_t size, size_t start )
563
{
564
	FILE *aid = fopen ( m_sFilename.c_str(), (m_bBinary) ? "ab" : "a" );
565
	if ( !aid )
566
		return false;
567
 
568
	// move to the end of the file
569
	fseek ( aid, 0, SEEK_END );
570
	size_t end = ftell(aid);
571
	if ( start > end )
572
	{
573
		fclose ( aid);
574
		return false;
575
	}
576
 
577
	fseek ( aid, start, SEEK_SET );
578
 
579
	char *pos = (char *)d;
580
	while ( size > 0 )
581
	{
582
		size_t read = 500000;
583
		if ( read > size )
584
			read = size;
585
 
586
		size -= read;
587
 
588
		fwrite ( pos, sizeof(char), read, aid );
589
		pos += read;
590
	}
591
 
592
	fclose ( aid );
593
	return true;
594
}
595
 
596
CyString CFileIO::GetBaseName()
597
{
598
	return m_sFile.GetTokenRev(".", 1, -1);
599
}
600
CyString CFileIO::GetFileExtension ()
601
{
602
	if ( m_sFilename.Empty() )
603
		return NullString;
604
 
605
	CyString ext = m_sFilename.GetToken ( ".", m_sFilename.NumToken ( "." ) );
606
	return ext;
607
}
608
 
609
CyString CFileIO::ChangeFileExtension ( CyString ext )
610
{
611
	if ( m_sFilename.Empty() )
612
		return NullString;
613
 
614
	CyString noext = m_sFilename.GetToken ( ".", 1, m_sFilename.NumToken ( "." ) - 1 );
615
	return noext + "." + ext;
616
}
617
 
618
bool CFileIO::Remove()
619
{
620
	if ( !Exists() )
621
		return false;
622
 
623
	if ( remove(m_sFilename.c_str()) == 0 )
624
		return true;
625
 
626
	return false;
627
}
628
 
629
bool CFileIO::WriteFileUTF(std::vector<CyString> *lines)
630
{
631
	if ( !lines || m_sFilename.Empty() )
632
		return false;
633
 
634
	// we need to create the directory
635
	if ( !m_sDirIO.Exists() )
636
	{
637
		if ( !m_sDirIO.Create() )
638
			return false;
639
	}
640
 
641
#ifdef _WIN32
642
	TCHAR buf[5000];
643
	wsprintf(buf, L"%hs", m_sFilename.c_str());
644
	FILE *id = _wfopen(buf, L"wt+,ccs=UTF-8");
645
	if ( !id )
646
		return false;
647
 
648
	// write the rest
649
	for ( int i = 0; i < (int)lines->size(); i++ )
650
	{
651
		CyString l = lines->at(i);
652
		if ( l.IsIn('\n') )
653
		{
654
			int max;
655
			CyString *strs = l.SplitToken("\n", &max);
656
			if ( strs && max )
657
			{
658
				for ( int i = 0; i < max; i++ )
659
				{
660
					CyString line = strs[i];
661
					line += "\n";
662
					int size = wsprintf(buf, L"%hs", line.c_str());
663
					fwrite(buf, sizeof(TCHAR), wcslen(buf), id);
664
				}
665
 
666
				CLEANSPLIT(strs, max);
667
			}
668
		}
669
		else
670
		{
671
			l += "\n";
672
			int size = wsprintf(buf, L"%hs", l.c_str());
673
			fwrite(buf, sizeof(TCHAR), wcslen(buf), id);
674
		}
675
	}
676
 
677
	fclose(id);
678
 
679
	return true;
680
#else
681
    //TODO: write utf8 file writing function
682
    return false;
683
#endif
684
}
685
 
686
bool CFileIO::WriteFile(std::vector<CyString> *lines)
687
{
688
	if ( !lines || m_sFilename.Empty() )
689
		return false;
690
 
691
	// we need to create the directory
692
	if ( !m_sDirIO.Exists() )
693
	{
694
		if ( !m_sDirIO.Create() )
695
			return false;
696
	}
697
 
698
 
699
	std::ofstream out(m_sFilename.c_str());
700
	if ( !out )
701
		return false;
702
 
703
	for ( int i = 0; i < (int)lines->size(); i++ )
704
	{
705
		CyString l = lines->at(i);
706
		out << l.c_str() << std::endl;
707
	}
708
 
709
	out.close();
710
 
711
	return true;
712
}
713
 
714
bool CFileIO::WriteFile(CyStringList *lines)
715
{
716
	if ( !lines || m_sFilename.Empty() )
717
		return false;
718
 
719
	// we need to create the directory
720
	if ( !m_sDirIO.Exists() )
721
	{
722
		if ( !m_sDirIO.Create() )
723
			return false;
724
	}
725
 
726
	std::ofstream out(m_sFilename.c_str());
727
	if ( !out )
728
		return false;
729
 
730
	/*
731
	if ( utf )
732
	{
733
		unsigned char smarker[4];
734
		smarker[0] = 0xEF;
735
		smarker[1] = 0xBB;
736
		smarker[2] = 0xBF;
737
		smarker[3] = 0x00;
738
 
739
		out << smarker;
740
	}
741
*/
742
	for ( int i = 0; i < (int)lines->Count(); i++ )
743
	{
744
		CyString l = lines->StringAt(i);
745
		out << l.c_str() << std::endl;
746
	}
747
 
748
	out.close();
749
 
750
	return true;
751
}
752
 
753
bool CFileIO::Rename(CyString toFile)
754
{
755
	if ( rename(m_sFilename.c_str(), toFile.c_str()) == 0 )
756
		return true;
757
	return false;
758
}
759
 
760
CyString CFileIO::GetWindowsFilename()
761
{
762
	CyString returnString = m_sFilename;
763
	returnString = returnString.FindReplace("/", "\\");
764
	return returnString;
765
}
766
 
767
void CFileIO::SetCreationTime(time_t time)
768
{
769
#ifdef _WIN32
770
	// Note that LONGLONG is a 64-bit value
771
    LONGLONG ll;
772
 
773
	FILETIME ft;
774
    ll = Int32x32To64(time, 10000000) + 116444736000000000;
775
    ft.dwLowDateTime = (DWORD)ll;
776
    ft.dwHighDateTime = ll >> 32;
777
 
778
	HANDLE filename = CreateFile((LPCWSTR)GetWindowsFilename().c_str(), FILE_WRITE_ATTRIBUTES, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
779
	// Set the file time on the file
780
	SetFileTime(filename,(LPFILETIME) NULL,(LPFILETIME) NULL,&ft);
781
	// Close our handle.
782
	CloseHandle(filename);
783
#endif
784
}
785
 
786
time_t CFileIO::GetCreationTime()
787
{
788
#ifdef _WIN32
789
	WIN32_FILE_ATTRIBUTE_DATA wfad;
790
	GetFileAttributesEx((LPCWSTR)GetWindowsFilename().c_str(), GetFileExInfoStandard, &wfad);
791
 
792
	LARGE_INTEGER date, adjust;
793
	date.HighPart = wfad.ftCreationTime.dwHighDateTime;
794
	date.LowPart = wfad.ftCreationTime.dwLowDateTime;
795
 
796
	// 100-nanoseconds = milliseconds * 10000
797
	adjust.QuadPart = 11644473600000 * 10000;
798
 
799
	// removes the diff between 1970 and 1601
800
	date.QuadPart -= adjust.QuadPart;
801
 
802
	// converts back from 100-nanoseconds to seconds
803
	return (time_t)(date.QuadPart / 10000000);
804
#else
805
	struct stat fileStat;
806
	if ( !stat(GetWindowsFilename().c_str(), &fileStat) )
807
		return (time_t)fileStat.st_atime;
808
#endif
809
	return 0;
810
}
811
/**
812
 * Copys the contents of a file to another
813
 *
814
 * Reads and writes the files in block
815
 */
816
bool CFileIO::Copy(CyString toFile, bool keepTime)
817
{
818
	//open both files
819
	FILE *id = fopen(GetWindowsFilename().c_str(), "rb");
820
	if ( !id )
821
		return false;
822
	FILE *toID = fopen(toFile.c_str(), "wb");
823
	if ( !toID )
824
	{
825
		fclose(id);
826
		return false;
827
	}
828
 
829
	time_t time = GetCreationTime();
830
 
831
	// get length of file
832
	fseek(id, 0, SEEK_END);
833
	size_t remainingLen = ftell(id);
834
	fseek(id, 0, SEEK_SET);
835
 
836
	if ( remainingLen <= 0 )
837
	{
838
		fclose(id);
839
		fclose(toID);
840
		return false;
841
	}
842
 
843
 
844
	// read then write a block
845
	char block[100000];
846
	while ( remainingLen )
847
	{
848
		size_t amt = 100000;
849
		if ( amt > remainingLen )
850
			amt = remainingLen;
851
 
852
		fread(block, amt, sizeof(char), id);
853
		fwrite(block, amt, sizeof(char), toID);
854
 
855
		remainingLen -= amt;
856
	}
857
 
858
	fclose(id);
859
	fclose(toID);
860
 
861
	if ( keepTime )
862
		CFileIO(toFile.c_str()).SetCreationTime(time);
863
 
864
 
865
	return true;
866
}