黑马程序员——java编程那些事儿____IO流(一)

来源:互联网 发布:怎么找淘宝刷手 编辑:程序博客网 时间:2024/04/28 06:33

                                                                                    -------android培训java培训、期待与您交流! ----------

 

IO很喜欢,也很有用,做了很详细的总结


1IO流概述

(1)用来处理设备(硬盘,控制台,内存)间的数据。
(2)java中对数据的操作都是通过流的方式。
(3)java用于操作流的类都在io包中。
(4)按照流操作的数据的类型不同:分为字节流和字符流。字符流是为了方便中文的操作而来的。
(5)按照流的流向不同分为:输入流,输出流

 

2IO流常用基类:


(1)字节流
写入字节流:OutputStream:字节写入流抽象类
|--->FileOutputStream:字节写入流
|--->BufferedOutputStream:字节写入流缓冲区

|--->PrintStream:打印流

读取字节流:InputStream:字节读取流抽象类
|--->FileInputStream:字节读取流

|--->BufferedInputStream:字节读取流缓冲区

(2)字符流
写入字符流:Writer:字符写入流的抽象
|--->FileWriter:字符写入流
|--->BufferedWriter:字符写入流缓冲区
|--->OutputStreamWriter:字符通向字节的转换流(涉及键盘录入时用)

|--->PrintWriter:打印流,可处理各种类型的数据

读取字符流:Reader: 字符读取流的抽象类
|--->FileReader:字符读取流
|--->BufferedReader:字符读取流缓冲区
|--->InputStreamReader:字节通向字符的转换流(涉及键盘录入时用)

|--->LineNumberReader:跟踪行号的缓冲字符读取流

(3)IO流常用基类方法摘要:
**字节写入流:OutputStream
void close() 关闭此输出流并释放与此流有关的所有系统资源。
void flush() 刷新此输出流并强制写出所有缓冲的输出字节。
abstract void write(int b)  将指定的字节写入此输出流。
void write(byte[] b) 将 b.length 个字节从指定的 byte 数组写入此输出流。    

void write(byte[] b, int off, int len) 将指定 byte 数组中从偏移量 off 开始的 len 个字节写入此输出流

 
**字节读取流:InputStream
void close() 关闭此输入流并释放与该流关联的所有系统资源。
int available() (特有方法!!)
                    返回此输入流下一个方法调用可以不受阻塞地从此输入流读取(或跳过)的估计字节数。 
abstract  int read() 从输入流中读取数据的下一个字节。 
int read(byte[] b) 从输入流中读取一定数量的字节,并将其存储在缓冲区数组 中。
int read(byte[] b, int off, int len)  将输入流中最多 len 个数据字节读入 byte 数组。

long skip(long n) 跳过和丢弃此输入流中数据的 个字节。

                      
**字符写入流:Writer
abstract void close() 关闭此流,但要先刷新它。
abstract void flush() 刷新该流的缓冲。
void write(int c) 写入单个字符。
void write(char[] cbuf) 写入字符数组。          
abstract void write(char[] cbuf, int off, int len) 写入字符数组的某一部分。 
void write(String str) 写入字符串。 

void write(String str, int off, int len) 写入字符串的某一部分。 


**字符读取流:Reader
abstract  void close() 关闭该流并释放与之关联的所有资源。
int read() 读取单个字符。
int read(char[] cbuf)  将字符读入数组
abstract  int read(char[] cbuf, int off, int len) 将字符读入数组的某一部分。
long skip(long n)  跳过字符。 

 

3IO流常用基类的子类:

 

字节流

**写入流:

(1)FileOutputStream

**构造方法:

FileOutputStream(String name) 

               创建一个向具有指定名称的文件中写入数据的输出文件流。

FileOutputStream(String name, boolean append) 

               创建一个向具有指定 name 的文件中写入数据的输出文件流。

FileOutputStream(File file) 

               创建一个向指定 File 对象表示的文件中写入数据的文件输出流。 

FileOutputStream(File file, boolean append) 

              创建一个向指定 File 对象表示的文件中写入数据的文件输出流。

**方法摘要:

public void flush()字节写入的时候不用刷新

void close() 关闭此文件输出流并释放与此流有关的所有系统资源。

void write(int b) 将指定字节写入此文件输出流。

void write(byte[] b, int off, int len) 将指定 byte 数组中从偏移量 off 开始的 len 个字节写入此文件输出流。 

void write(int b) 将指定字节写入此文件输出流。

(2)BufferedOutputStream

**构造方法:

BufferedOutputStream(OutputStream out) 

                 创建一个新的缓冲输出流,以将数据写入指定的底层输出流。 

BufferedOutputStream(OutputStream out, int size) 

                 创建一个新的缓冲输出流,以将具有指定缓冲区大小的数据写入指定的底层输出流。 

**方法摘要:

void flush() 刷新此缓冲的输出流。          

void write(byte[] b, int off, int len) 

                将指定 byte 数组中从偏移量 off 开始的 len 个字节写入此缓冲的输出流。 

void write(int b) 将指定的字节写入此缓冲的输出流。


