简体   繁体   中英

Copying offset to offset from file in C#

I have a bunch of very large video files (.ts) that range from 3GB up to 10GB. A lot of them have a specific error in them, and my solution is to simply cut out the part that contains the error. I have known starting and ending offsets for the parts I want to KEEP, and I was hoping to simply read in the main file and copy from start_offset to end_offset into a new file in the same folder.

For example, I have the main video MAIN.ts, which is 5.5GB. Let's say it has two of these errors. I want to keep offsets (in decimal, not hex) 0 through 1174698823 (the byte before the error starts) and save that to a new file, PART1.ts. Then I want to keep the offsets 1257553244 (the byte after the error ends) through offset 4126897791 (2nd error begin) and save that as PART2.ts. Then I need to save offsets 4207333028 through the end of the file as PART3.ts. Basically I just cut out about 155MB of the file and split it into three parts. If I could actually do the cuts without creating multiple new files and instead append them to each other as I go, then write the entire new file, that would be a bonus (or I could just use copy /b later).

I've been looking into filestreams and byte arrays, and I know about the 2GB limit. How do I get around this, and then if the length of the chunk I'm trying to keep is >2GB, how do I write it? I'm not sure how to use limited-length buffers to do this. If possible, I'd like to have a progress bar as well to show how much has been written.

Any help would be appreciated.

You definitely don't need to create new files. You can just open the output file once and the input file once, then append chunks by seeking in the input file, then copying one section from the input stream to the output stream before moving onto the next section.

 using (var output = File.Create("output.ts"))
 using (var input = File.OpenRead("input.ts"))
 {
     AppendChunk(output, input, 0, 1174698823L);
     AppendChunk(output, input, 1257553244L, 4126897791L);
 }

 ...

 private static void AppendChunk(Stream output, Stream input,
                                 long start, long end)
 {
     // TODO: Argument validation
     long size = end - start;
     byte[] buffer = new byte[32 * 1024]; // Copy 32K at a time
     input.Position = start;
     while (size > 0)
     {              
         int bytesRead = input.Read(buffer, 0, Math.Min(size, buffer.Length));
         if (bytesRead <= 0)
         {
             throw new EndOfStreamException("Not enough data");
         }
         output.Write(buffer, 0, bytesRead);
         size -= bytesRead;
     }
 }

To integrate a progress bar, you would want to work out the total size to copy beforehand, and then in the loop, increment the total copied so far, and update the progress bar that way. Don't forget that if this is in WinForms or WPF, you shouldn't do any of the IO work on the UI thread.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM