What’s actually slowing this PC down?

Pick the symptom - the matching free tool is one click away.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Use os.ReadFile when the complete file fits comfortably in memory, os.WriteFile to write a byte slice, and File.Read with a reusable buffer when you want to process data in chunks. With chunked reads, only buf[:n] contains bytes returned by that call. Use io.ReadFull when a record must have an exact size.

How Go slices work as file buffers

A Go slice describes a region of an underlying array. Assigning a slice to another slice does not automatically copy its bytes; both can refer to the same array. The slice passed to a read also specifies the maximum number of bytes the operation can place in the buffer: the Read method has the signature Read(buf []byte) (n int, err error). See the Go Authors’ Effective Go discussion of slices.

For a read, the returned count n is essential. It tells you how many bytes from the beginning of the buffer were filled. The rest of the slice may contain old or otherwise irrelevant data, so process buf[:n], not all of buf.

Read a complete file into a byte slice

For a small or otherwise bounded file whose complete contents can fit in memory, os.ReadFile is the straightforward option:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
data, err := os.ReadFile("input.bin")
if err != nil {
    return err
}
// data contains the complete file.

On success, err is nil; a successful whole-file read does not return io.EOF. If the operation fails, the error is a *PathError. The returned []byte can be inspected or modified. See the Go os.ReadFile documentation.

This convenience comes with a memory trade-off: the complete contents are returned as a slice. For a very large file or an unbounded upload, reading everything at once may use more memory than the application can afford. Use a bounded buffer and process chunks instead.

Write a byte slice to a file

Use os.WriteFile to create or replace a file from a []byte:

Rank #2
Roaring Spring Graph Ruled Spiral Engineering Notebook, Engineering Graph Paper, 5x5 Enclosed Grid, 8.5" x 11", 80 Perforated Sheets, 3 Hole Punched, Green Tinted Sheets, Made in USA
  • ENGINEERING GRAPH PAPER WITH ENCLOSED GRID - Front frame with 1/2" right margin on the front and 5x5 enclosed grid on the backside of each sheet helps keep numbers, diagrams, and layouts neat, aligned, and easy to read for math, drafting, and technical work.
  • GREEN TINTED PAPER REDUCES EYE STRAIN - Soft green engineering paper is easier on the eyes than bright white paper, helping reduce glare under harsh lighting and making extended writing, reading, and detailed work more comfortable.
  • 80 SHEETS OF 20 LB HIGH-QUALITY ENGINEERING PAPER – 8.5" x 11" letter size engineering notebook includes 80 sheets of premium 20 lb paper that helps reduce bleed-through and holds up to extended use for drafting, calculations, and note-taking.
  • COVERED SPIRAL NOTEBOOK KEEPS PAGES SECURE AND PROTECTED – Spiral binding keeps sheets together while perforated edge allows for clean tear-out, durable cover helps keep papers protected from the elements.
  • MADE IN USA QUALITY YOU CAN TRUST – Manufactured by Roaring Spring Paper Products in Pennsylvania for over 100 years, delivering reliable paper quality for consistent performance at school or work.
if err := os.WriteFile("output.bin", data, 0o644); err != nil {
    return err
}

If the file does not exist, os.WriteFile creates it with the requested permission bits, subject to the process umask. If it already exists, the function truncates it before writing and does not change its permissions. The Go documentation also warns that a failure partway through the multiple system calls may leave a partially written file. See os.WriteFile.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

If readers must not see a partially replaced file, a common pattern is to write a temporary file, confirm writing and closing it succeed, and then rename it into place. Whether that replacement is atomic depends on the filesystem and platform; os.WriteFile itself does not promise an all-or-nothing update.

Read sequentially with a reusable slice

File.Read reads up to the buffer’s length and returns the number of bytes read. At end of file it returns 0, io.EOF. A loop should process any bytes returned before handling the error, because a read can return both a positive count and an error.

Rank #3
ROARING SPRING Graph Paper Notebook, Spiral Lab Notebook, Green Tinted Paper, 80 Sheets, 11" x 8.5", Quad Ruled 5x5 Grid, Made in USA, Ideal for Math, Engineering & Science
  • 5x5 GRAPH RULED PAPER FOR PRECISION WORK – Clear 5x5 grid layout keeps numbers, graphs, and diagrams aligned, making this notebook ideal for math, engineering, science labs, and technical drawing.
  • GRAPH PAPER LAB NOTEBOOK FOR STEM USE – Designed for students and professionals, this spiral notebook is perfect for graphing, data tracking, lab notes, and structured problem solving.
  • REEN ENGINEERING PAPER REDUCES EYE STRAIN – Soft green tinted paper helps reduce glare compared to bright white sheets, improving readability during long study sessions and detailed work.
  • 11" x 8.5" SHEETS & 3-HOLE PUNCHED – This durable wirebound lab book contains 80 full sized sheets and 3-hole punched pages fit standard binders for easy organization.
  • MADE IN USA QUALITY YOU CAN TRUST – Proudly manufactured in the USA by Roaring Spring Paper Products, delivering dependable quality for classrooms, offices, and professional environments.
