jdk 源码分析(18)java io包分析

java.io包里定义输入与输出的关系, 输入和输出两种方式,这里只分析输入就可以,输出与输入相似。

1)第一个抽象类:InputStream
可以说IO里面一半与这个类直接或者间接相关,其余类要么是实现,要么是封装。

2)第一个封装接口:DataInput ,用来直接从输入流中读取数据。
DataInput 主要是将InputStream封装, 比如  DataInputStream, readInt,需要读4个字节,应为inputStream只能读1个字节。所以读四次就行。但是 InputStream的实现类不同, DataInput的不同实现类也是有差别的。
 
    
  1. public final int readInt() throws IOException {
  2. int ch1 = in.read();
  3. int ch2 = in.read();
  4. int ch3 = in.read();
  5. int ch4 = in.read();
  6.     //确保每次都能读到数据
  7. if ((ch1 | ch2 | ch3 | ch4) < 0)
  8. throw new EOFException();
  9.         //合成为int
  10. return ((ch1 << 24) + (ch2 << 16) + (ch3 << 8) + (ch4 << 0));
  11. }
3)Reader:用于将字节流转换成字符流。所以中间需要一个转码器。
主要实现InputStreamReader,以及FileReader
public int read() throws IOException {
    return sd.read();
}
buffer读因为是对字符层面的读写,所有可以获取到line的标志了。而且通过不同解码可以读取到中文和英文。
 
    
  1. String readLine(boolean ignoreLF) throws IOException {
  2. StringBuffer s = null;
  3. int startChar;
  4. synchronized (lock) {
  5. ensureOpen();
  6. boolean omitLF = ignoreLF || skipLF;
  7. bufferLoop:
  8. for (;;) {
  9. if (nextChar >= nChars)
  10. fill();
  11. if (nextChar >= nChars) { /* EOF */
  12. if (s != null && s.length() > 0)
  13. return s.toString();
  14. else
  15. return null;
  16. }
  17. boolean eol = false;
  18. char c = 0;
  19. int i;
  20.         //标准为行结束
  21. /* Skip a leftover '\n', if necessary */
  22. if (omitLF && (cb[nextChar] == '\n'))
  23. nextChar++;
  24. skipLF = false;
  25. omitLF = false;
  26. charLoop:
  27. for (i = nextChar; i < nChars; i++) {
  28. c = cb[i];
  29. if ((c == '\n') || (c == '\r')) {
  30. eol = true;
  31. break charLoop;
  32. }
  33. }
  34. startChar = nextChar;
  35. nextChar = i;
  36. if (eol) {
  37. String str;
  38. if (s == null) {
  39. str = new String(cb, startChar, i - startChar);
  40. } else {
  41. s.append(cb, startChar, i - startChar);
  42. str = s.toString();
  43. }
  44. nextChar++;
  45. if (c == '\r') {
  46. skipLF = true;
  47. }
  48. return str;
  49. }
  50. if (s == null)
  51. s = new StringBuffer(defaultExpectedLineLength);
  52. s.append(cb, startChar, i - startChar);
  53. }
  54. }
  55. }

4)ObjectInput 这个是继承了DataInput,主要进一步将读的数据合并成对象。
主要实现ObjectInputStream。里面涉及到序列化,反序类化。

5)缓存读BufferedInputStream和 BufferedReader
这个主要是可以通过用户自定长度来读。可以设置一个buffer byte 来存储数据,从inputStream读到这个buffer里。 相应的BufferedReader 是对其他字符流的一种限制。比如readLine


正式因为有了上面不同的包装才有了不同的文件读写。
1、按字节读取文件内容
2、按字符读取文件内容
3、按行读取文件内容

4、随机读取文件内容 


 
    
  1. public static void main(String[] args) throws IOException {
  2. File file = new File("c:");
  3. FileReader reader = new FileReader(file);
  4. BufferedReader bufferedReader = new BufferedReader(reader);
  5. String line = bufferedReader.readLine();
  6. FileInputStream in = new FileInputStream(file);
  7. int c = 0;
  8. while((c =in.read())!=-1){
  9. System.out.println(c);
  10. }
  11. in.read();
  12. }

文件系统不好写,内容太多了。写的比较乱。

总结:io分为读output和写input,同时通过解码可以分为字符流Reader和字节流InputStream。通过组装DataInput可以读取int,long和float和short等。 通过ObjectInputStream序列化和反射可以直接读成对象readUTF等。

你可能感兴趣的:(jdk,源代码)