1.内存操作流
之前学习的IO操作输入和输出都是从文件中来的,当然,也可以将输入和输出的位置设置在内存上,这就需要用到内存操作流,java提供两类内存操作流
- 字节内存操作流:ByteArrayOutputStream:将内存中数据输出 ByteArrayInputStream:将内容写入到内存中
- 字符内存操作流:CharArrayWriter CharArrayReader
使用场景:
假设现在需要实现IO操作,又不希望产生文件,则就可以以内存为终端进行处理,这个时候的流程
与文件IO不同,InputStream是往内存里写,OutputStream是读内存。
ByteArrayOutputStream类的定义:
public class ByteArrayOutputStream extends OutputStream
主要方法:
ByteArrayInputStream类的定义:
public class ByteArrayInputStream extends InputStream
代码实例:利用内存操作流实现一个小写字母转大写字母的操作
import java.io.*; public class ByteArrayStreamDemo { public static void main(String[] args) throws Exception { // TODO Auto-generated method stub String str = "i believe i can fly"; ByteArrayOutputStream output = new ByteArrayOutputStream(); InputStream input = new ByteArrayInputStream(str.getBytes()); int data = 0; while((data = input.read()) != -1) { output.write(Character.toUpperCase(data)); } byte res[] = output.toByteArray(); System.out.println(new String(res)); input.close(); output.close(); } }
2.管道流
管道流主要作用是实现两个线程之间的IO处理操作,java中提供两类管道流
- 字节管道流:PipedInputStream(管道输入流) PipedOutputStream(管道输出流)
- 字符管道流:PipedReader PipedWriter
如果想要进行管道输出,则必须把输出流连在输入流之上,在PipeOutputStream上有如下方法用于连接管道。
public void connect(PipedInputStream src) throws IOException
在PipedReader上有如下方法用于连接管道。
public void connect(PipedWriter snk) throws IOException
PipedOutputStream类的定义:
public class PipedOutputStream extends OutputStream
构造方法:
public PipedOutputStream()
主要方法:
public void write(int b) throws IOException//输出方法
PipedInputStream类的定义:
public class PipedInputStream extends InputStream
构造方法:
public PipedInputStream()
主要方法:
public int read() throws IOException//输入方法
代码实例:
import java.io.*; public class PipedDemo { public static void main(String[] args) throws IOException { // TODO Auto-generated method stub SendThread send = new SendThread(); RecieveThread recieve = new RecieveThread(); send.getOutput().connect(recieve.getInput()); new Thread(send,"消息发送线程:").start(); new Thread(recieve,"消息接收线程:").start(); } } class SendThread implements Runnable{ private PipedOutputStream output;//管道输出流 public SendThread() { this.output = new PipedOutputStream();//实例化管道输出流 } @Override public void run() { // TODO Auto-generated method stub for(int i=1;i<=10;i++) { try { this.output.write(("【第"+i+"次信息发送-" + Thread.currentThread().getName()+"i love you】\n").getBytes()); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } try { this.output.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } public PipedOutputStream getOutput() { return output; } } class RecieveThread implements Runnable{ private PipedInputStream input;//管道输入流 public RecieveThread() { this.input = new PipedInputStream();//实例化管道输入流 } @Override public void run() { // TODO Auto-generated method stub byte[] data = new byte[1024]; int len = 0; ByteArrayOutputStream bos = new ByteArrayOutputStream(); try { while((len=this.input.read(data))!= -1) { bos.write(data,0,len); } System.out.println("{"+Thread.currentThread().getName()+"接收消息}"+new String(bos.toByteArray())); bos.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } try { this.input.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } public PipedInputStream getInput() { return input; } }
3.随机流(RandomAcceFile类)
对于文件内容的处理操作主要是通过InputStream(Reader)OutputStream(Write)来实现,但是利用这些类
实现的内容读取只能够将数据部分部分读取进来,如果文件非常庞大(20G),此时存再按照传统的IO操作进行读取
和分析根本不可能完成,所以这种情况下RandomAccessFile类可以实现跳跃式的读取,可以只读取中间的部分内容
(前提:需要有一个完善的保存形式)
RandomAccessFile类的定义:
public class RandomAccessFile extends Object implements DataOutput, DataInput, Closeable
构造方法:
public RandomAccessFile(File file,String mode) throws FileNotFoundException
RandomAccessFile最大的特点实在数据的读取处理上,因为所有的数据时按照固定的长度进行的保存,所以读取的
时候就可以进行跳字节读取
主要方法:
public int skipBytes(int n) throws IOException//向下跳
public void seek(long pos) throws IOException//向回跳
代码实例:
/* * 实现文件的保存 */ package IODemo; import java.io.*; public class RandomAccessFileDemo { public static void main(String[] args) throws Exception { // TODO Auto-generated method stub File file = new File("D:"+File.separator+"mldn.txt"); RandomAccessFile raf = new RandomAccessFile(file,"rw"); String[] names = new String[] {"zhangsan","wangwu ","lisi "};//名字占8位 int age[] = new int[] {30,20,16};//年龄占4位 for(int x = 0 ; x < names.length ; x++) { raf.write(names[x].getBytes()); raf.writeInt(age[x]); } raf.close(); } }
/* * 读取数据 */ package IODemo; import java.io.*; public class RandomAccessFileDemo2 { public static void main(String[] args) throws Exception { // TODO Auto-generated method stub File file = new File("D:"+File.separator+"mldn.txt"); RandomAccessFile raf = new RandomAccessFile(file,"rw"); {//读取lisi数据,跳过24位 raf.skipBytes(24); byte[] data = new byte[8]; int len = raf.read(data); System.out.println("姓名:"+new String(data,0,len).trim()+"年龄:"+raf.readInt()); } {//读取wangwu数据,回跳12位 raf.seek(12); byte[] data = new byte[8]; int len = raf.read(data); System.out.println("姓名:"+new String(data,0,len).trim()+"年龄:"+raf.readInt()); } {//读取zhangsan数据,回跳到顶点 raf.seek(0); byte[] data = new byte[8]; int len = raf.read(data); System.out.println("姓名:"+new String(data,0,len).trim()+"年龄:"+raf.readInt()); } } }
整体的使用之中由用户自行定义要读取的位置,而后按照指定的结构进行数据的读取