首页 > 代码库 > Java IO 流

Java IO 流

 

 

<style>html,body,div,span,applet,object,iframe,h1,h2,h3,h4,h5,h6,p,blockquote,pre,a,abbr,acronym,address,big,cite,code,del,dfn,em,img,ins,kbd,q,s,samp,small,strike,strong,sub,sup,tt,var,b,u,i,center,dl,dt,dd,ol,ul,li,fieldset,form,label,legend,table,caption,tbody,tfoot,thead,tr,th,td,article,aside,canvas,details,embed,figure,figcaption,footer,header,hgroup,menu,nav,output,ruby,section,summary,time,mark,audio,video { margin: 0; padding: 0; border: 0 } body { font-family: Helvetica, arial, freesans, clean, sans-serif; font-size: 14px; line-height: 1.6; color: #333; background-color: #fff; padding: 20px; max-width: 960px; margin: 0 auto } body>*:first-child { margin-top: 0 !important } body>*:last-child { margin-bottom: 0 !important } p,blockquote,ul,ol,dl,table,pre { margin: 15px 0 } h1,h2,h3,h4,h5,h6 { margin: 20px 0 10px; padding: 0; font-weight: bold } h1 tt,h1 code,h2 tt,h2 code,h3 tt,h3 code,h4 tt,h4 code,h5 tt,h5 code,h6 tt,h6 code { font-size: inherit } h1 { font-size: 28px; color: #000 } h2 { font-size: 24px; border-bottom: 1px solid #ccc; color: #000 } h3 { font-size: 18px } h4 { font-size: 16px } h5 { font-size: 14px } h6 { color: #777; font-size: 14px } body>h2:first-child,body>h1:first-child,body>h1:first-child+h2,body>h3:first-child,body>h4:first-child,body>h5:first-child,body>h6:first-child { margin-top: 0; padding-top: 0 } a:first-child h1,a:first-child h2,a:first-child h3,a:first-child h4,a:first-child h5,a:first-child h6 { margin-top: 0; padding-top: 0 } h1+p,h2+p,h3+p,h4+p,h5+p,h6+p { margin-top: 10px } a { color: #4183C4; text-decoration: none } a:hover { text-decoration: underline } ul,ol { padding-left: 30px } ul li>:first-child,ol li>:first-child,ul li ul:first-of-type,ol li ol:first-of-type,ul li ol:first-of-type,ol li ul:first-of-type { margin-top: 0px } ul ul,ul ol,ol ol,ol ul { margin-bottom: 0 } dl { padding: 0 } dl dt { font-size: 14px; font-weight: bold; font-style: italic; padding: 0; margin: 15px 0 5px } dl dt:first-child { padding: 0 } dl dt>:first-child { margin-top: 0px } dl dt>:last-child { margin-bottom: 0px } dl dd { margin: 0 0 15px; padding: 0 15px } dl dd>:first-child { margin-top: 0px } dl dd>:last-child { margin-bottom: 0px } pre,code,tt { font-size: 12px; font-family: Consolas, "Liberation Mono", Courier, monospace } code,tt { margin: 0 0px; padding: 0px 0px; white-space: nowrap; border: 1px solid #eaeaea; background-color: #f8f8f8 } pre>code { margin: 0; padding: 0; white-space: pre; border: none; background: transparent } pre { background-color: #f8f8f8; border: 1px solid #ccc; font-size: 13px; line-height: 19px; overflow: auto; padding: 6px 10px } pre code,pre tt { background-color: transparent; border: none } kbd { background-color: #DDDDDD; background-image: linear-gradient(#F1F1F1, #DDDDDD); background-repeat: repeat-x; border-color: #DDDDDD #CCCCCC #CCCCCC #DDDDDD; border-style: solid; border-width: 1px; font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; line-height: 10px; padding: 1px 4px } blockquote { border-left: 4px solid #DDD; padding: 0 15px; color: #777 } blockquote>:first-child { margin-top: 0px } blockquote>:last-child { margin-bottom: 0px } hr { clear: both; margin: 15px 0; height: 0px; overflow: hidden; border: none; background: transparent; border-bottom: 4px solid #ddd; padding: 0 } table th { font-weight: bold } table th,table td { border: 1px solid #ccc; padding: 6px 13px } table tr { border-top: 1px solid #ccc; background-color: #fff } table tr:nth-child(2n) { background-color: #f8f8f8 } img { max-width: 100% }</style>

关于面向对象的方法的一个说明。 对于多态而言,可以使用子类来实例化父类,这对于面向对象有很重要的作用,但是,子类中的一些独有的方法父类就掉用不到了,这个时候可以使用向下转型,将父类进行强行的数据转型,就可以使用这些方法了


字节流和字符流

字节流InputStream/OutputStream ,只能操作byte
字符流Reader/Writer

FileoutputStream(File f)

字节流本身是只能操作byte的。
对于这一个类,如果文件不存在会自动创建
write()方法默认会将文件进行覆盖
可以使用构造方法FileoutputStream(File f,boolean append),这样就可以指定要不要使用追加模式

FileoutputStream(File f)

方法 - available() 获得可以读取的字节数

字符流

一般一个字符为两个字节,可以直接操作字符串
会用到缓冲区
FileWriter/FileReader
默认依然是覆盖,要追加只要和FileoutputStream类似加boolean标志就好了 Filereader读取到char/char[]

字节流和字符流的不同

字节流是直接与文件操作,不会用到缓冲区 字符流数据先放在缓冲区,然后再从缓冲区写到文件,要记得fiush()或者close()

字节-字符的转换流

  1. InputStreamReader
    将一个输入字节流转为字符流,是Reader的子类
  2. OutputStreamWriter
    将一个输出字节流转为字符流,是Writer的子类

FileWriter是OutputStreamWriter的子类 FileReader是OutputStreamReader的子类

内存操作流

ByteArrayInputStream(byte[])
将byte中是数据写入内存中
ByteArrayOutputStream()
实际的意思就是说,通过输入流将数据写入到内存里面,然后通过输出流把内存里面的东西取出来!

    private static void tesByteArrayInputStream() {
    // 创建ByteArrayInputStream字节流,内容是ArrayLetters数组
    ByteArrayInputStream bais = new ByteArrayInputStream(ArrayLetters);

    // 从字节流中读取5个字节
    for (int i=0; i<LEN; i++) {
        // 若能继续读取下一个字节,则读取下一个字节
        if (bais.available() >= 0) {
            // 读取“字节流的下一个字节”
            int tmp = bais.read();
            System.out.printf("%d : 0x%s\n", i, Integer.toHexString(tmp));
        }
    }

    // 若“该字节流”不支持标记功能,则直接退出
    if (!bais.markSupported()) {
        System.out.println("make not supported!");
        return ;
    }

    // 标记“字节流中下一个被读取的位置”。即--标记“0x66”,因为因为前面已经读取了5个字节,所以下一个被读取的位置是第6个字节”
    // (01), ByteArrayInputStream类的mark(0)函数中的“参数0”是没有实际意义的。
    // (02), mark()与reset()是配套的,reset()会将“字节流中下一个被读取的位置”重置为“mark()中所保存的位置”
    bais.mark(0);

    // 跳过5个字节。跳过5个字节后,字节流中下一个被读取的值应该是“0x6B”。
    bais.skip(5);

    // 从字节流中读取5个数据。即读取“0x6B, 0x6C, 0x6D, 0x6E, 0x6F”
    byte[] buf = new byte[LEN];
    bais.read(buf, 0, LEN);
    // 将buf转换为String字符串。“0x6B, 0x6C, 0x6D, 0x6E, 0x6F”对应字符是“klmno”
    String str1 = new String(buf);
    System.out.printf("str1=%s\n", str1);

    // 重置“字节流”:即,将“字节流中下一个被读取的位置”重置到“mark()所标记的位置”,即0x66。
    bais.reset();
    // 从“重置后的字节流”中读取5个字节到buf中。即读取“0x66, 0x67, 0x68, 0x69, 0x6A”
    bais.read(buf, 0, LEN);
    // 将buf转换为String字符串。“0x66, 0x67, 0x68, 0x69, 0x6A”对应字符是“fghij”
    String str2 = new String(buf);
    System.out.printf("str2=%s\n", str2);
}

}

