我们之前所做的都是对文件进行IO处理,实则我们也可以对内存进行IO处理。我们将发生在内存中的IO处理称为内存流。
内存操作流也可分为两类:字节内存流和字符内存流。
(1)ByteArrayInputStream 和 ByteArrayOutputStream
构造函数:
public class ByteArrayOutputStream extends OutputStream
public class ByteArrayInputStream extends InputStream
(2)CharArrayInputStream 和 CharArrayOutputStream
构造函数:
public class CharArrayWriter extends Writer
public class CharArrayReader extends Reader
由此我们可以得出内存流的继承关系:
利用内存流实现大小写转换:
package myIO; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; /*通过内存流实现大小写转换 * */ public class Test3 { public static void main(String[] args) throws IOException { String string = "hello world,hello lemon"; //实例化InputStream对象,进行实例化时应将需要操作的数据保存在内存中,读取的将是设置的内容 InputStream inputStream = new ByteArrayInputStream(string.getBytes()); //实例化OutputStream对象 OutputStream outputStream = new ByteArrayOutputStream(); int temp= 0; //判断是否读完 while((temp = inputStream.read())!=-1) { //对每个字节进行处理,处理之后存在于OutputStream类中 //进行大小写转换 outputStream.write(Character.toUpperCase(temp)); } //直接对outputStream对象进行输出 System.out.println(outputStream); //关闭流 inputStream.close(); outputStream.close(); } }
(2)内存流的操作
内存流有个很小的功能就是实现两个文件的合并操作(对很小的文件而言)。
内存流最核心的就是:将所有OutputStream输出的程序保存在了程序中,所以可以利用这一特征来进行处理。
/* * 实现两个文件的合并处理 * */ public class Test3{ public static void main(String[] args) throws IOException { String singal = File.separator; //指明要合并两个文件的地址 File[] files = new File[] { new File("C:"+singal+"Users"+singal+"lenovo"+singal+"Desktop"+singal+"Test1.txt") ,new File("C:"+singal+"Users"+singal+"lenovo"+singal+"Desktop"+singal+"Test2.txt")}; String[] data = new String[2]; for(int i = 0 ;i <files.length;i++) { data[i] = readFile(files[i]); } StringBuffer stringBuffer = new StringBuffer(); String contentA [] = data[0].split(" ") ; String contentB [] = data[1].split(" ") ; for (int i = 0; i < contentA.length ; i++) { stringBuffer.append(contentA[i]).append("(").append(contentB[i]).append(")").append(" ") ; } System.out.println(stringBuffer); } //读取文件内容,使用File对象因为其包含完整的路径信息 public static String readFile(File file) throws IOException { if(file.exists()) { InputStream inputStream = new FileInputStream(file); //没有向上转型,因为后续要使用toByteArray()方法 ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); int temp = 0; byte[] data = new byte[10]; while((temp = inputStream.read(data))!=-1) { //将数据保存在byteArrayOutputStream byteArrayOutputStream.write(data,0,temp); } byteArrayOutputStream.close(); inputStream.close(); return new String(byteArrayOutputStream.toByteArray()); } return null; } }
2、打印流
打印流的本质是解决OutputStream的缺陷,因为若想将非二进制的数据通过程序向终端目标直接输出信息的话,OutputStream有如下缺陷:所有的数据都要转换成字节数组,若要输出int、double更是不方便。
(1)进行简单打印流的设计
/* * 设计简单打印流 * */ class PrintDesign{ private OutputStream outputStream; //构造函数 //有外部传入要输出的目的终端 public PrintDesign(OutputStream outputStream) { super(); this.outputStream = outputStream; } //实现输出的功能(传入参数为字符串) public void print(String string) throws IOException { this.outputStream.write(string.getBytes()); } //实现换行功能 public void println(String string) throws IOException { this.print(string+"\r\n"); } //传入参数为int public void print(int data) throws IOException { this.print(String.valueOf(data)); } public void println(int data) throws IOException { this.print(String.valueOf(data)+"\r\n"); } } public class Test3{ public static void main(String[] args) throws IOException { String singal = File.separator; PrintDesign printDesign = new PrintDesign(new FileOutputStream( new File("C:"+singal+"Users"+singal+"lenovo"+singal+"Desktop"+singal+"Test1.txt"))); printDesign.println("姓名:"); printDesign.print("lemon"); printDesign.println("年龄:"); printDesign.print(20); } }
我们可以发现经过简单的处理使得OutputStream的功能变得更加强大了,其实我们所做的工作只不过是对OutputStream做了一个封装而已。实则java中提供有专门的打印流处理类:字节打印流rintStream、字符打印流PrintWriter.
(2)认识打印流处理类
字节打印流:public class PrintStream extends FilterOutputStream
构造函数:public PrintStream(OutputStream out)
字符打印流:public class PrintWriter extends Writer
构造函数:public PrintWriter(OutputStream out)
public PrintWriter (Writer out)
打印流的设计模式属于装饰者设计模式:核心是某个类的功能,但是为了得到更好的操作效果,让其支持的功能更多一些。
(3)打印流的使用
在后续的应用中字符打印流(PrintWriter)引用比较对,因为它可以接收Writer和OutputStream两种类型的参数;而字节打印流(PrintStream)只可接收OutputStream类型的参数。
/* * 字符打印流的使用 * */ public class Test3{ public static void main(String[] args) throws FileNotFoundException { String singal = File.separator; PrintWriter printWriter = new PrintWriter( new File("C:"+singal+"Users"+singal+"lenovo"+singal+"Desktop"+singal+"Test1.txt")); printWriter.print("班级:"); printWriter.println("数学152"); printWriter.println("年龄:"); printWriter.println(20); printWriter.close(); } }
(4)格式化输出
我们在C语言遇到一个printf()函数,这个函数在输出的时候可以使用一些占位符,例如:字符串(%s)、数字(%d)、小数 (%f)、字符(%c)等。从JDK1.5开始,PrintStream类中也追加了此种操作。
格式化输出:public PrintStream printf(String format, Object ... args)
/* * 格式化输出 * */ public class Test3{ public static void main(String[] args) throws FileNotFoundException { String name = "lemon"; int age = 20; double salary = 10.3; String singal = File.separator; PrintStream printStream = new PrintStream(new FileOutputStream( new File("C:"+singal+"Users"+singal+"lenovo"+singal+"Desktop"+singal+"Test2.txt"))); printStream.printf("姓名:%s,年龄:%d,工资:%f",name,age,salary); printStream.close(); } }