杰瑞科技汇

Java读取字节流,如何正确操作?

Of course! Reading bytes in Java is a fundamental I/O operation. The approach you use depends on the source of the bytes (a file, a network connection, a byte array, etc.) and whether you need to read them one by one or in bulk.

Here’s a comprehensive guide covering the most common scenarios.

Reading from a File (FileInputStream)

This is the most common scenario for reading binary data from a file.

Basic Example: Reading Byte-by-Byte

This approach is simple but inefficient for large files because it involves a system call for every single byte.

import java.io.FileInputStream;
import java.io.IOException;
public class ReadBytesFromFile {
    public static void main(String[] args) {
        String filePath = "my_data.bin";
        // The try-with-resources statement ensures the file is closed automatically.
        try (FileInputStream fis = new FileInputStream(filePath)) {
            int byteData;
            System.out.println("Reading file byte by byte:");
            // fis.read() returns an integer representing the byte read (0-255)
            // or -1 if the end of the stream (EOF) has been reached.
            while ((byteData = fis.read()) != -1) {
                // Cast the int back to a byte to get the value
                byte b = (byte) byteData;
                System.out.print(b + " ");
            }
            System.out.println("\nFile reading complete.");
        } catch (IOException e) {
            System.err.println("An error occurred while reading the file: " + e.getMessage());
        }
    }
}

Better Example: Reading into a Buffer

This is the standard, high-performance way to read files. You read a chunk of bytes (a buffer) at a time, which is much faster.

import java.io.FileInputStream;
import java.io.IOException;
public class ReadBytesFromFileBuffered {
    public static void main(String[] args) {
        String filePath = "my_data.bin";
        byte[] buffer = new byte[1024]; // A 1KB buffer
        try (FileInputStream fis = new FileInputStream(filePath)) {
            int bytesRead;
            System.out.println("Reading file into a buffer:");
            // fis.read(buffer) reads up to buffer.length bytes from the stream
            // into the buffer array. It returns the number of bytes actually read.
            // It returns -1 when the end of the stream is reached.
            while ((bytesRead = fis.read(buffer)) != -1) {
                // Process the chunk of bytes that was read
                // For example, let's just print the number of bytes read in this chunk
                System.out.println("Read " + bytesRead + " bytes this time.");
                // If you needed to work with the data, you would use the 'buffer'
                // from index 0 to bytesRead.
                // String chunk = new String(buffer, 0, bytesRead);
                // System.out.println("Chunk: " + chunk);
            }
            System.out.println("\nFile reading complete.");
        } catch (IOException e) {
            System.err.println("An error occurred: " + e.getMessage());
        }
    }
}

Reading from a Network Socket (SocketInputStream)

When you get an input stream from a socket, the principle is the same, but the source is a network connection.

import java.io.InputStream;
import java.net.Socket;
import java.io.IOException;
public class ReadBytesFromSocket {
    public static void main(String[] args) {
        String host = "example.com";
        int port = 80; // HTTP port
        try (Socket socket = new Socket(host, port);
             InputStream is = socket.getInputStream()) {
            // Send a simple HTTP GET request
            String request = "GET / HTTP/1.1\r\nHost: " + host + "\r\n\r\n";
            socket.getOutputStream().write(request.getBytes());
            byte[] buffer = new byte[4096];
            int bytesRead;
            System.out.println("Reading response from server:");
            while ((bytesRead = is.read(buffer)) != -1) {
                // Convert the byte chunk to a string and print it
                // This assumes the response is text (like HTML)
                String responseChunk = new String(buffer, 0, bytesRead, "UTF-8");
                System.out.print(responseChunk);
            }
        } catch (IOException e) {
            System.err.println("An error occurred with the socket: " + e.getMessage());
        }
    }
}

Reading from a Byte Array (ByteArrayInputStream)

This is useful when your data is already in memory as a byte array and you want to process it using standard stream-based logic.

import java.io.ByteArrayInputStream;
import java.io.IOException;
public class ReadBytesFromArray {
    public static void main(String[] args) {
        String data = "This is a test string.";
        byte[] byteArray = data.getBytes(); // Convert string to byte array
        // Create a ByteArrayInputStream from the byte array
        try (ByteArrayInputStream bis = new ByteArrayInputStream(byteArray)) {
            byte[] buffer = new byte[10]; // Small buffer to demonstrate reading in chunks
            int bytesRead;
            System.out.println("Reading from byte array:");
            while ((bytesRead = bis.read(buffer)) != -1) {
                // Process the chunk
                String chunk = new String(buffer, 0, bytesRead);
                System.out.print("[" + bytesRead + " bytes] " + chunk);
            }
            System.out.println("\nReading complete.");
        } catch (IOException e) {
            // IOException is possible, though less common with ByteArrayInputStream
            e.printStackTrace();
        }
    }
}

Reading from a String (StringReader)

If you need to read a string character by character (not byte by byte), StringReader is the correct tool. This is for text, not binary data.

import java.io.StringReader;
import java.io.IOException;
public class ReadFromString {
    public static void main(String[] args) {
        String text = "Hello, World!";
        try (StringReader reader = new StringReader(text)) {
            int charData;
            System.out.println("Reading string character by character:");
            // reader.read() reads a single character as an integer
            while ((charData = reader.read()) != -1) {
                // Cast the int to a char
                char c = (char) charData;
                System.out.print(c + " ");
            }
            System.out.println("\nReading complete.");
        } catch (IOException e) {
            // Rare for StringReader, but included for completeness
            e.printStackTrace();
        }
    }
}

Key Concepts and Best Practices

  1. InputStream.read() Returns an int: The read() method of an InputStream returns an int, not a byte. This is because it needs to use the special value -1 to signal the end of the stream (EOF). A byte cannot hold the value -1.

  2. try-with-resources: Always wrap your streams in a try-with-resources block (try (Stream s = ...)). This guarantees that the stream is automatically closed for you, preventing resource leaks. It's the modern, safe way to handle I/O.

  3. Buffering is Key: For any performance-critical operation (like reading files or network data), always use a buffer. Reading one byte at a time is orders of magnitude slower than reading a block of bytes (e.g., 4KB or 8KB at a time).

  4. Choose the Right Stream:

    • Binary Data (files, images, network packets): Use InputStream and OutputStream subclasses (FileInputStream, Socket.getInputStream(), ByteArrayInputStream).
    • Text Data: For reading text, it's almost always better to use a Reader (like FileReader or InputStreamReader), which handles character encoding (like UTF-8) for you. InputStreamReader is a bridge between byte streams and character streams.

    Example of reading text with proper encoding:

    // Good for text files
    try (FileInputStream fis = new FileInputStream("my_text.txt");
         InputStreamReader isr = new InputStreamReader(fis, "UTF-8"); // Specify encoding!
         BufferedReader br = new BufferedReader(isr)) { // BufferedReader for efficiency
        String line;
        while ((line = br.readLine()) != null) {
            System.out.println(line);
        }
    } catch (IOException e) {
        e.printStackTrace();
    }
分享:
扫描分享到社交APP
上一篇
下一篇