管道流

管道流就是实现两个进程之间的通信

PipeOutputStream PipeInputStream 使用的时候要使用connect()把输入输出流连接起来,Connect是PipeOutputStream的方法,用来连接一个PipeInputStream

打印流

PrintStream

定义了很多的print和pringtln方法,可以打印任意数据类型
System.out就是定位在输出设备的PrintStream

构造方法,指定输出的位置
PrintSTream(OutputStream out)

这样打印输出更加方便了,PrintStream就是OutputStream的子类,可以方便的进行输出,这样的设计称之为装饰设计模式

PrintWriter与上面的类似

格式化输出

类似于C语言的格式化输出 %d,%s,%f,%c

ps.printf("姓名%s,年龄:%d",a,b);

System.in以及BufferedReader(字符流)

是一个InputStream

    BufferedReader buf=null;
    buf=new BufferedReader(new InputStreamReader(System.in));
    String str=null;
    try {
        while ((str=buf.readLine())!=null){
            System.out.println(str);
        }
    } catch (IOException e) {
        e.printStackTrace();
    }

输入输出重定向

System.setOut(new PrintStream(new FileOutputStream("D:/a.txt")));

实际上in、out、err就是System的三个常量,可以通过set方法改变,然后就完成了重定向的作用。

Scanner

