Search code examples
c#filestreambinaryfiles

Read first X bytes of binary file into new files


I am trying to get the first few K of a file and store it into a temporary file without any changes other than length. For some reason, this code seems to be returning something from the middle of the file rather than the beginning.

    public static FileStream stream = new FileStream(@"isam.dat", FileMode.Open, FileAccess.Read);
    public static FileStream shortFile = null;
    int limit = 10000;
    public MainWindow()
    {
        byte[] block = new byte[limit];
        while (stream.Read(block, 0, limit) > 0)
        {
            using (FileStream fs = File.Create("tempfile.dat"))
            {
                fs.Write(block, 0, block.Length);
                if (stream.Position > limit)
                {
                    return;
                }
            }
            if (stream.Position > limit)
            {
                return;
            }
        }
        InitializeComponent();
    }

What am I doing wrong here?


Solution

  • This line is wrong:

    using (FileStream fs = File.Create("tempfile.dat"))
    

    It forces creation of a new file for each block read. You need to move above where your first start reading from the stream.

    Additionally, the if(stream.Position > limit) condition will still be true after the first read, since the position should be exactly at the limit value.

    You probably want something more like this:

    public static FileStream stream = new FileStream(@"isam.dat", FileMode.Open, FileAccess.Read);
    public static FileStream shortFile = null;
    const int limit = 10000;
    
    public MainWindow()
    {
        byte[] block = new byte[limit];
        using (FileStream fs = File.Create("tempfile.dat"))
        {
            while (stream.Read(block, 0, limit) > 0 && stream.Position <= limit)
            {
                fs.Write(block, 0, block.Length);
            }
        }
        InitializeComponent();
    }
    

    or even this:

    public static FileStream stream = new FileStream(@"isam.dat", FileMode.Open, FileAccess.Read);
    public static FileStream shortFile = null;
    const int limit = 10000;
    
    public MainWindow()
    {
        byte[] block = new byte[limit];
        using (FileStream fs = File.Create("tempfile.dat"))
        {
            int bytes = stream.Read(block, 0, limit);
            if (bytes > 0)
            {
                fs.Write(block, 0, bytes);
            }
        }
        InitializeComponent();
    }