java.io包里定义输入与输出的关系,
输入和输出两种方式,这里只分析输入就可以,输出与输入相似。
1)第一个抽象类:InputStream
可以说IO里面一半与这个类直接或者间接相关,其余类要么是实现,要么是封装。
2)第一个封装接口:DataInput ,用来直接从输入流中读取数据。
DataInput 主要是将InputStream封装,
比如
DataInputStream,
readInt,需要读4个字节,应为inputStream只能读1个字节。所以读四次就行。但是
InputStream的实现类不同,
DataInput的不同实现类也是有差别的。
public final int readInt() throws IOException { int ch1 = in.read(); int ch2 = in.read(); int ch3 = in.read(); int ch4 = in.read(); //确保每次都能读到数据
if ((ch1 | ch2 | ch3 | ch4) < 0) throw new EOFException(); //合成为int
return ((ch1 << 24) + (ch2 << 16) + (ch3 << 8) + (ch4 << 0)); }
3)Reader:用于将字节流转换成字符流。所以中间需要一个转码器。
主要实现InputStreamReader,以及FileReader
public int read()
throws IOException {
return sd.read()
;
}
buffer读因为是对字符层面的读写,所有可以获取到line的标志了。而且通过不同解码可以读取到中文和英文。
String readLine(boolean ignoreLF) throws IOException { StringBuffer s = null; int startChar; synchronized (lock) { ensureOpen(); boolean omitLF = ignoreLF || skipLF; bufferLoop: for (;;) { if (nextChar >= nChars) fill(); if (nextChar >= nChars) { /* EOF */ if (s != null && s.length() > 0) return s.toString(); else return null; } boolean eol = false; char c = 0; int i; //标准为行结束
/* Skip a leftover '\n', if necessary */ if (omitLF && (cb[nextChar] == '\n')) nextChar++; skipLF = false; omitLF = false; charLoop: for (i = nextChar; i < nChars; i++) { c = cb[i]; if ((c == '\n') || (c == '\r')) { eol = true; break charLoop; } } startChar = nextChar; nextChar = i; if (eol) { String str; if (s == null) { str = new String(cb, startChar, i - startChar); } else { s.append(cb, startChar, i - startChar); str = s.toString(); } nextChar++; if (c == '\r') { skipLF = true; } return str; } if (s == null) s = new StringBuffer(defaultExpectedLineLength); s.append(cb, startChar, i - startChar); } } }
4)ObjectInput 这个是继承了DataInput,主要进一步将读的数据合并成对象。
主要实现ObjectInputStream。里面涉及到序列化,反序类化。
5)缓存读BufferedInputStream和
BufferedReader
这个主要是可以通过用户自定长度来读。可以设置一个buffer byte 来存储数据,从inputStream读到这个buffer里。
相应的BufferedReader 是对其他字符流的一种限制。比如readLine
正式因为有了上面不同的包装才有了不同的文件读写。
1、按字节读取文件内容
2、按字符读取文件内容
3、按行读取文件内容
4、随机读取文件内容
public static void main(String[] args) throws IOException { File file = new File("c:"); FileReader reader = new FileReader(file); BufferedReader bufferedReader = new BufferedReader(reader); String line = bufferedReader.readLine(); FileInputStream in = new FileInputStream(file); int c = 0; while((c =in.read())!=-1){ System.out.println(c); } in.read(); }
文件系统不好写,内容太多了。写的比较乱。
总结:io分为读output和写input,同时通过解码可以分为字符流Reader和字节流InputStream。通过组装DataInput可以读取int,long和float和short等。
通过ObjectInputStream序列化和反射可以直接读成对象readUTF等。