在java.util包中,可以实现BufferedReader的全部功能,是一个工具类

  • 默认的分隔符是空格,可以自行设置
  • 非常强大,可以接受多种类型的数据,但是对于日期类型没有支持,可以使用Scanner.hasNext(Pattern)/next(Pattern)匹配来取出数据
  • 可以接受File,做一系列文件操作

    Scanner scanner=new Scanner(System.in);
    scanner.useDelimiter("\n");//修改分割符
    int a=0;
    float f=0f;
    String date=null;
    
    if(scanner.hasNextInt()){
        a=scanner.nextInt();
    }
    if(scanner.hasNextFloat()){
        f=scanner.nextFloat();
    }
    if(scanner.hasNext("\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2}")){
        date=scanner.next("\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2}");
    }
    System.out.println(a+" "+f+" "+date);
    try {
        Date date1=new SimpleDateFormat("yy-MM-dd hh:mm:ss").parse(date);
        System.out.println(date1);
    } catch (ParseException e) {
        e.printStackTrace();
    }
    

合并流

压缩流

支持三种格式的压缩,zip/jar/Gzip,这里以zip为例另外两种都是一样的
ZipEntry,就是压缩文件目录下的每一个文件

  • ZipOutputStream(OutputStream)
    • PutNextEntry(ZipEntry ?)

可以将文件、文件夹进行压缩

ZipFile类

专门表示压缩文件的类

回退流

字符编码

获得本机编码
System.getProperity("file.encoding")

常见的编码格式

  • iso8859-1单字节编码,只能表示英文
  • GBK国标,表示汉字
  • unicode 16进制两个字节的编码,最标准的,但是不兼容iso-8859-1
  • utf 变长的编码,一个字符长度1--6不等,可以表示所有语言的字符、

关于io流的结构

输入流

  • InputStream
    • ByteArrayInputStream(byte[])
    • FileInputStream(File)
    • PipedInputStream
    • SequenceInputStream(InputStream,InputStream)
    • FilterInputStream
      • BufferedInputStream(InputStream)
      • PushbackInputStream
      • DataInputStream
        • ObjectInputStream

输出流

  • OutputStream
    • ByteArrayOutputStream
    • FileOutputStream
    • PipedOutputStream
    • FilterOutputStream
      • BufferedOutputStream
      • PrintWriter
      • DataOutputStream
        • ObjectOutputStream

常见的方法

                        InputStream是输入字节数据用的类,所以InputStream类提供了3种重载的read方法.Inputstream类中的常用方法:

                      1   public abstract int read( ):读取一个byte的数据,返回值是高位补0的int类型值。

                      2   public int read(byte b[ ]):读取b.length个字节的数据放到b数组中。返回值是读取的字节数。该方法实际上是调用下一个方法实现的

                      3   public int read(byte b[ ], int off, int len):从输入流中最多读取len个字节的数据,存放到偏移量为off的b数组中。

                      4   public int available( ):返回输入流中可以读取的字节数。注意:若输入阻塞,当前线程将被挂起,如果InputStream对象调用这个方法的话,它只会返回0,这个方法必须由继承InputStream类的子类对象调用才有用,

                      5   public long skip(long n):忽略输入流中的n个字节,返回值是实际忽略的字节数, 跳过一些字节来读取

                      6   public int close( ) :我们在使用完后,必须对我们打开的流进行关闭. 

                    OutputStream提供了3个write方法来做数据的输出,这个是和InputStream是相对应的。

                      1. public void write(byte b[ ]):将参数b中的字节写到输出流。

                      2. public void write(byte b[ ], int off, int len) :将参数b的从偏移量off开始的len个字节写到输出流。

                      3. public abstract void write(int b) :先将int转换为byte类型,把低字节写入到输出流中。

                      4. public void flush( ) : 将数据缓冲区中数据全部输出,并清空缓冲区。

                      5. public void close( ) : 关闭输出流并释放与流相关的系统资源。

java的流类提供了结构化方法,如,底层流和高层过滤流。
而高层流不是从输入设备读取,而是从其他流读取。同样高层输出流也不是写入输出设备,而是写入其他流。
使用"分层对象(layered objects)",为单个对象动态地,透明地添加功能的做法,被称为Decorator
Pattern。Decorator模式要求所有包覆在原始对象之外的对象,都必须具有与之完全相同的接口。这使得
decorator的用法变得非常的透明--无论对象是否被decorate过,传给它的消息总是相同的。这也是Java I/O
类库要有"filter(过滤器)"类的原因:抽象的"filter"类是所有decorator的基类

  • DataInputStream 包含了一整套读取primitive数据的接口
  • BufferedInputStream,为InputStream增加了一个缓冲区,缓冲区的大小是8k
  • PushbackInputStream 有一个"弹压单字节"的缓冲区,可以把最后读到的那个字节再压回去
  • DataOutputStream 包括写入primitive数据的全套接口。
  • PrintStream(inpurstream,boolean autoflush) 打印流
  • BufferedOutputStream 有缓冲区

 

 

Java IO 流