杰瑞科技汇

java stream byte

Of course! In Java, "stream byte" most commonly refers to handling streams of raw binary data, which is a fundamental concept for I/O (Input/Output) operations. This is different from the java.util.stream API used for processing collections of objects.

java stream byte-图1
(图片来源网络,侵删)

Let's break down the main ways to work with byte streams in Java.

The Classic I/O Streams (java.io)

These are the traditional, foundational classes for handling byte streams. They are used for reading from and writing to files, network connections, and other sources/sinks of raw data.

Key Concepts:

  • Stream: A sequence of data.
  • Input Stream (InputStream): Reads data from a source.
  • Output Stream (OutputStream): Writes data to a destination.
  • Buffering: Wrapping a stream in a buffered stream (BufferedInputStream, BufferedOutputStream) significantly improves performance by reducing the number of direct I/O operations.

Common Byte Stream Classes:

Category Abstract Class Concrete Implementations (Examples) Purpose
Input InputStream FileInputStream, ByteArrayInputStream, BufferedInputStream Reading raw bytes.
Output OutputStream FileOutputStream, ByteArrayOutputStream, BufferedOutputStream Writing raw bytes.

Example 1: Reading and Writing a File with FileInputStream and FileOutputStream

This is the most common use case: copying a binary file (like an image or a PDF).

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
public class ByteStreamFileCopy {
    public static void main(String[] args) {
        // The source file to read from
        String sourcePath = "path/to/your/source-image.jpg";
        // The destination file to write to
        String destinationPath = "path/to/your/destination-image-copy.jpg";
        // Using try-with-resources to ensure streams are closed automatically
        try (FileInputStream fis = new FileInputStream(sourcePath);
             FileOutputStream fos = new FileOutputStream(destinationPath)) {
            // Read one byte at a time
            int byteData;
            while ((byteData = fis.read()) != -1) {
                fos.write(byteData);
            }
            System.out.println("File copied successfully!");
        } catch (IOException e) {
            System.err.println("An error occurred during file copy: " + e.getMessage());
            e.printStackTrace();
        }
    }
}

Explanation:

java stream byte-图2
(图片来源网络,侵删)
  1. try (FileInputStream fis = ...): We use a try-with-resources block. This is the modern, recommended way as it automatically closes the FileInputStream when the block is exited, even if an exception occurs.
  2. fis.read(): Reads one byte of data from the input stream and returns it as an int (in the range 0 to 255). It returns -1 when the end of the stream is reached.
  3. fos.write(byteData): Writes the specified byte to the output stream.

Example 2: Using BufferedInputStream for Better Performance

Reading/writing one byte at a time is inefficient. Buffering reads a large chunk of data into memory at once, reducing the number of system calls.

import java.io.*;
public class BufferedByteStreamCopy {
    public static void main(String[] args) {
        String sourcePath = "path/to/your/large-file.zip";
        String destinationPath = "path/to/your/large-file-copy.zip";
        // Using try-with-resources with multiple resources
        try (BufferedInputStream bis = new BufferedInputStream(new FileInputStream(sourcePath));
             BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(destinationPath))) {
            // Create a buffer to hold chunks of data
            byte[] buffer = new byte[8192]; // 8KB buffer
            int bytesRead;
            // Read from the input stream into the buffer
            while ((bytesRead = bis.read(buffer)) != -1) {
                // Write the bytes from the buffer to the output stream
                bos.write(buffer, 0, bytesRead);
            }
            System.out.println("Large file copied successfully with buffering!");
        } catch (IOException e) {
            System.err.println("An error occurred: " + e.getMessage());
            e.printStackTrace();
        }
    }
}

Explanation:

  1. new BufferedInputStream(new FileInputStream(...)): We wrap the FileInputStream in a BufferedInputStream. The same is done for the output stream.
  2. byte[] buffer = new byte[8192]: We create a byte array to act as our buffer. A size of 8KB is a common and good starting point.
  3. bis.read(buffer): This method attempts to read buffer.length bytes from the stream into the buffer array. It returns the actual number of bytes read, or -1 if the end of the stream is reached.
  4. bos.write(buffer, 0, bytesRead): We write the portion of the buffer that was actually filled. bytesRead tells us how many bytes to write.

The New I/O (NIO) API (java.nio)

Since Java 1.4, java.nio (New I/O) has provided an alternative, often more powerful, way to handle I/O. The java.nio.file package is particularly important for file operations.

Key Concepts:

  • Path: Represents a path to a file or directory in a platform-independent way. It's more modern and flexible than File.
  • Files: A utility class with static methods for common file operations (reading, writing, copying, deleting, etc.).
  • InputStream/OutputStream: You can still get traditional streams from Files, but NIO also offers Channels and Buffers, which are more efficient for certain types of operations.

Example 3: Reading/Writing Files with NIO (java.nio.file)

This is the modern, preferred way to handle file I/O in Java. It's more concise and often more performant.

java stream byte-图3
(图片来源网络,侵删)
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
public class NioFileCopy {
    public static void main(String[] args) {
        Path sourcePath = Paths.get("path/to/your/source-image.jpg");
        Path destinationPath = Paths.get("path/to/your/destination-image-nio-copy.jpg");
        try {
            // Files.copy() is a simple, high-level method for copying files.
            // It automatically handles opening, reading, writing, and closing the streams.
            Files.copy(sourcePath, destinationPath);
            System.out.println("File copied successfully using NIO!");
        } catch (IOException e) {
            System.err.println("An error occurred during NIO file copy: " + e.getMessage());
            e.printStackTrace();
        }
    }
}

Explanation:

  • Paths.get(...): A convenient factory method to create a Path object from a string.
  • Files.copy(Path source, Path target): This is the magic. It's a single method call that performs the entire copy operation efficiently. It's much simpler than the manual stream operations.

Summary: Which One to Use?

Feature java.io Streams java.nio.file
Simplicity Good for simple, direct operations. Excellent. High-level methods like Files.copy() are very easy to use.
Performance Buffered streams are good for general use. Generally better, especially for large files and concurrent operations, due to its channel-based architecture.
Flexibility Good for basic network and memory streams. Excellent. Offers advanced features like asynchronous I/O, file system watching, and symbolic links.
Modern Standard The classic, foundational API. The current standard for all new file I/O code in Java.

Recommendation:

  • For simple file operations (copy, read, write), always prefer java.nio.file.Files. It's simpler, safer, and often faster.
  • For networking or in-memory byte streams, the classic java.io streams (ByteArrayInputStream, SocketInputStream, etc.) are still perfectly valid and widely used.
  • If you need maximum performance for a specific high-throughput task (e.g., a file server), you might explore the more advanced NIO concepts like Channels and Buffers, but for most applications, Files.copy() is sufficient.
分享:
扫描分享到社交APP
上一篇
下一篇