7

testing.res ファイルのサイズは 240MB です。読みたいです。しかし、次の行でエラーが発生します。

int v = br.ReadInt32();

EndOfStreamException ストリームの終わりを超えて読み取ることができません

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;

namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();

            R();
        }

        private void Form1_Load(object sender, EventArgs e)
        {

        }

        public void R()
        {
            using (var br = new System.IO.BinaryReader(File.Open(@"d:\testing.res", FileMode.Open)))
            {
                // 2.
                // Position and length variables.
                int pos = 0;
                // 2A.
                // Use BaseStream.
                int length = (int)br.BaseStream.Length;
                while (br.BaseStream.Position < length)
                {
                    // 3.
                    // Read integer.
                    int v = br.ReadInt32();
                    textBox1.Text = v.ToString();
                }

            }
        }
    }
}

例外:

System.IO.EndOfStreamException was unhandled
  Message=Unable to read beyond the end of the stream.
  Source=mscorlib
  StackTrace:
       at System.IO.BinaryReader.FillBuffer(Int32 numBytes)
       at System.IO.BinaryReader.ReadInt32()
       at WindowsFormsApplication1.Form1.R() in D:\C-Sharp\BinaryReader\WindowsFormsApplication1\WindowsFormsApplication1\Form1.cs:line 41
       at WindowsFormsApplication1.Form1..ctor() in D:\C-Sharp\BinaryReader\WindowsFormsApplication1\WindowsFormsApplication1\Form1.cs:line 19
       at WindowsFormsApplication1.Program.Main() in D:\C-Sharp\BinaryReader\WindowsFormsApplication1\WindowsFormsApplication1\Program.cs:line 18
       at System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args)
       at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
       at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
       at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
       at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean ignoreSyncCtx)
       at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
       at System.Threading.ThreadHelper.ThreadStart()
  InnerException: 
4

3 に答える 3

4

で自分のカウンターをロールするのではなく、ストリームの最後にいるときを把握するためのより信頼性の高い方法を使用する必要がありますsizeof(int)。あなたの方法は十分に正確ではないかもしれません、そしてあなたがそのために安全でないコードを使用しているという事実もあまり良くありません。

ストリームの最後にいるかどうかを調べる1つの方法は、次のPeekChar方法を使用することです。

while (br.PeekChar() != -1)
{
    // 3.
    // Read integer.
    int v = br.ReadInt32();
    textBox1.Text = v.ToString();
}

より一般的な解決策はint、実際の整数リストの前に、保存するsの数をバイナリファイルに書き込むことです。このようにして、ストリームの長さや位置に依存せずに、いつ停止するかを知ることができます。

于 2012-08-16T02:29:58.333 に答える
3

コードが失敗する理由の 1 つは、ファイルに余分なバイトが含まれている場合です (つまり、7 バイト長のファイル)。コードは最後の 3 バイトでトリップします。

修正するには、事前に整数の数を計算し、次を使用forして読み取ることを検討してください。

var count = br.BaseStream.Length / sizeof(int);
for (var i = 0; i < count; i++)
{
  int v = br.ReadInt32();
  textBox1.Text = v.ToString();
}

このコードは、最後の 1 ~ 3 バイトが存在する場合、単純に無視することに注意してください。

于 2012-08-16T02:40:31.457 に答える