问题一:向内存写入ASCII码表
ByteArrayOutputStream out=new ByteArrayOutputStream();
for(int i=1;i<=127;i++){
out.write(i);
}
write()方法指的是写入一个字节,则out.write(i)指的是写入i的第一个字节么?用for循环的整数i就能代表ASCII码表了吗?不懂,不明白为什么以上for循环就将ASCII码表写入了内存
问题二:书上说字节数组流的读、写不会发生IOEception异常,而字符数组六的读操作可能发生IOEception异常,为什么?
ByteArrayOutputStream out=new ByteArrayOutputStream();
for(int i=1;i<=127;i++){
out.write(i);
}
write()方法指的是写入一个字节,则out.write(i)指的是写入i的第一个字节么?用for循环的整数i就能代表ASCII码表了吗?不懂,不明白为什么以上for循环就将ASCII码表写入了内存
问题二:书上说字节数组流的读、写不会发生IOEception异常,而字符数组六的读操作可能发生IOEception异常,为什么?
/*
* @(#)ByteArrayOutputStream.java 1.49 04/05/18
*
* Copyright 2004 Sun Microsystems, Inc. All rights reserved.
* SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
*/package java.io;
/**
* This class implements an output stream in which the data is
* written into a byte array. The buffer automatically grows as data
* is written to it.
* The data can be retrieved using <code>toByteArray()</code> and
* <code>toString()</code>.
* <p>
* Closing a <tt>ByteArrayOutputStream</tt> has no effect. The methods in
* this class can be called after the stream has been closed without
* generating an <tt>IOException</tt>.
*
* @author Arthur van Hoff
* @version 1.49, 05/18/04
* @since JDK1.0
*/public class ByteArrayOutputStream extends OutputStream { /**
* The buffer where data is stored.
*/
protected byte buf[]; /**
* The number of valid bytes in the buffer.
*/
protected int count; /**
* Creates a new byte array output stream. The buffer capacity is
* initially 32 bytes, though its size increases if necessary.
*/
public ByteArrayOutputStream() {
this(32);
} /**
* Creates a new byte array output stream, with a buffer capacity of
* the specified size, in bytes.
*
* @param size the initial size.
* @exception IllegalArgumentException if size is negative.
*/
public ByteArrayOutputStream(int size) {
if (size < 0) {
throw new IllegalArgumentException("Negative initial size: "
+ size);
}
buf = new byte[size];
} /**
* Writes the specified byte to this byte array output stream.
*
* @param b the byte to be written.
*/
public synchronized void write(int b) {
int newcount = count + 1;
if (newcount > buf.length) {
byte newbuf[] = new byte[Math.max(buf.length << 1, newcount)];
System.arraycopy(buf, 0, newbuf, 0, count);
buf = newbuf;
}
buf[count] = (byte)b;
count = newcount;
} /**
* Writes <code>len</code> bytes from the specified byte array
* starting at offset <code>off</code> to this byte array output stream.
*
* @param b the data.
* @param off the start offset in the data.
* @param len the number of bytes to write.
*/
public synchronized void write(byte b[], int off, int len) {
if ((off < 0) || (off > b.length) || (len < 0) ||
((off + len) > b.length) || ((off + len) < 0)) {
throw new IndexOutOfBoundsException();
} else if (len == 0) {
return;
}
int newcount = count + len;
if (newcount > buf.length) {
byte newbuf[] = new byte[Math.max(buf.length << 1, newcount)];
System.arraycopy(buf, 0, newbuf, 0, count);
buf = newbuf;
}
System.arraycopy(b, off, buf, count, len);
count = newcount;
} /**
* Writes the complete contents of this byte array output stream to
* the specified output stream argument, as if by calling the output
* stream's write method using <code>out.write(buf, 0, count)</code>.
*
* @param out the output stream to which to write the data.
* @exception IOException if an I/O error occurs.
*/
public synchronized void writeTo(OutputStream out) throws IOException {
out.write(buf, 0, count);
} /**
* Resets the <code>count</code> field of this byte array output
* stream to zero, so that all currently accumulated output in the
* output stream is discarded. The output stream can be used again,
* reusing the already allocated buffer space.
*
* @see java.io.ByteArrayInputStream#count
*/
public synchronized void reset() {
count = 0;
} /**
* Creates a newly allocated byte array. Its size is the current
* size of this output stream and the valid contents of the buffer
* have been copied into it.
*
* @return the current contents of this output stream, as a byte array.
* @see java.io.ByteArrayOutputStream#size()
*/
public synchronized byte toByteArray()[] {
byte newbuf[] = new byte[count];
System.arraycopy(buf, 0, newbuf, 0, count);
return newbuf;
} /**
* Returns the current size of the buffer.
*
* @return the value of the <code>count</code> field, which is the number
* of valid bytes in this output stream.
* @see java.io.ByteArrayOutputStream#count
*/
public int size() {
return count;
} /**
* Converts the buffer's contents into a string, translating bytes into
* characters according to the platform's default character encoding.
*
* @return String translated from the buffer's contents.
* @since JDK1.1
*/
public String toString() {
return new String(buf, 0, count);
} /**
* Converts the buffer's contents into a string, translating bytes into
* characters according to the specified character encoding.
*
* @param enc a character-encoding name.
* @return String translated from the buffer's contents.
* @throws UnsupportedEncodingException
* If the named encoding is not supported.
* @since JDK1.1
*/
public String toString(String enc) throws UnsupportedEncodingException {
return new String(buf, 0, count, enc);
} /**
* Creates a newly allocated string. Its size is the current size of
* the output stream and the valid contents of the buffer have been
* copied into it. Each character <i>c</i> in the resulting string is
* constructed from the corresponding element <i>b</i> in the byte
* array such that:
* <blockquote><pre>
* c == (char)(((hibyte & 0xff) << 8) | (b & 0xff))
* </pre></blockquote>
*
* @deprecated This method does not properly convert bytes into characters.
* As of JDK 1.1, the preferred way to do this is via the
* <code>toString(String enc)</code> method, which takes an encoding-name
* argument, or the <code>toString()</code> method, which uses the
* platform's default character encoding.
*
* @param hibyte the high byte of each resulting Unicode character.
* @return the current contents of the output stream, as a string.
* @see java.io.ByteArrayOutputStream#size()
* @see java.io.ByteArrayOutputStream#toString(String)
* @see java.io.ByteArrayOutputStream#toString()
*/
@Deprecated
public String toString(int hibyte) {
return new String(buf, hibyte, 0, count);
} /**
* Closing a <tt>ByteArrayOutputStream</tt> has no effect. The methods in
* this class can be called after the stream has been closed without
* generating an <tt>IOException</tt>.
* <p>
*
*/
public void close() throws IOException {
}}
1、ByteArrayOutputStream,这个是一个内存输出流,就是将字节以流的形式保存在一段内存中,这个流不会抛出IO异常是因为他是直接输出到内存中而非其它外部存储器,输出到内存是绝对可行且不会出现什么错误的,当然内存不足也会错误,但不是IO错误了。
2、数据存储方式,数据在存储介质中一般都是以字节的形式来存储的,一个字节(byte)为一个8位,但是OutputStream的write方法是传入一个int类型,而int在java中是32位,表示4个字节即一个字的长度(字的长度根据不同处理器的运算位宽来决定,而java虚拟机规定的位宽是4个字节一个字)。这里java这么设计估计是为了方便,因为int完全可以表示一个byte所要表示的全部内容,所以这里传入的一个int你可以当作byte来看待,就像write(byte b)一样了。
3、ascii基本表其实就是1到127位的数字,这些数字分别映射一个字符或者操作符,而这127个数字完全可以由一个byte的位宽来表示,所以上面的程序直接把i存入就相当于存入ascii基本表了。
4、至于最后字符数组的读取可能发生IO异常的原因应该就是期望读取字符大于实际能够读取字符而导致的IO异常。
/**
* Writes the specified byte to this byte array output stream.
*
* @param b the byte to be written.
*/
public synchronized void write(int b) {
int newcount = count + 1;
if (newcount > buf.length) {
byte newbuf[] = new byte[Math.max(buf.length << 1, newcount)];
System.arraycopy(buf, 0, newbuf, 0, count);
buf = newbuf;
}
buf[count] = (byte)b;
count = newcount;
}关键在于 buf[count] = (byte)b;
进行了强制转换