二、字符串流
1、StringReader
其源为一个字符串的字符流。
2、 StringWriter
一个字符流,可以用其回收在字符串缓冲区中的输出来构造字符串。
关闭 StringWriter 无效。
此类中的方法在关闭该流后仍可被调用,而不会产生任何 IOException。
TT_EOF 表示 流的最后
TT_EOL 表示 一行的最后 结尾
TT_NUMBER 表示 分析带数字的 0-9
TT_WORD 表示 分析一个单词
ttype表示获取下一个标记 类型
这一句意思是 只要类型不等于结尾 循环就继续
如果下一个标记 等于单词
- 字符串流:以一个字符串为数据源,来构造一个字符流
- 作用:在WEB开发中,我们经常要从服务器上获取数据,数据的返回格式通过是一个字符串(XML,JSON),我们需要把这个字符串构造成一个字符流
- 然后再用第三方的数据解析器来解析数据。
- 下列是计算字符串有几个单词
package com.vince;
import java.io.IOException;
import java.io.StreamTokenizer;
import java.io.StringReader;
/**
* 字符串流:以一个字符串为数据源,来构造一个字符流
* 作用:在WEB开发中,我们经常要从服务器上获取数据,数据的返回格式通过是一个字符串(XML,JSON),我们需要把这个字符串构造成一个字符流
* 然后再用第三方的数据解析器来解析数据。
* StringWriter
* @author vince
* @description
*/
public class StringStreamDemo {
private static void stringReader(){
String info = "good good study day day up";
StringReader sr = new StringReader(info);
//流标记器
StreamTokenizer st = new StreamTokenizer(sr);
int count = 0;
while(st.ttype != StreamTokenizer.TT_EOF){
try {
if(st.nextToken()==StreamTokenizer.TT_WORD){
count++;
}
} catch (IOException e) {
e.printStackTrace();
}
}
sr.close();
System.out.println("count="+count);
}
public static void main(String[] args) {
stringReader();
}
}
三、管道流
管道输入流应该连接到管道输出流;管道输入流提供要写入管道输出流的所有数据字节。
通常,数据由某个线程从 PipedInputStream 对象读取,并由其他线程将其写入到相应的 PipedOutputStream。
不建议对这两个对象尝试使用单个线程,因为这样可能死锁线程。
管道输入流包含一个缓冲区,可在缓冲区限定的范围内将读操作和写操作分离开。
如果向连接管道输出流提供数据字节的线程不再存在,则认为该管道已损坏。
package com.vince;
import java.io.IOException;
import java.io.PipedInputStream;
import java.io.PipedOutputStream;
/**
* 管道流测试:一个线程写入,一个线程读取
* 作用,用于线程之间的数据通讯
* @author vince
* @description
*/
public class PipedStreamDemo {
public static void main(String[] args) {
PipedInputStream pin = new PipedInputStream();
PipedOutputStream pout = new PipedOutputStream();
try {
pin.connect(pout); //两个管道进行链接
} catch (IOException e) {
e.printStackTrace();
} //输入流与输出流连接
ReadThread readTh = new ReadThread(pin);
WriteThread writeTh = new WriteThread(pout);
new Thread(readTh).start(); //先把读线程启动等着 读不到就堵塞 一直等
new Thread(writeTh).start();
}
}
//读取数据的线程
class ReadThread implements Runnable {
private PipedInputStream pin; //输入管道
ReadThread(PipedInputStream pin){
this.pin = pin;
}
public void run(){
try {
byte[] buf = new byte[1024];
int len = pin.read(buf); // read阻塞
String s = new String(buf, 0, len);
System.out.println("读到:"+s);
pin.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
//写入数据的线程
class WriteThread implements Runnable {
private PipedOutputStream pout; //输出管道
WriteThread(PipedOutputStream pout) {
this.pout = pout;
}
public void run() {
try {
pout.write("一个美女...".getBytes()); // 管道输出流
pout.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
RandomAccessFile
RandomAccessFile是IO包的类,从Object直接继承而来。
只可以对文件进行操作,可以对文件进行读取和写入。
当模式为r是,当文件不存在时会报异常,当模式为rw时,
当文件不存在时,会自己动创建文件,
当文件已经存在时 不会对原有文件进行覆盖。
RandomAccessFile有强大的文件读写功能,其内部是大型 byte[],
可以通过seek(),getFilePointer()等方法操作的指针,方便对数据进行写入与读取。
还可以对基本数据类型进行直接的读和写操作。
RandomAccessFile的绝大多数功能,已经被JDK 1.4的nio的“内存映射文件(memory-mapped files)”给取代了,你该考虑一下是不是用“内存映射文件”来代替RandomAccessFile了。
下述代码实现了文件的复制
package com.vince;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;
/**
* RandromAccessFile
* @author vince
* @description
*/
public class RandromAccessFileDemo {
public static void main(String[] args) {
try {
//读取文件
RandomAccessFile r = new RandomAccessFile("c:\\3D0.jpg","r");
//写入文件
RandomAccessFile w= new RandomAccessFile("c:\\test\\3D0.jpg","rw");
byte[] bytes = new byte[1024];
int len = -1;
while((len=r.read(bytes))!=-1){
w.write(bytes,0,len);
}
w.close();
r.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("copy success.");
}
}