java网络编程读书笔记-Ch02

来源:互联网 发布:linux系统的rpm包什么 编辑:程序博客网 时间:2024/05/29 04:05

Streams

同步的streams需要等待读写完毕,才能继续做别的
Streams are synchronous; that is, when a program (really a thread) asks a stream to read or write a piece of data, it waits for the data to be read or written before it does anything else.

basic output class

public abstract class OutputStream// 方法public abstract void write(int b) throws IOExceptionpublic void write(byte[] data) throws IOExceptionpublic void write(byte[] data, int offset, int length)throws IOExceptionpublic void flush() throws IOExceptionpublic void close() throws IOException

The flush() method breaks the deadlock by forcing the buffered stream to send its data even if the buffer isn’t yet full.

It’s important to flush your streams whether you think you need to or not. Depending on how you got hold of a reference to the stream, you may or may not know whether it’s buffered.

Java 7 introduces the try with resources construct to make this cleanup neater. Instead of declaring the stream variable outside the try block, you declare it inside an argument list of the try block. For instance, the preceding fragment now becomes the much simpler

try(OutputStream out = new FileOutputStream("/tmp/data.txt")){    // do work}catch(IOException ex){    System.err.println(ex.getMessage())}

The finally clause is no longer needed. Java automatically invokes close() on any AutoCloseable objects declared inside the argument list of the try block.

byte[] input = new byte[1024];int bytesRead = in.read(input);

It attempts to read 1,024 bytes from the InputStream in into the array input. However, if only 512 bytes are available, that’s all that will be read, and bytesRead will be set to 512.

int bytesRead = 0;int bytesToRead = 1024;byte[] input = new byte[bytesToRead];while(bytesRead < bytesToRead){    bytesRead += in.read(input, bytesRead, bytesToRead - bytesRead)}

All three read() methods return –1 to signal the end of the stream.

int bytesAvailable = in.available();byte[] input = new byte[bytesAvailable];int bytesRead = in.read(input, 0, bytesAvailable);

Marking and Resetting

three less commonly used methods that allow programs to back up and reread data they’ve already read

public void mark(int readAheadLimit)public void reset() throws IOExceptionpublic boolean markSupported()

In order to reread data, mark the current position in the stream with the mark() method. At a later point, you can reset the stream to the marked position using the reset() method.

The number of bytes you can read from the mark and still reset is determined by the readAheadLimit argument to mark().

Marking and resetting are usually implemented by storing every byte read from the marked position on in an internal buffer.

Filter Streams

InputStream and OutputStream are fairly raw classes. They read and write bytes singly or in groups, but that’s all.
这些bytes是 integer, IEEE754 floating-point, Unicode text由编程人员自己来决定。怎么解释这些字节,是你的事。有一些非常常用的data formats

For example, many integers passed as parts of network protocols are 32-bit big-endian integers. Much of the text sent over the Web is either 7-bit ASCII, 8-bit Latin-1, or multibyte UTF-8. Many files transferred by FTP are stored in the ZIP format. Java provides a number of filter classes you can attach to raw streams to translate the raw bytes to and from these and other formats.

例如下面一个流程:
raw compressed, encrypted data –TelnetInputStream–> raw compressed,encrypted data –BufferedInputStream–> buffered, compressed, encrypted data –CipherInputStream–> buffered, compressed data –GZIPInputStream–> buffered data –InputStreamReader–> Text

Chaining Filters Together

FileInputStream fin = new FileInputStream("data.txt");BufferedInputStream bin = new BufferedInputStream(fin);
\\ 为了避免不同的名称对同一个source读写InputStream in = new FileInputStream("data.txt");in = new BufferedInputStream(in);

或者这样

DataOutputStream dout = new DataOutputStream(new BufferedOutputStream( new FileOutputStream("data.txt")));

Buffered Streams

The BufferedInputStream class also has a protected byte array named buf that serves as a buffer. When one of the stream’s read() methods is called, it first tries to get the requested data from the buffer.

public BufferedInputStream(InputStream in)public BufferedInputStream(InputStream in, int buffersize)public BufferedOutputStream(OutputStream out)public BufferedOutputStream(OutputStream out, int buffersize)

BufferedInputStream does not declare any new methods of its own. It only overrides methods from InputStream. It does support marking and resetting.

BufferedOutputStream also does not declare any new methods of its own. You invoke its methods exactly as you would in any output stream. The difference is that each write places data in the buffer rather than directly on the underlying output stream. Conse‐ quently, it is essential to flush the stream when you reach a point at which the data needs to be sent.

PrintStream

public PrintStream(OutputStream out)public PrintStream(OutputStream out, boolean autoFlush)

By default, print streams should be explicitly flushed. However, if the autoFlush argu‐ ment is true, the stream will be flushed every time a byte array or linefeed is written or a println() method is invoked.

public void print(boolean b) public void print(char c) public void print(int i) public void print(long l) public void print(float f) public void print(double d) public void print(char[] text) public void print(String s) public void print(Object o) public void println()public void println(boolean b) public void println(char c) public void println(int i) public void println(long l) public void println(float f) public void println(double d) public void println(char[] text) public void println(String s) public void println(Object o)

换行问题

The println() methods do the same thing, but they also append a platform-dependent line separator to the end of the line they write. This is a linefeed (\n) on Unix (including Mac OS X), a carriage return (\r) on Mac OS 9, and a carriage return/linefeed pair (\r \n) on Windows.

Most network protocols such as HTTP and Gnutella specify that lines should be terminated with a carriage return/linefeed pair. Using println() makes it easy to write a program that works on Windows but fails on Unix and the Mac. Although many servers and clients are liberal in what they accept and can handle in‐ correct line terminators, there are occasional exceptions.

编码问题

The second problem is that PrintStream assumes the default encoding of the platform on which it’s running.

PrintStream吃掉所有的异常

The third problem is that PrintStream eats all exceptions.

However, PrintStream catches any exceptions thrown by the underlying output stream.

Instead, PrintStream relies on an outdated and inadequate error flag. If the underlying stream throws an exception, this internal error flag is set. The programmer is relied upon to check the value of the flag using the checkError() method:

public boolean checkError()

Data Streams

The DataInputStream and DataOutputStream classes provide methods for reading and writing Java’s primitive data types and strings in a binary format.

All data is written in big-endian format. Integers are written in two’s complement in the minimum number of bytes possible.

Readers and Writers

Java provides an almost complete mirror of the input and output stream class hierarchy designed for working with characters instead of bytes.

In this mirror image hierarchy, two abstract superclasses define the basic API for reading and writing characters. The java.io.Reader class specifies the API by which characters are read. The java.io.Writer class specifies the API by which characters are written.

The most important concrete subclasses of Reader and Writer are the InputStream Reader and the OutputStreamWriter classes.

In addition to these two classes, the java.io package provides several raw reader and writer classes that read characters without directly requiring an underlying input stream, including:

FileReaderFileWriterStringReaderStringWriter CharArrayReader CharArrayWriter

Writers

protected Writer()protected Write(Object lock)public abstract void write(char[] text, int offset, int length) throws IOExpectionpublic void write(int c) throws IOExceptionpublic void write(char[] text) throws IOExceptionpublic void write(String s) throws IOExceptionpublic void write(String s, int offset, int length) throws IOException public abstract void flush() throws IOExceptionpublic abstract void close() throws IOException
原创粉丝点击