Concepts / Streams and Their States

Streams and Their States

The stream state fail records that an I/O operation has failed, so the program can examine it instead of assuming success.

  • Programming

Why Failed Input and Output Goes Unnoticed

Programs constantly read data from somewhere and write data somewhere else. Reading a value typed by a user, loading a file, and sending text to a screen are all input/output operations, usually called I/O. Any of these operations can fail. The data might not match what the program expected, or the connection to the source or destination might have a problem.

A program that ignores these failures can produce wrong results without warning anyone. Imagine a program that asks for a number, receives text that is not a number, and then carries on as if a valid number had arrived. Every later calculation is quietly wrong. This article explains the mechanism a program can use to notice that an I/O operation has failed and to decide what to do about it.

A Stream and Its Working State

A stream is the object through which a program's input or output flows. Like any object, it has a state at each moment. In normal operation the stream is in a state that says it is working. This is the state in which reading and writing behave as the program expects.

When an I/O operation goes wrong, the stream can be placed into the fail state. The fail state records that something went wrong. It does not repair anything and does not by itself decide what the program should do. It is a record, and the program is responsible for reading that record and acting on it.

The Fail State as a Recorded Flag

Definition

The stream state fail records that an I/O operation has failed, so the program can examine it instead of assuming success.

The important idea is that failure is recorded as information the program can examine. The program does not have to guess from the output whether something went wrong. It can look at the stream's state and respond. Failure becomes a fact the program can check, not a surprise it discovers later when results look strange.

Notice the order of events. The failure is first recorded by the stream, then the program checks for it, and only then does the program choose a response. Each step is separate. That separation is what makes the handling deliberate rather than accidental. The diagram below shows these three steps in order.

ProgramStreamData source ordestination1. perform I/O operation2. transfer data3. record fail state if it failed4. check the stream state
In what order do the I/O call, the stream's state update, and the program's check of that state occur?

Moving From Working to Fail

The diagram below shows the two states the source develops most directly. A stream starts in the working state during normal operation. If an I/O operation goes wrong, the stream moves into the fail state. The source describes this as the stream being placed into the fail state, which is a one-way record of the failure at the moment it happened.

Working statenormal operationFail statefailure recordedProgram checks stateI/O operation goes wrongexamined afterward
What state does the stream move to after an I/O operation goes wrong, and what must the program do next?

The source treats getting back to a usable situation as something the program does deliberately after noticing the failure. Recovery means the program takes an action such as asking for the value again, using a fallback, or reporting the problem clearly. Recovery is not described as something that happens automatically just because time passes.

Tracing Control After a Failure

When handling an I/O error, the question is what happens to the program's flow after the failure. The flowchart below follows the general path. The program performs an operation. The stream is either working or in the fail state. The program then branches based on that state. A recovery branch leads back to a new attempt, while a branch that cannot recover leads to reporting the problem.

Perform I/OoperationStream in fail state?Use the dataAsk again, usefallbackCan the error berecovered?Report the problemcheck the streamno, workingyes, failedyesnonew attempt
After a read or write fails, which statement runs next, and where does execution go when the fail state is checked?

The diagram is a general model rather than a fixed recipe. It shows the central habit: check the stream after the operation, and let that check decide which path the program takes. The branch on recoverability is a judgment the program must make case by case, which is the next topic.

Why Some Errors Are Only Potentially Recoverable

The source describes the stream state fail as the tool for handling potentially recoverable I/O errors. The word potentially matters. It means that some I/O errors are the kind a program can respond to and continue past, while the program still has to decide, case by case, whether recovery makes sense. The source does not claim that every I/O error can be recovered from.

The practical goal is to handle an error that the program has reason to expect and can react to, rather than to pretend the operation succeeded. Some failures, such as a value that does not match what was expected, give the program a clear next step: ask again. Others, such as a broken connection to the source or destination, may leave no sensible way to continue. The table below compares these two situations.

AspectPotentially recoverable errorError that cannot be recovered from
Typical cause from the sourceData does not match what the program expectedA problem with the connection to the source or destination may leave no usable path
Stream stateFail state is recorded and examinedFail state is recorded and examined
Program's decisionChoose a deliberate recovery action such as asking again or using a fallbackReport the problem clearly rather than assume success
What the program must avoidContinuing as if the operation succeededContinuing as if the operation succeeded

Recoverable and unrecoverable I/O errors both require checking the stream. They differ in what the program does next.

