Ошибка времени выполнения чтение после конца потока невозможно

В паскале (да и не только) данные в типизированном файле (в вашем случае — file of integer) хранятся в шестнадцатиричном виде. В паскале integer занимал 2 байта, именно поэтому выскочила ошибка «Чтение после конца потока невозможно», ведь «8» — это один байт.

Если вы хотите читать целые числа из текстового файла, используйте TextFile (или Text в олдскульном варианте). Для freepascal, pascalABC.NET и Delphi это будет так:

var 
  a : integer; 
  f : TextFile;
begin
  AssignFile(f, 'f.txt');
  Reset(f);
  //Seek(f, 0);
  Read(f, a); // a = 8, хотя лучше читать сразу всю строку, используя несколько переменных

  <...>
 CloseFile(f);

end.

А в варианте для Turbo Pascal и самых первых версий Delphi — так:

var 
  a : integer; 
  f : Text;
begin
  Assign(f, 'f.txt');
  Reset(f);
  //Seek(f, 0);
  Read(f, a); { a = 8 поскольку в Turbo Pascal // не было комментарием :) }

  <...>
  Close(f);
end.

type
  base = record
    n1, n2: string[15];
    tel: string[4];
    d, m: byte;
    y: integer;
  end;
 
var
  r: base;
  a: array [1..10] of base; f: file of base; 
  i: integer;
 
begin
  assign(f, 'in.dat');
  rewrite(f); // создаем новый файл
  for i := 1 to 10 do // заполняем его 10 значениями "от балды", чтобы был понятен принцип
  begin
    r.d := i; r.m := i; r.y := i; // тут тестовые значения
    r.n1 := 'start';
    r.n2 := 'finish';
    r.tel := '3234';
    write(f, r); // пишем структуру в файл
  end;
  close(f);
  
  reset(f); // переоткрываем файл уже для чтения
  i := 0;
  while not eof(f) do // и читаем содержимое в массив a
  begin
    inc(i);
    read(f, a[i]); // в этой строке не показывает никакой ошибки
  end;
  close(f);
end.

G1gg13s

0 / 0 / 0

Регистрация: 30.01.2016

Сообщений: 21

1

Ошибка времени выполнения: Чтение после конца потока невозможно

28.02.2016, 21:32. Показов 10067. Ответов 5

Метки нет (Все метки)


Ошибка в строке 9.

Pascal
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
var
  A: file of integer;
  B, I, J: integer;
begin
  assign(A, 'D:KEK.txt');
  reset(A);
  while not eof(A) do
    begin
      read(A, B);
      write(B);
    end;
  seek(A, 3);
  read(A, I);
  seek(A, 5);
  read(A, J);
  seek(A, 3);
  write(A, J);
  seek(A, 5);
  write(A, I);
  close(A);
end.

__________________
Помощь в написании контрольных, курсовых и дипломных работ, диссертаций здесь

0

318 / 208 / 162

Регистрация: 08.12.2015

Сообщений: 863

28.02.2016, 23:29

2

Вы пытаетесь из текстового файла прочитать как из файла с переменными. Это несколько неверно. seek тоже даст далее ошибку. Так-же , в 17 и 19 строках тоже будет ошибка, пытаетесь записать в тот же файл, не открыв его на запись. В общем, задание неизвестно ,как исправить — непонятно.

0

0 / 0 / 0

Регистрация: 30.01.2016

Сообщений: 21

29.02.2016, 20:37

 [ТС]

3

Есть текстовый файл с текстом ‘123456’ и нужно заменить 3 и и 5 элементы.

0

Почетный модератор

64270 / 47569 / 32739

Регистрация: 18.05.2008

Сообщений: 115,182

29.02.2016, 20:49

4

Лучший ответ Сообщение было отмечено G1gg13s как решение

Решение

А как создан файл А, он точно типизированный?

1

0 / 0 / 0

Регистрация: 30.01.2016

Сообщений: 21

29.02.2016, 20:50

 [ТС]

5

Я — е*лан, сори. Я понял, люблю тебя :*, пусик

0

Puporev

Почетный модератор

64270 / 47569 / 32739

Регистрация: 18.05.2008

Сообщений: 115,182

29.02.2016, 20:53

6

Лучший ответ Сообщение было отмечено G1gg13s как решение

Решение

А зачем у него расширение да еще и txt? Как Вы его создавали?
При чтении типизированного файла целых чисел не может быть ошибки в этом

Pascal
1
2
3
4
5
6
reset(A);
  while not eof(A) do
    begin
      read(A, B);
      write(B);
    end;

1

IT_Exp

Эксперт

87844 / 49110 / 22898

Регистрация: 17.06.2006

Сообщений: 92,604

29.02.2016, 20:53

Помогаю со студенческими работами здесь

Чтение после конца потока невозможно
Выдаёт такую ошибку. Помогите :-|

С чем связана ошибка:»Чтение после конца потока невозможно»
С чем связана ошибка:&quot;Чтение после конца потока невозможно&quot;.

Подпрограмма выдает ошибку времени выполнения: Чтение после конца потока невозможно
Дан файл, содержащий сведения об игрушках: указывается название игрушки, ее стоимость в рублях и…

Чтение чисел из файла. Чтение после конца потока невозможно
Товарищи, помогите.
В Pascal’e я не силен, так что не бейте меня ногами, но есть задача: написать…

Чтение после конца потока невозможно
Сам код:

Uses Crt;
var i,k:integer;
f: file;
a,b:real;
Begin
Assign(f,…

Чтение после конца потока невозможно
var f:file of integer;
i,a,max,l:integer;
begin
assign(f,’f.txt’);
reset(f);
i:=0;
while…

Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:

6

На чтение 2 мин Просмотров 361 Опубликовано 12.01.2021

Всем доброго времени суток, столкнулся с проблемой

Чтения после конца потока невозможно

Дело в том что я читаю бинарный файл :

И так получилось что numb2 имеет запись в файле поэтому reader2.PeekChar() > -1 больше 1, но вот ndef2 уже нету в файле, и я получаю ошибку чтения после конца потока, может есть более правильный метод инициализации данных в файле, и если дальше записи нет, то просто передать 0 и перейти дальше, либо пропускать и идти дальше, просто не хотелось бы делать что-то вроде:

Или все же придется ставить еще одну проверку, как я написал выше ?
Помогите пожалуйста разобраться.

Приветствую, мне требуется ваша помощь, уже не знаю, что делать, весь интернет перерыл, и всем помогает Position = 0,а мне нет.

Подскажите пожалуйста! Всем спасибо!

  • Вопрос задан более года назад
  • 647 просмотров

Для ReadString() возврат пустой строки, вполне вменяемое поведение.

Например, если бы считывался этот комментарий, то Ваш код не дошёл бы до этой строчки.

Я сейчас сижу проверяю, и наткнулся на одну вещь, вот на этой строке:

Если сервер решил не отправлять данные, то программа виснет на указанной строке, до тех пор пока не поучит сообщение с сервера, даже сама Unity виснет и я не могу остановить выполнение программы, как можно это исправить? Я пытаюсь сделать это с использованием корутин, но я с ними почти не знаком и у меня ничего пока что не выходит. Если знаете, подскажите пожалуйста, как избавится от зависания?

program fgd;
type f= file of real;
var f1:f;
i,j: byte;
a: array[1..4,1..5] of real;
k: real;
begin
assign (f1,’massiv.txt’);
reset (f1);
for i:=1 to 4 do
for j:=1 to 5 do
begin
read (f1, k);
a[i,j]:=k;
end;
close (f1);
for i:=1 to 4 do
begin
for j:=1 to 5 do write (a[i,j],’ ‘);
writeln;
end;
end.

Pascal.
Program2.pas(18) : Ошибка времени выполнения: Чтение после конца потока невозможно.
В чём ошибка

Здесь легко и интересно общаться. Присоединяйся!

Вы файл заполняли в ручную? Возможно для корректного чтения следует заполнить файл программно.

  • Распечатать

Оцените статью:

  1. 5
  2. 4
  3. 3
  4. 2
  5. 1

(0 голосов, среднее: 0 из 5)

Поделитесь с друзьями!

The testing.res file is 240MB size.
I want to read it. But im getting the error on this line:

int v = br.ReadInt32();

EndOfStreamException
Unable to read beyond the end of the stream

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();
                }

            }
        }
    }
}

