OctoTorrent.Client.SparseFile.CreateSparse C# (CSharp) Method

CreateSparse() public static method

public static CreateSparse ( string filename, long length ) : void
filename string
length long
return void
        public static void CreateSparse(string filename, long length)
        {
            if (!SupportsSparse)
                return;

            // Ensure we have the full path
            filename = Path.GetFullPath(filename);
            try
            {
                if (CanCreateSparse(filename) == false)
                    return;

                uint bytesReturned = 0;
                const uint access = (uint) 0x40000000;      // GenericWrite
                const int sharing = 0;                      // none
                const uint attributes = (uint) 0x00000080;  // Normal
                const uint creation = (uint) 1;             // Only create if new

                using (var handle = CreateFileW(filename, access, sharing, IntPtr.Zero, creation, attributes, IntPtr.Zero))
                {
                    // If we couldn't create the file, bail out
                    if (handle.IsInvalid)
                        return;

                    // If we can't set the sparse bit, bail out
                    if (!DeviceIoControl(handle, FSCTL_SET_SPARSE, IntPtr.Zero, 0, IntPtr.Zero, 0, ref bytesReturned, IntPtr.Zero))
                        return;

                    // Tell the filesystem to mark bytes 0 -> length as sparse zeros
                    var data = new FILE_ZERO_DATA_INFORMATION(0, length);
                    var structSize = (uint) Marshal.SizeOf(data);
                    var ptr = Marshal.AllocHGlobal((int) structSize);

                    try
                    {
                        Marshal.StructureToPtr(data, ptr, false);
                        DeviceIoControl(handle, FSCTL_SET_ZERO_DATA, ptr,
                                        structSize, IntPtr.Zero, 0, ref bytesReturned, IntPtr.Zero);
                    }
                    finally
                    {
                        Marshal.FreeHGlobal(ptr);
                    }
                }
            }
            catch (DllNotFoundException)
            {
                SupportsSparse = false;
            }
            catch (EntryPointNotFoundException)
            {
                SupportsSparse = false;
            }
            catch
            {
                // Ignore for now. Maybe if i keep hitting this i should abort future attemts
            }
        }

Usage Example

Esempio n. 1
0
        internal TorrentFileStream GetStream(TorrentFile file, FileAccess access)
        {
            var fileStream = FindStream(file.FullPath);

            if (fileStream != null)
            {
                // If we are requesting write access and the current stream does not have it
                if (((access & FileAccess.Write) == FileAccess.Write) && !fileStream.CanWrite)
                {
                    Logger.Log(null, "Didn't have write permission - reopening");
                    CloseAndRemove(fileStream);
                    fileStream = null;
                }
                else
                {
                    // Place the filestream at the end so we know it's been recently used
                    _list.Remove(fileStream);
                    _list.Add(fileStream);
                }
            }

            if (fileStream == null)
            {
                if (File.Exists(file.FullPath) == false)
                {
                    Directory.CreateDirectory(Path.GetDirectoryName(file.FullPath));
                    SparseFile.CreateSparse(file.FullPath, file.Length);
                }
                fileStream = new TorrentFileStream(file, FileMode.OpenOrCreate, access, FileShare.Read);

                // Ensure that we truncate existing files which are too large
                if (fileStream.Length > file.Length)
                {
                    if (!fileStream.CanWrite)
                    {
                        fileStream.Close();
                        fileStream = new TorrentFileStream(file, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.Read);
                    }
                    fileStream.SetLength(file.Length);
                }

                Add(fileStream);
            }

            return(fileStream);
        }