Handling a Mistyped Number

Worked example

Responding to a failed read of a user's number

A program needs the user to type a whole number. The user types text that is not a number. How should the program use the fail state to decide what happens next?

  1. 1
    Perform the operation

    The program asks the stream to read a value typed by the user. The read cannot produce a valid number from the text, so the operation fails.

  2. 2
    Let the stream record the failure

    The stream enters the fail state. The failure is recorded rather than being hidden in the output.

  3. 3
    Check the state

    The program examines the stream state instead of assuming the value is valid. This is the step that prevents wrong results from spreading.

  4. 4
    Decide whether recovery makes sense

    A mismatch between typed text and the expected number is the kind of error the program can react to. It is potentially recoverable, so the program chooses a recovery action.

  5. 5
    Take a deliberate action

    The program asks the user to type the number again, starting a new attempt at the operation.

Result

The failure is noticed and handled before any calculation uses bad data. The program resumed by making a deliberate new attempt, not by ignoring the failure.

Change one fact in this scenario. Suppose the connection to the destination the program writes to has a fault. Retrying the same write may not make sense if the fault is not cleared. In that case the program should report the problem clearly rather than repeat the attempt indefinitely. The same check-the-state habit serves both cases; only the branch the program takes differs.

Mistakes When Responding to an I/O Error

  • Common mistake

    Ignoring the fail state entirely

    What it looks like

    The program reads a value and uses it immediately, without checking whether the operation succeeded.

    Why it fails

    The source says a program that ignores these failures can produce wrong results without warning anyone.

    Do this instead

    Check the stream after the operation and branch on the result before using the data.

  • Common mistake

    Retrying without fixing the cause

    What it looks like

    After a connection failure, the program repeats the same write again and again with no change.

    Why it fails

    A retry only makes sense for an error the program has reason to expect and can react to. A fault that persists will keep failing.

    Do this instead

    Decide case by case whether recovery makes sense. If it does not, report the problem clearly.

  • Common mistake

    Treating the stream as healthy because the flag was reset

    What it looks like

    The program clears the failure record and continues, without changing the input or the connection that caused the problem.

    Why it fails

    Recovery is described as a deliberate action taken after the failure, so simply moving past the record does not resolve the underlying cause.

    Do this instead

    Take a specific recovery action such as asking for the value again or using a fallback, and confirm the operation succeeds before using its result.

  • Common mistake

    Assuming every I/O error is recoverable

    Why it fails

    The source explicitly says not every I/O error can be recovered from.

    Do this instead

    Treat recoverability as a per-case judgment and be ready to report the problem.

Predicting the Next Step After a Failed Read

What do you think happens?

A read operation fails and the stream enters the fail state. Before the program uses the value it just read, what should it do first?

  • Use the value immediately, since the read has already finished

  • Check the stream state to see whether the operation failed

  • Clear the failure and use the value once the state is reset

Reveal answer
Answer:

Check the stream state to see whether the operation failed

The source describes checking the stream after an operation and branching on the result before using the data. Assuming success is the mistake the mechanism exists to prevent.

MEDIUM

A program reads a list of numbers from a file. Partway through, the stream enters the fail state. Describe, in order, the steps the program should take before any number is added to a total. Then state whether the error should be retried or reported, and justify your choice using the idea that recoverability is decided case by case.

Hints
  • Start with the order of events: the failure is recorded first, then the program checks for it, then it chooses a response.
  • Ask whether the cause of the failure is something the program can reasonably fix or retry, or whether it points to a problem that persists.
  • Remember that the fail flag only reports the failure; it does not decide the response.

Key Points to Carry Forward

  • A stream is the object through which input or output flows, and it has a state at each moment.
  • The fail state records that an I/O operation has failed, so the program can examine that record instead of assuming success.
  • Control moves through a sequence: the operation runs, the stream records any failure, the program checks the state, and then the program chooses a response.
  • Some I/O errors are potentially recoverable, but the program must decide case by case whether recovery makes sense, and some errors must be reported instead.

Key Takeaways

  • The fail state is a recorded fact that an I/O operation went wrong, which the program can check instead of guessing from the output.
  • The program must check the stream after each operation and branch on that result before using the data.
  • Some I/O errors are potentially recoverable, such as a value that does not match what was expected, but not every error can be recovered from.
  • Recovery is a deliberate action such as asking again or using a fallback, and an unrecoverable failure should be reported clearly.

Related concepts

More concepts starting with S