| 707 | |
| 708 | #ifndef SFX_MODULE |
| 709 | int64 File::Copy(File &Dest,int64 Length) |
| 710 | { |
| 711 | Array<byte> Buffer(File::CopyBufferSize()); |
| 712 | int64 CopySize=0; |
| 713 | bool CopyAll=(Length==INT64NDF); |
| 714 | |
| 715 | while (CopyAll || Length>0) |
| 716 | { |
| 717 | Wait(); |
| 718 | size_t SizeToRead=(!CopyAll && Length<(int64)Buffer.Size()) ? (size_t)Length:Buffer.Size(); |
| 719 | byte *Buf=&Buffer[0]; |
| 720 | int ReadSize=Read(Buf,SizeToRead); |
| 721 | if (ReadSize==0) |
| 722 | break; |
| 723 | size_t WriteSize=ReadSize; |
| 724 | #ifdef _WIN_ALL |
| 725 | // For FAT32 USB flash drives in Windows if first write is 4 KB or more, |
| 726 | // write caching is disabled and "write through" is enabled, resulting |
| 727 | // in bad performance, especially for many small files. It happens when |
| 728 | // we create SFX archive on USB drive, because SFX module is written first. |
| 729 | // So we split the first write to small 1 KB followed by rest of data. |
| 730 | if (CopySize==0 && WriteSize>=4096) |
| 731 | { |
| 732 | const size_t FirstWrite=1024; |
| 733 | Dest.Write(Buf,FirstWrite); |
| 734 | Buf+=FirstWrite; |
| 735 | WriteSize-=FirstWrite; |
| 736 | } |
| 737 | #endif |
| 738 | Dest.Write(Buf,WriteSize); |
| 739 | CopySize+=ReadSize; |
| 740 | if (!CopyAll) |
| 741 | Length-=ReadSize; |
| 742 | } |
| 743 | return CopySize; |
| 744 | } |
| 745 | #endif |