f, err := os.Open("input.bin")
if err != nil {
    return err
}
defer f.Close()

buf := make([]byte, 32*1024)
for {
    n, err := f.Read(buf)
    if n > 0 {
        consume(buf[:n])
    }
    if err == io.EOF {
        break
    }
    if err != nil {
        return err
    }
}

The 32 KiB buffer in this example is a chosen buffer size, not a guarantee about how much any individual read returns. A read may return fewer bytes than requested. The Go Authors document the contract as: “Read reads up to len(b) bytes from the File and stores them in b.” See os.File.Read.

Because the buffer is reused, a consumer that needs to retain a chunk after the next read must copy it; retaining a slice of buf otherwise means retaining a view of the same backing array that subsequent reads overwrite.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Read an exact number of bytes

A single Read is not a request for an exact-length result. When a file format requires a complete fixed-size header or record, use io.ReadFull:

Rank #4
Sale
le vent 2 pack Grid Paper Large Spiral Notebook 8.5 x 11 with 100gsm Thick Paper - Square Graph Quad Ruled Notebooks for Math, Science, Engineering - 200 Pages of Lay Flat, Ink Proof Paper - A4
  • LARGE 8.5 X 11 SPIRAL NOTEBOOK 2-PACK Professional graph paper notebooks with quad ruled pages. Perfect for engineering calculations and mathematics work. Superior alternative to college ruled paper
  • 100GSM THICK PAPER - NO BLEED THROUGH Heavyweight ink-proof paper prevents ghosting. Your writing stays crisp with any pen type. Ideal for archival notes and technical sketches
  • LAY-FLAT SPIRAL BINDING DESIGN Pages stay flat for seamless writing across spreads. Perfect for laboratory research and scientific documentation. Durable spiral withstands daily use
  • GRID PAPER FOR MULTIPLE USES Engineering notebook meets academic requirements. Use for mathematics, science, and architectural drawings. An essentials notebook for students and engineers.
  • PREMIUM SPIRAL BOUND CONSTRUCTION Rugged spiral binding lasts through semesters of use. Crisp grid lines enhance precision work. Designed for demanding educational environments
header := make([]byte, 16)
if _, err := io.ReadFull(f, header); err != nil {
    return err // io.ErrUnexpectedEOF indicates a partial header
}

io.ReadFull keeps reading until the buffer is full or an error prevents it. If the input ends after some but not all bytes have arrived, it returns io.ErrUnexpectedEOF; its count equals the buffer length exactly when the error is nil. See io.ReadFull.

Read at an offset

Use ReadAt when the access pattern calls for a specific offset rather than the current sequential position:

chunk := make([]byte, 4096)
n, err := f.ReadAt(chunk, 1<<20)
if err != nil && err != io.EOF {
    return err
}
process(chunk[:n])

ReadAt begins at the supplied offset and reports an error if it reads fewer bytes than the requested buffer length. If the data format requires the entire chunk, check that the count is the expected length and treat a short read as incomplete, or use io.ReadFull with a suitable section reader. See os.File.ReadAt.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Read all bytes from a reader that is not a file

io.ReadAll reads from an io.Reader until EOF and returns the bytes as a slice. It is useful when the input is a reader rather than a filename, but it still accumulates all data in memory; it is not a memory-bounded streaming alternative for unbounded input. The standard library’s filesystem implementation illustrates a growing slice by repeatedly reading into the unused capacity. See io.ReadAll.

For code that accepts an io.Reader, bytes.NewReader lets a test use an existing slice as a read-only, seekable input without creating a temporary file:

r := bytes.NewReader(input)
copy, err := io.ReadAll(r)
if err != nil {
    return err
}

The resulting *bytes.Reader implements io.Reader, io.ReaderAt, and related interfaces. See bytes.NewReader.

Choose the read or write pattern that fits

Pattern Best fit Key behavior
os.ReadFile Read a bounded file completely Returns the full file in a byte slice; whole contents occupy memory.
File.Read with a reusable slice Process sequential input in chunks Returns a count that may be smaller than the buffer; consume only buf[:n].
io.ReadFull Require an exact-size header or record Fills the requested slice or reports an error; a truncated input yields io.ErrUnexpectedEOF.
File.ReadAt Read from a particular file offset Starts at the specified offset and reports a short-read error when fewer than the requested bytes are read.
io.ReadAll Read an entire stream exposed as an io.Reader Reads until EOF and accumulates all bytes in memory.
os.WriteFile Create or truncate a file from a byte slice Existing contents are truncated; a failure can leave a partial write.

Use the current standard-library names

For new code, use os.ReadFile and os.WriteFile for whole-file operations, and io.ReadAll for reading a complete stream. The older ioutil.ReadFile and ioutil.WriteFile names are deprecated aliases; see the Go documentation for ioutil.ReadFile and ioutil.WriteFile.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.