一.I/O内容后续
Object补充
transient:标记被序列化的对象的属性透明化,不参与序列化,只能修饰变量,
不能修饰其他内容
建议使用实现Serializable接口进行序列化,
并且再文件操作和网络操作中所有的类都要实现序列化
PipedInputStream,PipedOutputStream
管道流,字节流,基础流
一般用来解决多线程的数据访问问题
需要使用connect方法将管道输出流和管道输入流连接起来,达到一个线程通信的目的,
其中管道流的read方法具有线程阻塞的作用
一般不用在单线程中,容易出现死锁
相关代码实现:
import java.io.*;
/**
* 对比之前线程中生产者和消费者的模型
* 没有通过wait和notify就可以实现通信
* @author Acer
*
*/
public class PipedTest {
public static void main(String[] args) {
//先准备管道流的对象
PipedOutputStream pos = new PipedOutputStream();
PipedInputStream pis = new PipedInputStream();
//连接
try {
pis.connect(pos);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
// 初始化线程
Sender s = new Sender("线程1", pos);
Printer p = new Printer("线程2", pis);
//线程启动
s.start();
p.start();
}
}
// 准备两个线程
// 输出线程
class Sender extends Thread {
PipedOutputStream pos = null;
public Sender(String name, PipedOutputStream pos) {
super(name);
this.pos = pos;
}
@Override
public void run() {
// 在管道流中输出基本类型的数据
DataOutputStream dos = new DataOutputStream(pos);
// 循环输出1-10
System.out.println("正在写入...");
for (int i = 1; i < 11; i++) {
try {
dos.writeInt(i);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
// 输入线程
class Printer extends Thread {
PipedInputStream pis = null;
public Printer(String name, PipedInputStream pis) {
super(name);
this.pis = pis;
}
@Override
public void run() {
//
DataInputStream dis = new DataInputStream(pis);
for (int i = 0; i < 10; i++) {
try {
//read()方法具有阻塞功能
System.out.println(getName()+"输出"+dis.readInt());
sleep(200);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
reader,writer
字符输入流,和字符输出流的超类
作为抽象类,一般不直接产生实例,需要靠其子类完成功能
FileReader,FileWriter
文件流,字符流,基础流
相关代码:
import java.io.*;
import general.CloseUtil;
import general.UrlFiled;
/**
* 使用字符流完成文件拷贝
*
* @author Acer
*
*/
public class FileCopy2 {
public static void main(String[] args) {
//确认使用什么流
FileReader fr = null;
FileWriter fw = null;
String inPath = UrlFiled.PROJECT+"a.txt";
String outPath = UrlFiled.TARGET+"b.txt";
try {
fr = new FileReader(inPath);
fw = new FileWriter(outPath);
System.out.println("开始...");
int i = 0;
while((i=fr.read())!=-1) {
System.out.println(i);
fw.write(i);
}
// int i = 0;
// char[] c = new char[20];
// while((i=fr.read(c))!=-1) {
// System.out.println(new String(c,0,i));
// fw.write(c,0,i);
// }
System.out.println("结束");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally {
CloseUtil.closeStream(fr, fw);
}
}
}
InputStreamReader,OutputStreamWriter
转换流,字符流,中间流
为什么只提供了字节转字符,没有提供字符转字节呢
效率:字符流比字节流好
范围:字节流比字符流使用范围广
BufferedReader,BufferedWriter
缓冲流,字符流,包装流
对应的缓冲流要记得flush
建议:对输出流操作完成之后要使用flush
代码:
import java.io.*;
import general.CloseUtil;
import general.UrlFiled;
/**
* 测试字符流的缓冲流
*
* @author Acer
*
*/
public class BufferedTest2 {
public static void main(String[] args) {
//输入
//需求,读取文件内容并输出在控制台上
BufferedReader br = null;
// 基础流使用字节流,文件流
FileInputStream fis = null;
//需要使用转换流来进行转换
InputStreamReader isr = null;
//输出
BufferedWriter bw = null;
FileOutputStream fos = null;
OutputStreamWriter osw = null;
try {
fis = new FileInputStream(UrlFiled.TARGET+"b.txt");
isr = new InputStreamReader(fis,"UTF-8");
br = new BufferedReader(isr);
fos = new FileOutputStream(UrlFiled.TARGET+"c.txt");
osw = new OutputStreamWriter(fos,"UTF-8");
bw = new BufferedWriter(osw);
//直接读
String s ="";
while((s=br.readLine())!=null) {
System.out.println(s);
}
//直接写
bw.write(s+"\n");
bw.newLine();//每写完一行产生新的空行
bw.flush();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally {
CloseUtil.closeStream(fis, null);
CloseUtil.closeStream(br, null);
CloseUtil.closeStream(isr, null);
}
}
}
PrintStream,PrintWriter
打印流,
为输出流提供了更方便的输出方式
字节流的操作使用Stream,字符流的操作使用Writer
记得flush
代码:
import java.io.*;
import general.CloseUtil;
import general.UrlFiled;
/**
*
* 测试打印流
*
* @author Acer
*
*/
public class PrintTest {
public static void main(String[] args) {
// 当成基础流来处理
PrintStream ps = null;
//当成包装类来处理,使用基础流的参数的构造器
try {
ps = new PrintStream(UrlFiled.TARGET+"d.txt");
ps.print(true);
ps.print(20);
ps.println("这是一个字符串");
ps.write("今天是个好日子\n".getBytes());
System.setOut(ps);//修改了系统类的打印流对象
System.out.println("这是调用的内部打印方法");
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally {
CloseUtil.closeStream(null, ps);
}
}
}
随机访问流 RandomAccessFile
既能读又能写
一般用在大文件上
seek(long);
getFilePointer;
代码:
import java.io.*;
import general.UrlFiled;
/**
* 测试随机文件访问流
*
* @author Acer
*
*/
public class RandomTest {
public static void main(String[] args) {
RandomAccessFile raf = null;
DataOutputStream dos = null;
try {
raf = new RandomAccessFile(UrlFiled.TARGET + "b.txt", "rw");
long pointer = raf.getFilePointer();
long len = raf.length();
dos = new DataOutputStream(new FileOutputStream(UrlFiled.DESKTOP+"pointer"));
dos.writeLong(pointer);
dos.writeLong(len);
//思路:判断文件是否存在,如果存在直接读取
//如果文件不存在,则创建指针文件
//指针文件保存了当前文件的位置和文件的总体大小
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
File类
java.io包
流中用到的比较多
本机上的文件–>抽象成类–>产生对应的对象
文件大小
文件是否存在
文件的名字
文件的类型
是否是一个目录
展现文件系统
等待…
代码:
import java.io.*;
import java.util.Arrays;
import general.UrlFiled;
public class FileTest {
public static void main(String[] args) {
File file = new File(UrlFiled.TARGET+"dd.txt");
File ff = file.getParentFile();
System.out.println(ff.getName());
System.out.println(ff.isDirectory());
boolean flag = file.exists();
//判断该路径的文件是否存在
System.out.println(flag);
//该file是不是一个目录,如果是目录就打印出来
if(ff.isDirectory()) {
String[] names = ff.list();
System.out.println(Arrays.toString(names));
}
if(!flag) {
try {
file.createNewFile();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
二.心得
今天还是学的i/o流相关的内容,在不断的接受新的api时,已经开始有点乱了,得找时间把相关内容好好整理一遍.明天加油