The exception:

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-SharpBinaryReaderWindowsFormsApplication1WindowsFormsApplication1Form1.cs:line 41
       at WindowsFormsApplication1.Form1..ctor() in D:C-SharpBinaryReaderWindowsFormsApplication1WindowsFormsApplication1Form1.cs:line 19
       at WindowsFormsApplication1.Program.Main() in D:C-SharpBinaryReaderWindowsFormsApplication1WindowsFormsApplication1Program.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: 

The testing.res file is 240MB size.
I want to read it. But im getting the error on this line:

int v = br.ReadInt32();

EndOfStreamException
Unable to read beyond the end of the stream

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();
                }

            }
        }
    }
}

The exception:

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-SharpBinaryReaderWindowsFormsApplication1WindowsFormsApplication1Form1.cs:line 41
       at WindowsFormsApplication1.Form1..ctor() in D:C-SharpBinaryReaderWindowsFormsApplication1WindowsFormsApplication1Form1.cs:line 19
       at WindowsFormsApplication1.Program.Main() in D:C-SharpBinaryReaderWindowsFormsApplication1WindowsFormsApplication1Program.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: 

Добрый вечер. Постараюсь подробно изложить проблему, которую не могу решить уже давно. Есть клиент-серверное приложение. Между ними происходит обмен командами и различными файлами. Я реализовал это следующим
образом:

 'Получения блока байт информации
    Public Sub DoRead(ByVal obj As Object)
        Try
            Dim Stream As NetworkStream = myClient.GetStream
            Dim Reader As New BinaryReader(Stream)
            Do
                Dim typeMsg = Reader.ReadByte()
                'Далее смотрим заголовок
                Select Case typeMsg
                    Case 0 'Сообщение
                        Dim tmpName = Reader.ReadString
                        Dim tmpMessage = Reader.ReadString
                        RaiseEvent MessageReceived(Me, tmpName, tmpMessage))
                    Case 11 'Пришла часть файла
                        'Получаем индекс-код загружаемого файла
                        typeMsg = Reader.ReadByte
                        'Считываем размер блока данных
                        Dim SizePart = Reader.ReadInt32
                        'Теперь сам блок
                        Dim byteArray = Reader.ReadBytes(SizePart)
                        'Вызываем событие принятия
                        RaiseEvent FileReceived(Me, typeMsg, byteArray)
                    Case 13 'Ошибка при отправке файла
                        'Получаем индекс-код загружаемого файла
                        typeMsg = Reader.ReadByte
                        'Текст ошибки
                        Dim tmpMessage = Reader.ReadString
                        'Теперь выводим ошибку
                        If BufferTCPFiles.ContainsKey(typeMsg) Then
                            BufferTCPFiles(typeMsg).onError(tmpMessage)
                        End If
                End Select
            Loop While Stream.CanRead
        Catch ex As Exception
            ConnectStatus = False
        End Try
    End Sub

