SubtitleEdit/subtitleedit · error · InvalidOperationException

End of file reached before expected

Error message

End of file reached before expected

What it means

Inside ReadAllBytesShared's read loop, Stream.Read returned 0 while count was still positive, meaning the file shrank or was concurrently truncated between the initial Length query and the reads. The buffer cannot be filled to the expected length, so the read is aborted rather than returning partial data.

Source

Thrown at src/libse/Common/FileUtil.cs:43

        public static byte[] ReadAllBytesShared(string path)
        {
            using (var fs = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
            {
                var index = 0;
                var fileLength = fs.Length;
                if (fileLength > int.MaxValue)
                {
                    throw new IOException("File too long");
                }

                var count = (int)fileLength;
                var bytes = new byte[count];
                while (count > 0)
                {
                    var n = fs.Read(bytes, index, count);
                    if (n == 0)
                    {
                        throw new InvalidOperationException("End of file reached before expected");
                    }

                    index += n;
                    count -= n;
                }

                return bytes;
            }
        }

        /// <summary>
        /// Opens a binary file in read/write shared mode, reads the specified number of bytes from the file into a byte array, and then closes the file.
        /// </summary>
        /// <param name="path">The file to open for reading.</param>
        /// <param name="bytesToRead">The number of bytes to read from the file.</param>
        /// <returns>A byte array containing the specified number of bytes read from the file.</returns>
        public static byte[] ReadBytesShared(string path, int bytesToRead)
        {

View on GitHub (pinned to 17a9f07487)

Solutions

  1. Open the file with FileShare.ReadWrite and snapshot it (copy) before reading when concurrent writers are expected.
  2. Retry the read once after a short delay if a partial-read is plausible.
  3. For growing files, use ReadBytesShared with the known prefix length instead of the full Length.
  4. Handle IOException and report which byte range could not be read.

Example fix

// before
var n = fs.Read(bytes, index, count);
if (n == 0) throw new InvalidOperationException("End of file reached before expected");

// after
var n = fs.Read(bytes, index, count);
if (n == 0)
{
    Array.Resize(ref bytes, index);
    break; // return what was read, or surface a partial-result exception with the index
Defensive patterns

Strategy: retry

Validate before calling

var info = new FileInfo(path);
if (info.Length > int.MaxValue) throw new IOException("File too long");
// optional: copy to a local snapshot before reading when a writer may truncate

Try / catch

try { bytes = FileUtil.ReadAllBytesShared(path); }
catch (InvalidOperationException ex) when (ex.Message.Contains("End of file")) { /* retry once or snapshot */ }

Prevention

When it happens

Trigger: Another process truncates/overwrites the file mid-read; the file is on a network share that drops content; sparse file whose reported length exceeds actual data; race with a writer that did not use FileShare.ReadWrite correctly.

Common situations: Reading a log file while it is being rotated; tailing a capture file still being written by a recorder; antivirus/quarantine removing bytes during read; virtualized/network filesystem inconsistencies.

Related errors


AI-assisted analysis of SubtitleEdit/subtitleedit@17a9f07487 (2026-08-13). Data as JSON: /api/errors/9126cd3b84e40f5a. Report an issue: GitHub.