首先对于IO操作应注意以下步骤:
总结:
流操作的基本规律:最痛苦的就是流对象有很多,不知道该用哪一个
通过两个明确来完成。
1.明确源和目的
源:输入流,InputStream Reader
目的:输出流。OutputStream Writer
2.操作的数据是否是纯文本
是:字符流
不是:字节流
3.档体系明确后,在明确要使用哪个具体的对象。
通过啊设备来进行区分
源设备:内存,硬盘,键盘
目的设备:内存,硬盘,控制台
举例:一个文件复制程序需求分析
1.将一个文件中的数据存储到另一个文件中(复制)
源:文件 InputStream Reader,是不是文本文件:是:选择Reader
明确设备:硬盘,Reader体系中可以操作文件的对象是:FileReader
是否提高读写效率:加入Reader体系中的缓冲区 BufferedReader
目的:文件 OutputStream Writer
是否是纯文本?是:Writer
设备:硬盘,一个文件,Writer体系中可以操作的对象。FileWriter
是否提高效率:BufferedWriter
2.将键盘录入的数据保存到一个文件中
流对象介绍
1.FileReader,FileWriter,BufferedReader,BufferedWriter对象
对于字符流对象的操作参考下面例子,FileReader和FileWriter指定目的和源,Bufferde流用于提供缓存,提高效率
import java.io.*;
public class CopyPicDemo {
/**
* 使用字节流复制一张图片
* 操作步骤:
* 1.创建图片写入关联、图片读取关联流对象
* 2.创建缓冲区存储
* 3.循环读取
* 4.读取完成,关闭资源
*/
public static void main(String[] args) {
//创建读写流对象
FileInputStream fis = null;
FileOutputStream fos = null;
try {
//确定操作文件位置
fos = new FileOutputStream("D:\\2.jpg");
fis = new FileInputStream("D:\\1.jpg");
int len = 0;
//创建存储数组
byte []buf = new byte[1024];
//循环读取数据,将读到的数据写入到制定文件中。
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 e2) {
throw new RuntimeException("读入资源关闭失败");
}
try {
if(fos!=null)
fos.close();
} catch (IOException e3) {
throw new RuntimeException("写入资源关闭");
}
}
}
}
2.File类,文件操作类
//File基本操作
/**
* 创建:如果不存在就创建一个,如果存在、则提示,不能完成创建过程:createNewFile
* mkdir创建文件夹 mddirs创建文件夹多级目录
* 删除:删除一个文件。delete:删除失败返回假 or deleteOnExit 退出是删除
* 判断:boolean exists isDirecroty isFile 后两者需要先判断是否存在对象,通过isExists判断
* 获取信息:getPath getName getAbsolutePath long lastModify, getParent(); //该方法如果没有绝对路径,则
返回为空(getParent)long length;
* @throws IOException
*/
public static void getFileDemo() throws IOException{
File f = new File("D:\\demo.txt");
System.out.println("exists:"+f.exists());
System.out.println("canExecute:"+f.canExecute());
System.out.println("canRead:"+f.canRead());
//System.out.println("createFile: "+f.createNewFile());
//System.out.println("delete: "+f.delete());
}
public static String method2(){
File f = new File("D:\\demo.txt");
f.deleteOnExit();//在程序退出时,删除
return null;
}
//创建目录
public static void crateDir(){
File f = new File("d:\\demo");
if(f.exists())// 判断是否存在
f.mkdir();
System.out.println("mkdir:"+f.mkdir());//创建一级目录
File ff = new File("d:\\demo\\de\\dd\\gsag\\gfdasg\\gfa\\sadfs");
System.out.println("mkdirs:"+ff.mkdirs());//创建多级目录
}
//重命名,相当于移动文件renameTo
public static void reaName(){
File f2 = new File("D:\\demo.txt");
File f1 = new File("D:\\demo11.txt");
f1.renameTo(f2);
}
3.ByteArray
ByteArray 是用于操作字节数组的流对象
ByteArrayInputStream:在构造的时候,需要接受数据源,而且数据源是一个字节数组。
ByteArrayOutputStream:在够早的时候,不用定义数据目的,因为该对象中已经内部封装了可变长度的字节数组。
这就是数据目的地
因为这两个流对象都操作的数据,并没有使用系统资源,所以不用close();
public class ByteArrayStream {
public static void main(String[] args) {
//数据源
ByteArrayInputStream bis = new ByteArrayInputStream("abcdefg".getBytes());
//数据目的
ByteArrayOutputStream bos = new ByteArrayOutputStream();
int by = 0;
while((by=bis.read())!=-1){
bos.write(by);
}
//System.out.println(bos.size());
//writeTo方法,
//将此 byte数组输出流的全部内容写入到指定的输出流参数中。
//bos.writeTo(new FileOutputStream("D:\\demo.txt"));
}
}
4.DataStream对象
import java.io.*;
/*
* 操作基本数据类型(**)
* DataInputStream DataOutputStream
* 可以用于操作基本数据类型的数据的流对象
* utf增强版 write 和 read
*/
public class DataStreamDemo {
public static void main(String[] args)throws Exception {
//writeData();
// readData();
//wirteUTFDemo();
readUTFDemo();
}
//utf增强版 write
public static void wirteUTFDemo() throws IOException {
DataOutputStream dos = new DataOutputStream(new FileOutputStream("D:\\demo.txt"));
dos.writeUTF("你好");
dos.close();
}
//utf增强版read
public static void readUTFDemo() throws IOException {
DataInputStream dis = new DataInputStream(new FileInputStream("D:\\demo.txt"));
System.out.println(dis.readUTF().toString());
dis.close();
}
//DataOutputStream write方法
public static void writeData() throws IOException {
DataOutputStream dos = new DataOutputStream(new FileOutputStream("D:\\demo.txt"));
dos.writeInt(123);
dos.writeDouble(23561.1346);
dos.writeBoolean(true);
dos.close();
}
//DataInputStream read方法
public static void readData() throws IOException {
DataInputStream dis = new DataInputStream(new FileInputStream("D:\\demo.txt"));
int a = dis.readInt();
double d = dis.readDouble();
boolean b = dis.readBoolean();
System.out.println("a="+a);
System.out.println("d="+d);
System.out.println("b="+b);
dis.close();
}
5.PipedStream,管道流
import java.io.*;
public class PipedStreamDemo {
public static void main(String[] args) throws IOException {
//创建管道流对象
PipedInputStream pis = new PipedInputStream();
PipedOutputStream pos = new PipedOutputStream();
//将两个管道流流进行连接
pis.connect(pos);
//实例化对象
Read r = new Read(pis);
Write w = new Write(pos);
//启动两个线程处理管道流的读写
new Thread(r).start();
new Thread(w).start();
}
}
//read类,实现Runnable接口
class Read implements Runnable{
//创建PipedInputStream对象引用
private PipedInputStream pis;
Read(PipedInputStream pis){
this.pis = pis;
}
//重写Runnable接口的run()
public void run(){
try {
//创建一个用于保存数据的数组
byte[] buf = new byte[1024];
int len = pis.read(buf);
//打印这个长度的string字符串
String s = new String(buf,0,len);
System.out.println(s);
pis.close();
} catch (IOException e) {
throw new RuntimeException("管道输入失败");
}
}
}
//write类,实现Runnable接口
class Write implements Runnable {
private PipedOutputStream pos;
Write(PipedOutputStream pos){
this.pos = pos;
}
public void run(){
try {
//pos写入字符串,装成byte类型
pos.write("heima".getBytes());
pos.close();
} catch (Exception e) {
throw new RuntimeException("管道输出失败");
}
}
}
6.InputStreamReader 和 OutputStreamWriter,转换流
import java.io.*;
/*
使用InputStreamReader 和 OutputStreamWriter进行的字符转换
*/
public class StreamTransformDemo {
public static void main(String[] args) throws IOException {
//writeStream();
readStream();
}
//readStream
public static void readStream() throws IOException {
InputStreamReader isr = new InputStreamReader(new FileInputStream("D:\\demo.txt"),"utf-8");
char[] buf = new char[10];
int len = isr.read(buf);
String s = new String(buf,0,len);
System.out.println(s);
isr.close();
}
//writeStream方法
public static void writeStream() throws IOException {
OutputStreamWriter osr = new OutputStreamWriter(new FileOutputStream("D:\\demo.txt"),"gbk");
osr.write("你好");
osr.close();
}
}
7.RandomAccessFile随机访问文件流
import java.io.*;
/**
* RandomAccessFile不是io体系中的子类,而是直接继承自Object
* 但他是io包中的成员,具备读写功能
*
* 内部封装了一个数组,而且通过指针对数据进行操作
* 通过getFilePointer获取指针位置
* 同时可以使用seek方法改变指针位置
*
* RandomAccessFiel内部封装了字节输入流和输出流
* 通过构造函数可以看出,该类只能操作文件,而且操作文件需要模式"r" "rw" "rws" "rwd",并且如果文件不存在则创建,如
果存在则修改。
* 如果模式为只读,则会读文件,但不会创建文件,找不到文件会报错
* 如果模式为读写,则会创建不存在的文件。
*/
public class RandomAccessFileDemo {
public static void main(String[] args) throws IOException {
readFile();
}
//RandomAccessFile写入文件
public static void writeFile() throws IOException{
RandomAccessFile raf = new RandomAccessFile("D:\\demotxt.txt","rw");
raf.write("李四".getBytes());
raf.writeInt(20);
raf.seek(8*2);
raf.write("王五".getBytes());
raf.writeInt(25);
raf.close();
}
//Random
public static void readFile() throws IOException {
RandomAccessFile raf = new RandomAccessFile("D:\\demotxt.txt","r");
//调整指针位置
//raf.seek(8);
//2.向后空以为
raf.skipBytes(8);
byte[] buf = new byte[4];
raf.read(buf);
int age = raf.readInt();
String name = new String(buf);
System.out.println("name="+name);
System.out.println("age="+age);
raf.close();
}
}
8.标准输入输出流
* System类中的字段:in,out。
*它们各代表了系统标准的输入和输出设备。
* 默认输入设备是键盘,输出设备是显示器。
* System.in的类型是InputStream.
* System. out的类型是PrintStream.
System.out的类型是PrintStream是OutputStream的子类FilterOutputStream 的子类