В отдельном потоке идет считывание 1 байта заголовка. По нему определяем что пришло и уже считываем или строку, в случае передачи команды, или размер массива и сам массив байт (в случае отправки файла).
После этого идет вызов событий принятия команды или файла, которые обрабатываются другими классами.

Первый вопрос. Когда сервер передает массив байт размером, например, 16000 байт, а клиент принимает его способом, указанным в коде (Reader.ReadBytes(SizePart)), может клиент получить не 16000 байт, а, например,
15000, затем вызвать событие обработки FileReceived и потом начать считывать байт-заголовок. В итоге считывает байт из оставшихся 1000 байт и начинает обрабатывать неправильно? Или он будет пытаться прочитать все байты до конца?

Продолжу дальше. Проблема в обмене файлами. Событие FileReceived обрабатывается в классе приема файла (LoadFileTCP) следующим образом:

       BufferTCPFiles = New Concurrent.ConcurrentDictionary(Of Byte, LoadFileTCP)
       'Событие обработки команд с сервера (принятие массива данных)
       AddHandler UserClient.FileReceived, AddressOf onFileReceived

Изначально создается BufferTCPFiles — так как одновременно могут передаваться несколько файлов, он содержит в себе ключ-значения состоящие из индекс-кода загружаемого файла и классы LoadFileTCP, которые обрабатывают массивы
байт. Когда происходит событие FileReceived — идет поиск нужного класса по индекс-коду и у него вызывается процедура обработки:

