/// <summary> /// Find all occurance of byte[] in stream and return an IEnumerable contening index when is find. /// </summary> /// <param name="findtest"></param> public IEnumerable <long> FindIndexOf(byte[] bytesTofind, long startPosition = 0) { //start position checkup if (startPosition > Length) { startPosition = Length; } else if (startPosition < 0) { startPosition = 0; } //var Position = startPosition; byte[] buffer = new byte[ConstantReadOnly.FIND_BLOCK_SIZE]; IEnumerable <long> findindex; List <long> indexList = new List <long>(); //Launch event at process strated IsOnLongProcess = true; LongProcessProgressStarted?.Invoke(this, new EventArgs()); //start find for (long i = startPosition; i < Length; i++) { //Do not freeze UI... if (i % 2000 == 0) { LongProcessProgress = (double)Position / Length; } //Break long process if needed if (!IsOnLongProcess) { break; } if ((byte)ReadByte() == bytesTofind[0]) { //position correction after read one byte Position--; i--; if (buffer.Length > Length - Position) { buffer = new byte[Length - Position]; } //read buffer and find _stream.Read(buffer, 0, buffer.Length); findindex = buffer.FindIndexOf(bytesTofind); //if byte if find add to list if (findindex.Count() > 0) { foreach (long index in findindex) { indexList.Add(index + i + 1); } } //position correction i += buffer.Length; } } //Yield return all finded occurence foreach (long index in indexList) { yield return(index); } //Launch event at process completed IsOnLongProcess = false; LongProcessProgressCompleted?.Invoke(this, new EventArgs()); }
/// <summary> /// Submit change to files/stream /// TODO : NEED OPTIMISATION FOR LARGE FILE... IT'S AS BEGINING :) USE TEMPS FILE ? /// TODO : USE TEMPS FILE FOR LARGE FILE /// </summary> public void SubmitChanges() { if (CanWrite) { //Set percent of progress to zero and create and iterator for help mesure progress LongProcessProgress = 0; int i = 0; //Create appropriate temp stream for new file. Stream NewStream = null; if (Length < ConstantReadOnly.LARGE_FILE_LENGTH) { NewStream = new MemoryStream(); } else { NewStream = File.Open(Path.GetTempFileName(), FileMode.Open, FileAccess.ReadWrite); } //Fast change only nothing byte deleted or added if (ByteModifieds(ByteAction.Deleted).Count() == 0 && ByteModifieds(ByteAction.Added).Count() == 0) { //Launch event at process strated IsOnLongProcess = true; LongProcessProgressStarted?.Invoke(this, new EventArgs()); var bytemodifiedList = ByteModifieds(ByteAction.Modified); double countChange = bytemodifiedList.Count(); i = 0; //Fast save. only save byteaction=modified foreach (ByteModified bm in bytemodifiedList) { if (bm.IsValid) { //Set percent of progress LongProcessProgress = i++ / countChange; //Break process? if (!IsOnLongProcess) { break; } _stream.Position = bm.BytePositionInFile; _stream.WriteByte(bm.Byte.Value); } } //Launch event at process completed IsOnLongProcess = false; LongProcessProgressCompleted?.Invoke(this, new EventArgs()); } else { //Launch event at process strated IsOnLongProcess = true; LongProcessProgressStarted?.Invoke(this, new EventArgs()); byte[] buffer = new byte[ConstantReadOnly.COPY_BLOCK_SIZE]; long bufferlength = 0; var SortedBM = ByteModifieds(ByteAction.All).OrderBy(b => b.BytePositionInFile); double countChange = SortedBM.Count(); i = 0; //Set position Position = 0; ////Start update and rewrite file. foreach (ByteModified nextByteModified in SortedBM) { //Set percent of progress LongProcessProgress = (i++ / countChange); //Break process? if (!IsOnLongProcess) { break; } //Reset buffer buffer = new byte[ConstantReadOnly.COPY_BLOCK_SIZE]; //start read/write / use little block for optimize memory while (Position != nextByteModified.BytePositionInFile) { bufferlength = nextByteModified.BytePositionInFile - Position; //TEMPS if (bufferlength < 0) { bufferlength = 1; } //EOF if (bufferlength < ConstantReadOnly.COPY_BLOCK_SIZE) { buffer = new byte[bufferlength]; } _stream.Read(buffer, 0, buffer.Length); NewStream.Write(buffer, 0, buffer.Length); } //Apply ByteAction! switch (nextByteModified.Action) { case ByteAction.Added: //TODO : IMPLEMENTING ADD BYTE break; case ByteAction.Deleted: //NOTHING TODO we dont want to add deleted byte Position++; break; case ByteAction.Modified: Position++; NewStream.WriteByte(nextByteModified.Byte.Value); break; } //Read/Write the last section of file if (nextByteModified.BytePositionInFile == SortedBM.Last().BytePositionInFile) { while (!EOF) { bufferlength = _stream.Length - Position; //EOF if (bufferlength < ConstantReadOnly.COPY_BLOCK_SIZE) { buffer = new byte[bufferlength]; } _stream.Read(buffer, 0, buffer.Length); NewStream.Write(buffer, 0, buffer.Length); } } } //Write new data to current stream Position = 0; NewStream.Position = 0; buffer = new byte[ConstantReadOnly.COPY_BLOCK_SIZE]; while (!EOF) { //Set percent of progress LongProcessProgress = ((double)Position / (double)Length); //Break process? if (!IsOnLongProcess) { break; } bufferlength = _stream.Length - Position; //EOF if (bufferlength < ConstantReadOnly.COPY_BLOCK_SIZE) { buffer = new byte[bufferlength]; } NewStream.Read(buffer, 0, buffer.Length); _stream.Write(buffer, 0, buffer.Length); } _stream.SetLength(NewStream.Length); //dispose resource NewStream.Close(); buffer = null; //Launch event at process completed IsOnLongProcess = false; LongProcessProgressCompleted?.Invoke(this, new EventArgs()); } //Launch event ChangesSubmited?.Invoke(this, new EventArgs()); } else { throw new Exception("Cannot write to file."); } }