Messing around with files, i found that i needed some extra functionalities when i Read/Write in a (binary) file. For example i need to read a specific block of bytes with an offset (if exists – not out of bound) as well as write a given block of bytes to a certain address and select if the current block will override the existing data etc…

Unfortunately, some of those functionalities do not exist in the NetFramework but by combining the available API we are able to archive them. So, below you will find a simple static class which had only to methods Read and Write.

    public static class FileExt
    {
        private static readonly object fsLock = new object();

        public static byte[] Read(string filepath, int offset, int size)
        {
            byte[] result = null;

            try
            {
                result = new byte[size];

                lock (fsLock)
                {
                    using (FileStream fs = new FileStream(filepath, System.IO.FileMode.Open))
                    {
                        if (fs.CanSeek != true)
                            return null;

                        fs.Seek(offset, SeekOrigin.Begin);
                        var actualSize = fs.Read(result, 0, size);

                        if (actualSize != size)
                            Array.Resize(ref result, actualSize);
                    }
                }
            }
            catch { result = null; }

            return result;
        }

        public static void Write(string filepath, byte[] data, int offset, bool overriteData)
        {
            bool fileExists = File.Exists(filepath);
            
            try
            {
                using (FileStream fs = new FileStream(filepath + (fileExists == true ? ".tmp" : ""), FileMode.CreateNew))
                {
                    int partSize = 1024*10;
                    int parsedOffset = 0;
                    var preData = new byte[0];

                    if(offset>=partSize)
                        for(int i=0;i<partSize*(offset / partSize);i+= partSize)
                        {
                            preData = fileExists == true 
                                    ? Read(filepath, i, partSize) 
                                    : new byte[partSize];
                            preData = preData ?? (new byte[partSize]);
                            if(preData.Length!=partSize)
                                Array.Resize(ref preData, partSize);
                            fs.Write(preData, 0, partSize);
                            parsedOffset += partSize;
                        }

                    if (parsedOffset < offset)
                    {
                        preData = fileExists == true 
                                 ? Read(filepath, (offset / partSize) * partSize, offset - parsedOffset) 
                                 : new byte[offset - parsedOffset];
                        if (preData != null && preData.Length != 0)
                            fs.Write(preData, 0, preData.Length);
                    }

                    parsedOffset = offset;

                    fs.Write(data, 0, data.Length);
                    parsedOffset += overriteData == true ? data.Length : 0;

                    if (fileExists == false)
                        return;

                    do
                    {
                        preData = Read(filepath, parsedOffset, partSize);
                        fs.Write(preData, 0, preData.Length);
                        parsedOffset += preData.Length;
                    } while (preData != null && preData.Length != 0);
                }

                File.Copy(filepath + ".tmp", filepath,true);
                File.Delete(filepath + ".tmp");
            }
            catch { }
        }
    }

 

Author

Write A Comment