Private ThreadLock As New Object
        Private Sub onFileReceived(ByVal sender As ClientVisio, ByVal NumberOf As Byte, ByVal PartArray As Byte())
            'Записываем данные в файл только одним потоком
            SyncLock ThreadLock
                If BufferTCPFiles.ContainsKey(NumberOf) Then
                    BufferTCPFiles(NumberOf).WriteDataToFile(PartArray)
                End If
            End SyncLock
        End Sub

Теперь о самой процедуре обработки массива байт — WriteDataToFile:

        Public Sub WriteDataToFile(ByVal byteArray As Byte())
            Try
		'Количество принятых блоков до отправки подтверждения о приеме
                BlockNow = CByte(BlockNow - 1)

		'fs - это ранее созданный FileStream(pathToFile & "tmp", FileMode.OpenOrCreate, FileAccess.Write)
                fs.Write(byteArray, 0, byteArray.Length)
		'Общее количество байт
                LoadDataCount += byteArray.Length

                'Пора отправлять подтверждение о принятии на сервер?
                If BlockNow <= 0 Then
                    'Отправляем ответ с индекс-кодом файла
                    UserClient.SendFOk(myData.IndexLoad)
		    'Сбрасываем счетчик
                    BlockNow = 10
                End If

		'Если все байты получены (размер файла FullSize сервер присылает перед отправкой файла)
                If LoadDataCount = FullSize Then
                    StatusLoad = False
                    fs.Close()

                    'Это последний блок! 
                    'Теперь переименовываем файл, удаляя предыдущий, если есть
                    If FileIO.FileSystem.FileExists(pathToFile) Then 'Файл существует?
                        FileIO.FileSystem.DeleteFile(pathToFile) 'Удаляем...
                    End If
		    'Данные имени и расширения сервер так-же присылает перед отправкой файла
                    FileIO.FileSystem.RenameFile(pathToFile & "tmp", myData("Имя") & myData("Расширение"))
                    'Сообщаем о загрузке
                    BufferTCPFiles.RaiseNewEvent(myData, TypeEvent.LoadComplete, pathToFile)

		'Если вдруг принято больше, чем нужно
                ElseIf LoadDataCount > FullSize Then
                    StatusLoad = False
                    fs.Close()

                    'Сообщаем об ошибке
                    BufferTCPFiles.RaiseNewEvent(myData, TypeEvent.ErrorLoad, "Переполнение! " & vbCrLf & LoadDataCount & "/" & FullSize)
                End If
            Catch ex As Exception
                Console.WriteConsole("Ошибка: " & ex.Message)
            End Try
        End Sub

Я постарался прокомментировать все действия в процедуре. Это все дело работает, но иногда, на некоторых компьютерах, выдает ошибку. Причем ошибка идет в процедуре приема данных DoRead! Такое ощущение, что данные были не
до конца прочитаны, потом прочитался байт заголовок команды, а оказалось этот байт принадлежал массиву байт файла. И все пошло наперекосяк.

Второй вопрос. Нужно ли при вызове процедуры записи данных файла — WriteDataToFile — использовать SyncLock? Я его поставил, думая, что если много будет потоков вызывать запись на диск по FileStream, то будет некорректно записаны данные.

Ну и третий вопрос — годится ли сама реализация обработки данных с сервера? Выдает ошибку она или процедура записи на диск? Самое интересное, если компьютер более менее производительный (офисный), тогда ошибок вообще нет. Ошибка приема
файла ТОЛЬКО у компьютеров с медленным жестким диском (с большим временем доступа) или просто у старых компьютеров, у которых ждешь по 2 минуты открытие браузера :) Именно из за этого я решил
использовать SyncLock при вызове процедуры записи данных на диск. Решил, что он не успевает записать данные, а уже пришли новые и они вместе со старыми конфликтуют :)

Буду рад любой помощи )

Приветствую, мне требуется ваша помощь, уже не знаю, что делать, весь интернет перерыл, и всем помогает Position = 0,а мне нет.

private static byte[] buffer = new byte[1024];
    private static MemoryStream stream = new MemoryStream(buffer);
    private static BinaryWriter writer = new BinaryWriter(stream);
    private static BinaryReader reader = new BinaryReader(stream);

    private List<string> listCode = new List<string>();