(3)PrintStream打印流,可将各种类型的数据原样打印,有自动刷新功能

**构造方法:

PrintStream(String fileName) 

                创建具有指定文件名称且不带自动行刷新的新打印流。

PrintStream(File file) 

                创建具有指定文件且不带自动行刷新的新打印流。

PrintStream(OutputStream out) 

                创建新的打印流。

PrintStream(OutputStream out, boolean autoFlush) (autoFlushtrue时具有自动刷新功能)

                创建新的打印流。

**方法摘要:

PrintStream append(char c) 

              将指定字符添加到此输出流。

void close() 

              关闭流。 

void flush() 

               刷新该流的缓冲。

void print(各种类型的数据:

               打印各种类型的数据 

void println(各种类型的数据:):自动换行

               打印各种类型的数据 

void write(byte[] buf, int off, int len) 

               将 len 字节从指定的初始偏移量为 off 的 byte 数组写入此流。 

void write(int b) 

               将指定的字节写入此流。 

**读取流:


(1)FileInputStream

**构造方法:

FileInputStream(String name) 

通过打开一个到实际文件的连接来创建一个 FileInputStream

该文件通过文件系统中的路径名 name 指定。

FileInputStream(File file) 

通过打开一个到实际文件的连接来创建一个 FileInputStream

该文件通过文件系统中的 File 对象 file 指定。

**方法摘要:

int available() (字节读取流特有方法!!!)

                 返回下一次对此输入流调用的方法可以不受阻塞地从此输入流读取(或跳过)的估计剩余字节数。

int read() 

                 从此输入流中读取一个数据字节。 

int read(byte[] b) 

                从此输入流中将最多 b.length 个字节的数据读入一个 byte 数组中。 

int read(byte[] b, int off, int len) 

                从此输入流中将最多 len 个字节的数据读入一个 byte 数组中。 

long skip(long n) 

               从输入流中跳过并丢弃 个字节的数据。 


(2)BufferedInputStream:(有read方法,注意与BufferReader的特有方法readLine进行区别)

**构造方法:

BufferedInputStream(InputStream in) 

               创建一个 BufferedInputStream 并保存其参数,即输入流 in,以便将来使用。 

BufferedInputStream(InputStream in, int size) 

               创建具有指定缓冲区大小的 BufferedInputStream 并保存其参数,即输入流 in,以便将来使用。 

**方法摘要:

int available() (字节读取流特有方法!!!)

              返回可以从此输入流读取(或跳过)、且不受此输入流接下来的方法调用阻塞的估计字节数。 

int read() 

              参见 InputStream 的 read 方法的常规协定。 

int read(byte[] b, int off, int len) 

              从此字节输入流中给定偏移量处开始将各字节读取到指定的 byte 数组中。 

long skip(long n) 

             参见 InputStream 的 skip 方法的常规协定。

FileInputStream与FileOutputStream的例子,复制一个图片

/*复制一个图片思路:1,用字节读取流对象和图片关联。2,用字节写入流对象创建一个图片文件。用于存储获取到的图片数据。3,通过循环读写,完成数据的存储。4,关闭资源。*/import java.io.*;class  CopyPic{public static void main(String[] args) {FileOutputStream fos = null;FileInputStream fis = null;try{fos = new FileOutputStream("c:\\2.bmp");fis = new FileInputStream("c:\\1.bmp");byte[] buf = new byte[1024];int len = 0;while((len=fis.read(buf))!=-1){fos.write(buf,0,len);}}catch (IOException e){throw new RuntimeException("复制文件失败");}finally{try{if(fis!=null)fis.close();}catch (IOException e){throw new RuntimeException("读取关闭失败");}try{if(fos!=null)fos.close();}catch (IOException e){throw new RuntimeException("写入关闭失败");}}}}


BufferInputStream与BufferOutputStream的例子,复制mp3

import java.io.*;//read与write的区别//read返回的是int而不是byte,避免了-1的发生,write再将最低一个字节写出去,保证了原数据的原样性class CopyMp3ByBuf {public static void main(String[] args) throws IOException{long start = System.currentTimeMillis();copy_2();//copy_1();long end = System.currentTimeMillis();System.out.println((end-start)+"毫秒");}         //定义自己的缓冲区public static void copy_2()throws IOException{MyBufferedInputStream bufis = new MyBufferedInputStream(new FileInputStream("c:\\2.mp3"));BufferedOutputStream bufos = new BufferedOutputStream(new FileOutputStream("d:\\3.mp3"));int by = 0;while((by=bufis.myRead())!=-1){bufos.write(by);}bufos.close();bufis.myClose();}//通过字节流的缓冲区完成复制public static void copy_1()throws IOException{BufferedInputStream bufis = new BufferedInputStream(new FileInputStream("c:\\2.mp3"));BufferedOutputStream bufos = new BufferedOutputStream(new FileOutputStream("d:\\3.mp3"));int by = 0;while((by=bufis.read())!=-1){bufos.write(by);}bufos.close();bufis.close();}}


 

字符流

**写入流:

(1)FileWriter:

  **构造方法:

FileWriter(String fileName) 

                 根据给定的文件名构造一个 FileWriter 对象。 

FileWriter(String fileName, boolean append) 

                 根据给定的文件名以及指示是否附加写入数据的 boolean 值来构造 FileWriter 对象。 

FileWriter(File file) 

                 根据给定的 File 对象构造一个 FileWriter 对象。 

FileWriter(File file, boolean append) 

                根据给定的 File 对象构造一个 FileWriter 对象。 

FileWriter(FileDescriptor fd) 

              构造与某个文件描述符相关联的 FileWriter 对象。

  **方法摘要:跟Writer一样

abstract  void close() 关闭此流,但要先刷新它。

abstract  void flush() 刷新该流的缓冲。

void write(int c) 写入单个字符。

void write(char[] cbuf) 写入字符数组。          

abstract  void write(char[] cbuf, int off, int len) 写入字符数组的某一部分。 

void write(String str) 写入字符串。 

void write(String str, int off, int len) 写入字符串的某一部分。 

import java.io.*;//在硬盘上创建一个文件并写入一些文字数据class FileWriterDemo {public static void main(String[] args) throws IOException{//创建一个FileWriter对象,该对象一被初始化就必须要明确被操作的文件//而且该文件会被创建到指定的目录下。如果该目录下已有同名文件,将被覆盖//其实该步骤就是在明确数据要存放的目的地FileWriter fw = new FileWriter("d:\\demo.txt");//调用writer方法,将字符串写入到流中fw.write("abcdef");//刷新流对象中的缓冲中的数据,将数据刷新到目的地中。//fw.flush();//关闭流资源,但是关闭之前会刷新一次内部的缓冲中的数据,将数据刷到目的地中。//和flush区别:flush刷新后,流就可以继续使用。close刷新后,会将流关闭fw.close();}} 


(2)BufferedWriter:(有一个newLine方法,自动换行)

**构造方法:

BufferedWriter(Writer out) 

          创建一个使用默认大小输出缓冲区的缓冲字符输出流。 

BufferedWriter(Writer out, int sz) 

          创建一个使用给定大小输出缓冲区的新缓冲字符输出流。 

**方法摘要:

void close() 

         关闭此流,但要先刷新它。 

void flush() 

        刷新该流的缓冲。 

void newLine() 

        写入一个行分隔符。 自动换行

void write(char[] cbuf, int off, int len) 

        写入字符数组的某一部分。 

void write(int c) 

       写入单个字符。 

void write(String s, int off, int len) 

       写入字符串的某一部分。 

import java.io.*;class BufferedWriterDemo {public static void main(String[] args) throws IOException{//创建一个字符写入流对象FileWriter fw = new FileWriter("buf.txt");//为了提高写入流效率,加入了缓冲技术//只要将需要被提高的流对象作为参数传递给缓冲区的构造函数即可BufferedWriter bufw = new BufferedWriter(fw);for(int x=1;x<5;x++){bufw.write("abcd"+x);//将字符串写入到流中bufw.newLine();//自动换行bufw.flush();//刷新流对象中的缓冲中的数据,将数据刷新到目的地//只要用到缓冲区,就要刷新}bufw.close();//其实关闭缓冲区,就是在关闭缓冲区中的流对象}}


 

(3)OutputStreamWriter:字节通向字符的转换流

**构造方法:

OutputStreamWriter(OutputStream out) 

        创建使用默认字符编码的 OutputStreamWriter

**方法摘要:

void write(char[] cbuf, int off, int len) 

          写入字符数组的某一部分。 

void write(int c) 

         写入单个字符。 

void write(String str, int off, int len) 

         写入字符串的某一部分。

(4)PrintWriter:

**构造方法:

PrintWriter(String fileName) 

            创建具有指定文件名称且不带自动行刷新的新 PrintWriter

PrintWriter(File file) 

            使用指定文件创建不具有自动行刷新的新 PrintWriter

PrintWriter(Writer out) 

            创建不带自动行刷新的新 PrintWriter。 

PrintWriter(Writer out, boolean autoFlush) 

            创建新 PrintWriter。 

PrintWriter(OutputStream out) 

            根据现有的 OutputStream 创建不带自动行刷新的新 PrintWriter。 

PrintWriter(OutputStream out, boolean autoFlush) 

          通过现有的 OutputStream 创建新的 PrintWriter

**方法摘要:

PrintWriter append(char c) 

           将指定字符添加到此 writer。 

void print(各种类型的数据:

           打印各种类型的数据 

void println(各种类型的数据:):自动换行

          打印各种类型的数据

void write(char[] buf) 

          写入字符数组。 

void write(char[] buf, int off, int len) 

         写入字符数组的某一部分。 

void write(int c) 

         写入单个字符。 

void write(String s) 

        写入字符串。 

void write(String s, int off, int len) 

       写入字符串的某一部分。

**读取流:

(1)FileReader:

**构造方法:

FileReader(String fileName) 

              在给定从中读取数据的文件名的情况下创建一个新 FileReader

FileReader(File file) 

             在给定从中读取数据的 File 的情况下创建一个新 FileReader。 

FileReader(FileDescriptor fd) 

             在给定从中读取数据的 FileDescriptor 的情况下创建一个新 FileReader。 

**方法摘要:和Reader基类方法一致:

abstract  void close() 关闭该流并释放与之关联的所有资源。

int read() 读取单个字符。

int read(char[] cbuf)  将字符读入数组

abstract  int read(char[] cbuf, int off, int len) 将字符读入数组的某一部分。

long skip(long n)  跳过字符。 

import java.io.*;class FileReaderDemo {public static void main(String[] args) throws IOException{FileReader fr = new FileReader("demo.txt");//定义一个字符数组,用于存储读到的字符//该read(char[])返回的是读到字符个数char[] buf = new char[1024];int len = 0;while((len=fr.read(buf))!=-1){System.out.println(new String(buf,0,len));}fr.close();}}


(2)BufferedReader:(有特有方法readLine(),注意与BufferInputStream的read()方法进行区别)

**构造方法:

BufferedReader(Reader in) 

创建一个使用默认大小输入缓冲区的缓冲字符输入流。

**方法摘要:

int read() 

         读取单个字符。 

int read(char[] cbuf, int off, int len) 

         将字符读入数组的某一部分。 

String readLine() 

         读取一个文本行。 包含该行内容的字符串,不包含任何行终止符,如果已到达流末尾,则返回 null 

import java.io.*;class  BufferedReaderDemo{public static void main(String[] args) throws IOException{//创建一个读取流对象和文件相关联FileReader fr = new FileReader("buf.txt");//为了提高写入流效率,加入了缓冲技术//将需要被提高的流对象作为参数传递给缓冲区的构造函数BufferedReader bufr = new BufferedReader(fr);String bufline = null;while((bufline=bufr.readLine())!=null){System.out.println(bufline);}bufr.close();}}


(3)MyBufferedReader:

 
/*明白了BufferedReader类中特有方法readLine的原理后,可以自定义一个类中包含一个功能和readLine一致的方法。来模拟一下BufferedReader*/import java.io.*;class MyBufferedReader extends Reader{private Reader r;MyBufferedReader(Reader r){this.r = r;}//可以一次读一行数据的方法。public String myReadLine()throws IOException{//定义一个临时容器。原BufferReader封装的是字符数组。//为了演示方便。定义一个StringBuilder容器。因为最终还是要将数据变成字符串。StringBuilder sb = new StringBuilder();int ch = 0;while((ch=r.read())!=-1){if(ch=='\r')continue;if(ch=='\n')return sb.toString();elsesb.append((char)ch);}if(sb.length()!=0)return sb.toString();return null;}/*覆盖Reader类中的抽象方法。*/public int read(char[] cbuf, int off, int len) throws IOException{return r.read(cbuf,off,len) ;}public void close()throws IOException{r.close();}public void myClose()throws IOException{r.close();}}class  MyBufferedReaderDemo{public static void main(String[] args) throws IOException{FileReader fr = new FileReader("buf.txt");MyBufferedReader myBuf = new MyBufferedReader(fr);String line = null;while((line=myBuf.myReadLine())!=null){System.out.println(line);}myBuf.myClose();}}


(4)LineNumberReader:(跟踪行号的缓冲字符输入流)

**构造方法:

LineNumberReader(Reader in) 

            使用默认输入缓冲区的大小创建新的行编号 reader

**方法摘要:

int read() 

          读取单个字符。 

int read(char[] cbuf, int off, int len) 

          将字符读入数组中的某一部分。 

String readLine() 

           读取文本行。

long skip(long n) 

           跳过字符。 

int getLineNumber() 

          获得当前行号。 

void setLineNumber(int lineNumber) 

          设置当前行号。 

(5)MyLineNumberReader

package com.itheima;import java.io.FileReader;import java.io.IOException;import java.io.Reader;/*** 第七题:自定义字符输入流的包装类,通过这个包装类对底层字符输入流进行包装,让程序通过这个包装类读取某个文本文件*       (例如,一个java源文件)时,能够在读取的每行前面都加上行号和冒号。* @author wangzhi *//*//将MyLineNumberReader代码优化,要继承MyBufferedReaderclass MyLineNumberReader extends MyBufferedReader{private int lineNumber;MyLineNumberReader(Reader r){super(r);}public String myReadLine() throws IOException{lineNumber++;return super.myReadLine();}public void setLineNumber(int lineNumber){this.lineNumber = lineNumber;}public int getLineNumber(){return lineNumber;}}*///自定义一个字符输入流的包装类class MyLineNumberReader {private int lineNumber;//包装一个私有的行号lineNumberprivate Reader r;//包装一个reader//在构造函数中将被包装的对象传递进来MyLineNumberReader(Reader r){this.r = r;}//对外提供一个myReadLine方法public String myReadLine() throws IOException{lineNumber++;//在调用myReadLine方法的时候行号自增StringBuilder sb =new StringBuilder();//定义一个容器int ch = 0;//定义一个整形的变量//循环读取while((ch=r.read())!=-1){if(ch=='\r')//如果读到\r继续读,不存储continue;if(ch=='\n')//如果读到\n返回容器toStringreturn sb.toString();elsesb.append((char)ch);//将独到的数据存到容器中}if(sb.length()!=0)//如果容器里有数据,返回容器return sb.toString();return null;}//定义一个设置行号的方法setLineNumberpublic void setLineNumber(int lineNumber){this.lineNumber = lineNumber;}//定义一个获取行号的方法getLineNumberpublic int getLineNumber(){return lineNumber;}//对外提供一个myClose方法public void myClose() throws IOException{r.close();//关闭流}}class MyLineNumberReaderDemo {public static void main(String[] args) throws IOException{//关联一个文件CopyTextByBuf.javaFileReader fr = new FileReader("CopyTextByBuf.java");//最好是绝对路径//定义一个跟踪行号的缓冲字符输入流MyLineNumberReader mylnr = new MyLineNumberReader(fr);String line = null;//定义一个字符串mylnr.setLineNumber(100);//设置行号从100开始//循环读取while((line=mylnr.myReadLine())!=null){//打印出行号需要调用getLineNumber方法System.out.println(mylnr.getLineNumber()+"::"+line);}mylnr.myClose();//关流}}

(6)InputStreamReader:字符通向字节的桥梁:

**构造方法:

InputStreamReader(InputStream in) 

         创建一个使用默认字符集的 InputStreamReader

**方法摘要:

int read() 读取单个字符。

int read(char[] cbuf)  将字符读入数组

abstract  int read(char[] cbuf, int off, int len) 将字符读入数组的某一部分。

long skip(long n)  跳过字符。



 FileReader与FileWriter的例子,将c盘文件复制到d盘

//将C盘一个文本文件复制到D盘。/*复制的原理:其实就是将C盘下的文件数据存储到D盘的一个文件中。步骤:1,在D盘创建一个文件。用于存储C盘文件中的数据。2,定义读取流和C盘文件关联。3,通过不断的读写完成数据存储。4,关闭资源。*/import java.io.*;class CopyText {public static void main(String[] args) throws IOException{copy_2();}public static void copy_2(){FileWriter fw = null;FileReader fr = null;try{fw = new FileWriter("SystemDemo_copy.txt");fr = new FileReader("SystemDemo.java");char[] buf = new char[1024];int len = 0;while((len=fr.read(buf))!=-1){fw.write(buf,0,len);}}catch (IOException e){throw new RuntimeException("读写失败");}finally{if(fr!=null)try{fr.close();}catch (IOException e){}if(fw!=null)try{fw.close();}catch (IOException e){}}}//从C盘读一个字符,就往D盘写一个字符。public static void copy_1()throws IOException{//创建目的地。FileWriter fw = new FileWriter("RuntimeDemo_copy.txt");//与已有文件关联。FileReader fr = new FileReader("RuntimeDemo.java");int ch = 0;while((ch=fr.read())!=-1){fw.write(ch);}fw.close();fr.close();}}


 

BufferReader与BufferWriter的例子,复制一个.java文件

import java.io.*;class CopyTextByBuf {public static void main(String[] args) {BufferedReader bufr = null;BufferedWriter bufw = null;try{bufr = new BufferedReader(new FileReader("BufferedWriterDemo.java"));bufw = new BufferedWriter(new FileWriter("BufWriter_Copy.txt"));String line = null;//两流之间的中转站while((line=bufr.readLine())!=null){bufw.write(line);bufw.newLine();bufw.flush();}}catch (IOException e){throw new RuntimeException("读写失败");}finally{try{if(bufr!=null)bufr.close();}catch (IOException e){throw new RuntimeException("读取关闭失败");}try{if(bufw!=null)bufw.close();}catch (IOException e){throw new RuntimeException("写入关闭失败");}}}}

 

InputStreamReader与OutputStreamWriter的例子

import java.io.*;class TransStreamDemo {public static void main(String[] args) throws IOException{System.setIn(new FileInputStream("TransStreamDemo.java"));//重新分配“标准”输入流。将源(键盘录入)改为一个文件//System.setOut(new PrintStream("zz.txt"));//重新分配“标准”输出流。将目的地改为一个文件//PrintStream是一个打印流对象/*读取转换流//获取键盘录入对象InputStream in = System.in;//将字节流对象转换成字符流对象,使用转读取换流InputStreamReaderInputStreamReader isr = new InputStreamReader(in);//为了提高效率,将字符串进行缓冲区技术高效操作,使用BufferedReaderBufferedReader bufr = new BufferedReader(isr);*/BufferedReader bufr = new BufferedReader(new InputStreamReader(System.in));//源,键盘录入//BufferedReader bufr = new BufferedReader(new InputStreamReader(new FileInputStream("CopyPic.java")));//源,文件/*写入转换流OutputStream out = System.out;OutputStreamWriter osw = new OutputStreamWriter(out);BufferedWriter bufw = new BufferedWriter(osw);*/BufferedWriter bufw = new BufferedWriter(new OutputStreamWriter(System.out));//目的,控制台//BufferedWriter bufw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream("out.txt")));//目的,文件String line = null;while((line=bufr.readLine())!=null){if("over".equals(line))break;//System.out.println(line.toUpperCase());//有了写入转换流就不用这样写了bufw.write(line.toUpperCase());//字符流当然可以直接操作字符串bufw.newLine();bufw.flush();}bufr.close();}}



 

4,IO流常见需求:

****字符流:

(1)需求1:在硬盘上创建一个文件并写入信息

用字符写入流:FileWriter

FileWriter fw = new FileWriter("g:\\filewriter.txt");

fw.write("输入信息");

fw.write("也可以写入字符数组".toCharArray());

fw.flush();

fw.close();


(2)需求2:在原有文件上续写数据

FileWriter fw = new FileWriter("g:\\filewriter.txt",true);

fw.write("还可以续写信息");

fw.write("也可以写入字符数组".toCharArray());

fw.flush();

fw.close();


(3)需求3:读取硬盘上的文本文件,并将数据打印在控制台

FileReader fr = new FileReader("g:\\filewriter.txt");

**第一种读取方法:一个一个字节的读

int ch = 0;

ch = fr.read();

sop((char)ch);

fr.close();

**第二种读取方法:利用数组来提高效率

char[] buf = new char[1024];

int len = 0;

while((len = fr.read(buf))!=-1)

{

        sop(new String(buf,0,len));

}

fr.close();


(4)需求4:拷贝文本文件

利用缓冲区提高数据读写效率

(无缓冲区就相当于一滴一滴的喝水,有缓冲区就相当于一杯一杯的喝水)

BufferedReader bufr = new BufferedReader(new FileReader("g:\\filewriter.txt"));

BufferedWriter bufw = new BufferedWriter(new FileWriter("d:\\copyfilewriter.txt"));

String line = null;

while((line = bufr.readLine())!=null)

{

           burw.write(line);

           bufw.newLine();

           bufw.flush();

}

bufr.close();

bufw.close();

 

****字节流


(1)需求1:在硬盘上创建一个文件并写入信息(字节流写入时没有刷新)

FileOutputStream fos = new FileOutputStream("g:\\filestream.txt");

fos.write(97);//写入一个字节,int97代表写入chara

fos.write("也可以写入字节数组".getBytes());//通常使用此种方式写入,直观!

fos.close();


(2)需求2:在硬盘已有文件上续写数据(字节流写入时没有刷新)

FileOutputStream fos = new FileOutputStream("g:\\filestream.txt",true);

fos.write("创建字节写入流时,传进去一个true参数就可以继续写入信息".getBytes());

fos.close();


(3)需求3:读取硬盘上的文件

FileInputStream fis = new FileInputStream("g:\\filestream.txt");

**第一种读法:一个字节一个字节的读(此种读法慢)

int ch = 0;

while((ch = fis.read())!=-1)

{

       sop((char)ch);

}

**二种读法:利用字节数组读(此种读法效率有一定提高)

byte[] buf = new byte[1024];

int len = 0;

while((len = fis.read())!=-1)

{

sop(new String(buf,0,len));

}


(4)需求4:拷贝字节文件,如图片或者MP3或者电影

**第一种拷贝:不带缓冲区(慢,还是效率问题)

FileInputStream fis = new FileInputStream("g:\\1.mp3");

FileOutputStream fos = new FileOutputStream("g:\\copy1.mp3");

byte[] buf = new byte[1024];

int len = 0;

while((len = fis.read(buf))!=-1)

{

         fos.(buf,0,len);

}

fis.close();

fos.close();


**第二种拷贝:带缓冲区,高效

BufferedInputStream bufi = new BufferedInputStream(new FileInputStream("g:\\1.mp3"));

BufferedOutputStream bufo = new BufferedOutputStream(new FileOutputStream("g:\\copy1.mp3"));

int ch = 0;

while((ch = bufi.read())!=-1)

{

           bufo.write(ch);//字节流写入无需刷新

}

bufi.close();

bufo.close();

 

****转换流:

(1)需求1:读取一个键盘录入

InputStream in = System.in;//创建一个键盘录入流,流不关则可以一直录入

int by1 = in.read();//一次读一个字节

int by2 = in.read();//一次读一个字节

sop(by1);//假设键盘录入的是abcd,则打印a

sop(by2);//假设键盘录入的是abcd,则打印b

in.close();


(2)需求2:键盘录入一行数据打印一行数据,如果录入的是over则结束录入

InputStream in = System.in;StringBuilder sb = new StringBuilder();while(true){int ch = in.read();if(ch=='\r')continue;if(ch=='\n'){String line = sb.toString();if("over".equals(line))break;sop(line.toUpperCase());//输出大写sb.delete(0.sb.length());//清除上一行录入的数据}elsesb.append((char)ch);}in.close();

(3)需求3:发现需求2中其实就是读一行的原理,故引入字节通向字符的桥梁:InputStreamReader

为提高效率加入缓冲区:BufferedReader bufr = new BufferedReader(new InputStreamReader(System.in));String line = null;while((line = bufr.readLine())!=null){if("over".equals(line))break;sop(line.toUpperCase());//输出大写}bufr.close();

(4)需求4:键盘录入数据并打印到控制台

BufferedReader bufr = new BufferedReader(new InputStreamReader(System.in));BufferedWriter bufw = new BufferedWriter(new OntputStreamWriter(System.out));String line = null;while((line = bufr.readLine())!=null){if("over".equals(line))break;bufw.write(line.toUpperCase());bufw.newLine();bufw.flush();}bufr.close();bufw.close();


(5)需求5:将键盘录入的数据存储到硬盘文件

则只需将(4)中的BufferedWriter bufw = new BufferedWriter(new OntputStreamWriter(System.out));改为:BufferedWriter bufw = new BufferedWriter(new OntputStreamWriter(new FileWriter("g:\\demo.txt")));即:BufferedReader bufr = new BufferedReader(new InputStreamReader(System.in));BufferedWriter bufw = new BufferedWriter(new OntputStreamWriter(new FileWriter("g:\\demo.txt")));String line = null;while((line = bufr.readLine())!=null){if("over".equals(line))break;bufw.write(line.toUpperCase());bufw.newLine();bufw.flush();}bufr.close();bufw.close();

(6)需求6:将硬盘文件的数据打印到控制台

则只需将(4)中的BufferedReader bufr = new BufferedReader(new InputStreamReader(System.in));改为:BufferedReader bufr = new BufferedReader(new InputStreamReader(new FileReader("g:\\demo.txt")));即:BufferedReader bufr = new BufferedReader(new InputStreamReader(new FileReader("g:\\demo.txt")));BufferedWriter bufw = new BufferedWriter(new OntputStreamWriter(System.out));String line = null;while((line = bufr.readLine())!=null){if("over".equals(line))break;bufw.write(line.toUpperCase());bufw.newLine();bufw.flush();}bufr.close();bufw.close();



5、流操作的规律:


****流操作的难点:流对象很多,不知道具体用哪个

****规律:

(1)第一步:先明确源和目的

源:

文本:用Reader

字节:用InputStream

目的:

文本:用Writer

字节:用OutputStream

(2)第二步:明确是不是纯文本

是:用字符流;

不是:用字节流

(3)第三步:明确流体系后,通过设备来明确具体使用哪个流对象

源设备:

键盘:System.in

硬盘:文件流File

内存:数组流ArrayStream

目的设备:

键盘:System.out

硬盘:文件流File

内存:数组流ArrayStream 



 6、一道综合练习题

package com.itheima;/** * 第二题: 有五个学生,每个学生有3门课(语文、数学、英语)的成绩,写一个程序接收从键盘输入学生的信息, *   输入格式为:name,30,30,30(姓名,三门课成绩),然后把输入的学生信息按总分从高到低的顺序写入到一个名称"stu.txt"文件中。 *        要求:stu.txt文件的格式要比较直观,打开这个文件,就可以很清楚的看到学生的信息。 * @author wangzhi *  *  * 这个题我用两种方法做 *///方法一import java.io.*;import java.util.*;/* 步骤:1,描述学生对象2,定义一个可操作学生对象的工具类 思想:1,通过获取键盘录入一行数据,并将该行中的信息取出封装成学生对象。2,因为学生有很多,那么就需要存储,使用到集合。因为要对学生的总分排序。所以可以使用TreeSet。3,将集合的信息写入到一个文件中。*/class Test2 {public static void main(String[] args) throws IOException{//输出的是倒序,由于compareTo方法已经写死,只能在主方法中强行逆转比较器,于是就自定义一个比较器Comparator<Student> cmp = Collections.reverseOrder();//reverseOrder()反转比较器//用学生信息工具类调用getStudents方法,因为是静态方法,可以直接调用,返回一个Set集合Set<Student> stus = StudentInfoTool.getStudents(cmp);//用学生信息工具类调用writeToFile方法,因为是静态方法,可以直接调用StudentInfoTool.writeToFile(stus);}}//描述学生对象。TreeSet第一种排序方式让元素自身具备比较性,实现Compareble接口,//覆盖compareTo方法,此方式是元素的自然顺序 class Student implements Comparable<Student>{private String name;private int ma,cn,en;private int sum;//构造函数,初始化学生对象(学生一初始化就都有了)Student(String name,int cn,int ma,int en){this.name = name;this.cn = cn;this.ma = ma;this.en = en;sum = cn + ma + en;}//覆盖compareTo方法public int compareTo(Student s){//先比总分int num = new Integer(this.sum).compareTo(new Integer(s.sum));if(num==0)return this.name.compareTo(s.name);//如果总分相等,则比较姓名return num;//如果总分不相等,则比较总分}public String getName(){return name;}public int getSum(){return sum;}//覆盖hashCode方法public int hashCode(){return name.hashCode()+sum*78;}//重写equals方法public boolean equals(Object obj){if(!(obj instanceof Student))//如果obj不是学生throw new ClassCastException("类型不匹配");Student s = (Student)obj;//将Object强转为Student//如果是学生的话,则用姓名和总分比,compareTo中线比较总分return this.name.equals(s.name) && this.sum==s.sum;}//为了打印效果,有必要覆盖toString方法public String toString(){return "student["+name+", "+ma+", "+cn+", "+en+"]";}}//定义一个可操作学生的工具类class StudentInfoTool{//定义一个按照自然顺序比较的方法public static Set<Student> getStudents()throws IOException{return getStudents(null);//调用getStudents方法,不需要比较器,则往里面传入null}//定义一个静态方法(将泛型定义在方法上),这个方法是按指定比较器的比较顺序来比较public static Set<Student> getStudents(Comparator<Student> cmp)throws IOException{//通过获取键盘录入一行数据,并将该行中的信息取出封装成学生对象。BufferedReader bufr = new BufferedReader(new InputStreamReader(System.in));//定义一个字符串String line = null;//创建一个set集合,将数据存储起来,内部进行了排序Set<Student> stus  = null;//如果比较器中没有数据,就按自然顺序比较,否则按指定比较器的顺序排序if(cmp==null)stus = new TreeSet<Student>();elsestus = new TreeSet<Student>(cmp);//循环读while((line=bufr.readLine())!=null){//如果输入over则结束if("over".equals(line))break;String[] info = line.split(",");//用逗号把数据隔开//将info封装成学生对象,将各成绩都转换成整数Student stu = new Student(info[0],Integer.parseInt(info[1]),Integer.parseInt(info[2]),Integer.parseInt(info[3]));stus.add(stu);//将字符串数组添加到集合中}bufr.close();return stus;}public static void writeToFile(Set<Student> stus)throws IOException{//创建一个文件用来存放数据BufferedWriter bufw = new BufferedWriter(new FileWriter("stuinfo.txt"));//遍历集合for(Student stu : stus){bufw.write(stu.toString()+"\t");//将学生的姓名和各成绩写出去,然后换行//bufw.write(stu.getName());//将学生的姓名写到文件,这样也可以,只是没有用toString罢了bufw.write(stu.getSum()+"");//将学生的总分写到文件。后面加“”是为了不乱码,输出整数,因为stu.getSum写在了最后8位bufw.newLine();//换行一次bufw.flush();//字符流缓冲区需要刷新}bufw.close();}}


//方法二://但是没有排序import java.io.BufferedWriter;import java.io.FileWriter;import java.io.IOException;import java.io.PrintWriter;import java.util.Scanner; class Test2 {public static void main(String[] args) {//创建一个数组Student[] stu = new Student[5]; for (int i = 0; i < stu.length; i++) {System.out.println("请输入姓名"); Scanner s2 = new Scanner(System.in); String name = s2.next();System.out.println("请输入数学成绩"); Scanner sc1 = new Scanner(System.in); double c1 = sc1.nextDouble();System.out.println("请输入英语成绩"); Scanner sc2 = new Scanner(System.in); double c2 = sc2.nextDouble();System.out.println("请输入语文成绩"); Scanner sc3 = new Scanner(System.in); double c3 = sc3.nextDouble(); stu[i] = new Student(name,new Course(c1,c2,c3)); Test2 t = new Test2(); t.doIO(stu[i]); }} public void doIO(Student stu){PrintWriter out = null; try {//创建一个文件用于存放数据out = new PrintWriter(new BufferedWriter(new FileWriter("stu.txt",true)));out.println(stu.getName()+" 数学:"+stu.getC().getMathematics()+" 英语:"+stu.getC().getEnglish()+" 语文:"+stu.getC().getChinaLanguage()+" 总分:"+((stu.getC().getMathematics()+stu.getC().getEnglish()+stu.getC().getChinaLanguage())));} catch (IOException e) { e.printStackTrace(); } finally{ try{ out.close(); }catch (Exception e) { e.printStackTrace();}} }}//Course类:class Course {private double mathematics;//数学成绩private double english;//英语成绩private double chinaLanguage;//语文成绩public double getMathematics() { return mathematics;}public void setMathematics(double mathematics) { this.mathematics = mathematics;}public double getEnglish() { return english;} public void setEnglish(double english) { this.english = english;}public double getChinaLanguage() { return chinaLanguage;}public void setJavaLanguage(double chinaLanguage) { this.chinaLanguage = chinaLanguage;}public Course(double mathematics, double english, double chinaLanguage) { super(); this.mathematics = mathematics; this.english = english; this.chinaLanguage = chinaLanguage;}public Course() { super(); }}//Student类:class Student {private String name;// 学生姓名 private Course c;// 学生课程分数public String getName() { return name;}public void setName(String name) { this.name = name;}public Course getC() { return c;}public void setC(Course c) { this.c = c;}public Student(String name, Course c) { super();  this.name = name; this.c = c;}public Student() { super();}}




------- android培训java培训、期待与您交流! ----------

原创粉丝点击