void ReceiveData()
    {
        int bytes = 0;

        EndPoint remoteIp = new IPEndPoint(IPAddress.Any, 0);
        listCode.Clear();

        do
        {
            bytes = socket.ReceiveFrom(buffer, ref remoteIp);
        }
        while (socket.Available > 0);


        bool getData = true;

        stream.Position = 0;

        try
        {
            while (getData)
            {
                string data = reader.ReadString(); // ВОТ ТУТ КОД ВЫДАЕТ ИСКЛЮЧЕНИЕ ПОСЛЕ ТОГО КАК ДАННЫЕ С СЕРВЕРА ПРИХОДЯТ 2-ОЙ РАЗ
                if (data != "")
                    listCode.Add(data);
                else
                    getData = false;
            }
        }
        catch(Exception ex)
        {
            Debug.Log(ex.Message);
        }

        stream.SetLength(0);
        stream.Position = 0;

        IPEndPoint remoteFullIP = remoteIp as IPEndPoint;
    }

Подскажите пожалуйста! Всем спасибо!

Добрый вечер. Постараюсь подробно изложить проблему, которую не могу решить уже давно. Есть клиент-серверное приложение. Между ними происходит обмен командами и различными файлами. Я реализовал это следующим
образом:

 'Получения блока байт информации
    Public Sub DoRead(ByVal obj As Object)
        Try
            Dim Stream As NetworkStream = myClient.GetStream
            Dim Reader As New BinaryReader(Stream)
            Do
                Dim typeMsg = Reader.ReadByte()
                'Далее смотрим заголовок
                Select Case typeMsg
                    Case 0 'Сообщение
                        Dim tmpName = Reader.ReadString
                        Dim tmpMessage = Reader.ReadString
                        RaiseEvent MessageReceived(Me, tmpName, tmpMessage))
                    Case 11 'Пришла часть файла
                        'Получаем индекс-код загружаемого файла
                        typeMsg = Reader.ReadByte
                        'Считываем размер блока данных
                        Dim SizePart = Reader.ReadInt32
                        'Теперь сам блок
                        Dim byteArray = Reader.ReadBytes(SizePart)
                        'Вызываем событие принятия
                        RaiseEvent FileReceived(Me, typeMsg, byteArray)
                    Case 13 'Ошибка при отправке файла
                        'Получаем индекс-код загружаемого файла
                        typeMsg = Reader.ReadByte
                        'Текст ошибки
                        Dim tmpMessage = Reader.ReadString
                        'Теперь выводим ошибку
                        If BufferTCPFiles.ContainsKey(typeMsg) Then
                            BufferTCPFiles(typeMsg).onError(tmpMessage)
                        End If
                End Select
            Loop While Stream.CanRead
        Catch ex As Exception
            ConnectStatus = False
        End Try
    End Sub

В отдельном потоке идет считывание 1 байта заголовка. По нему определяем что пришло и уже считываем или строку, в случае передачи команды, или размер массива и сам массив байт (в случае отправки файла).
После этого идет вызов событий принятия команды или файла, которые обрабатываются другими классами.

Первый вопрос. Когда сервер передает массив байт размером, например, 16000 байт, а клиент принимает его способом, указанным в коде (Reader.ReadBytes(SizePart)), может клиент получить не 16000 байт, а, например,
15000, затем вызвать событие обработки FileReceived и потом начать считывать байт-заголовок. В итоге считывает байт из оставшихся 1000 байт и начинает обрабатывать неправильно? Или он будет пытаться прочитать все байты до конца?

Продолжу дальше. Проблема в обмене файлами. Событие FileReceived обрабатывается в классе приема файла (LoadFileTCP) следующим образом:

       BufferTCPFiles = New Concurrent.ConcurrentDictionary(Of Byte, LoadFileTCP)
       'Событие обработки команд с сервера (принятие массива данных)
       AddHandler UserClient.FileReceived, AddressOf onFileReceived

Изначально создается BufferTCPFiles — так как одновременно могут передаваться несколько файлов, он содержит в себе ключ-значения состоящие из индекс-кода загружаемого файла и классы LoadFileTCP, которые обрабатывают массивы
байт. Когда происходит событие FileReceived — идет поиск нужного класса по индекс-коду и у него вызывается процедура обработки:

Private ThreadLock As New Object
        Private Sub onFileReceived(ByVal sender As ClientVisio, ByVal NumberOf As Byte, ByVal PartArray As Byte())
            'Записываем данные в файл только одним потоком
            SyncLock ThreadLock
                If BufferTCPFiles.ContainsKey(NumberOf) Then
                    BufferTCPFiles(NumberOf).WriteDataToFile(PartArray)
                End If
            End SyncLock
        End Sub

Теперь о самой процедуре обработки массива байт — WriteDataToFile:

        Public Sub WriteDataToFile(ByVal byteArray As Byte())
            Try
		'Количество принятых блоков до отправки подтверждения о приеме
                BlockNow = CByte(BlockNow - 1)

		'fs - это ранее созданный FileStream(pathToFile & "tmp", FileMode.OpenOrCreate, FileAccess.Write)
                fs.Write(byteArray, 0, byteArray.Length)
		'Общее количество байт
                LoadDataCount += byteArray.Length

                'Пора отправлять подтверждение о принятии на сервер?
                If BlockNow <= 0 Then
                    'Отправляем ответ с индекс-кодом файла
                    UserClient.SendFOk(myData.IndexLoad)
		    'Сбрасываем счетчик
                    BlockNow = 10
                End If

		'Если все байты получены (размер файла FullSize сервер присылает перед отправкой файла)
                If LoadDataCount = FullSize Then
                    StatusLoad = False
                    fs.Close()

                    'Это последний блок! 
                    'Теперь переименовываем файл, удаляя предыдущий, если есть
                    If FileIO.FileSystem.FileExists(pathToFile) Then 'Файл существует?
                        FileIO.FileSystem.DeleteFile(pathToFile) 'Удаляем...
                    End If
		    'Данные имени и расширения сервер так-же присылает перед отправкой файла
                    FileIO.FileSystem.RenameFile(pathToFile & "tmp", myData("Имя") & myData("Расширение"))
                    'Сообщаем о загрузке
                    BufferTCPFiles.RaiseNewEvent(myData, TypeEvent.LoadComplete, pathToFile)

		'Если вдруг принято больше, чем нужно
                ElseIf LoadDataCount > FullSize Then
                    StatusLoad = False
                    fs.Close()

                    'Сообщаем об ошибке
                    BufferTCPFiles.RaiseNewEvent(myData, TypeEvent.ErrorLoad, "Переполнение! " & vbCrLf & LoadDataCount & "/" & FullSize)
                End If
            Catch ex As Exception
                Console.WriteConsole("Ошибка: " & ex.Message)
            End Try
        End Sub

Я постарался прокомментировать все действия в процедуре. Это все дело работает, но иногда, на некоторых компьютерах, выдает ошибку. Причем ошибка идет в процедуре приема данных DoRead! Такое ощущение, что данные были не
до конца прочитаны, потом прочитался байт заголовок команды, а оказалось этот байт принадлежал массиву байт файла. И все пошло наперекосяк.

Второй вопрос. Нужно ли при вызове процедуры записи данных файла — WriteDataToFile — использовать SyncLock? Я его поставил, думая, что если много будет потоков вызывать запись на диск по FileStream, то будет некорректно записаны данные.

Ну и третий вопрос — годится ли сама реализация обработки данных с сервера? Выдает ошибку она или процедура записи на диск? Самое интересное, если компьютер более менее производительный (офисный), тогда ошибок вообще нет. Ошибка приема
файла ТОЛЬКО у компьютеров с медленным жестким диском (с большим временем доступа) или просто у старых компьютеров, у которых ждешь по 2 минуты открытие браузера :) Именно из за этого я решил
использовать SyncLock при вызове процедуры записи данных на диск. Решил, что он не успевает записать данные, а уже пришли новые и они вместе со старыми конфликтуют :)

Буду рад любой помощи )

Понравилась статья? Поделить с друзьями:

Не пропустите эти материалы по теме:

  • Яндекс еда ошибка привязки карты
  • Ошибка времени выполнения файл не открыт на чтение
  • Ошибка времени выполнения файл не найден pascal
  • Ошибка времени выполнения программы
  • Ошибка времени выполнения попытка деления на нуль

  • 0 0 голоса
    Рейтинг статьи
    Подписаться
    Уведомить о
    guest

    0 комментариев
    Старые
    Новые Популярные
    Межтекстовые Отзывы
    Посмотреть все комментарии