一、学习目的
输人输出是指程序与外部设备或其他计算机进行交互的操作。几乎所有程序都具有输人与输出操作,比如从键盘上读取数据、从文件读取数据和向文件写人数据等。通过输人与输出操作可以从外界接收信息,或者是把信息传递给外界。Java 语言把这些输人与输出操作用流来实现,用统一的接口来表示,从而使程序设计简单明了。
二、学习内容
一、流
(1)流是计算机各部件之间的数据流动,按数据传输的方向可分为输入流与输出流,按流的内容可分为字符流与字节流,即流是由位或字符所构成的序列。统一管理数据的写入和读取 开发者只需要将内存里面的数据写到流里面或者从流里面读取数据
- 输出流:从内存空间将数据写入外部存储设备(磁盘,硬盘,光盘);OutputStream 字节流 Writer字符流
- 输入流:将外部存储设备的数据写到内存空间 ;InputStream 字节流 Reader字符流
- 缓存流:为了提高数据传输效率,通常用缓存流,即一个流配有一个缓存区Buffer,这个就是专门用于传输数据的一块内存
(2)注意:OutputStream,InputString都是抽象类不能直接使用,只能使用它们的子类:
对文件操作:FileOutputStream/FileInputStream FileWriter/FileReader
对象操作:ObjectOutputStream/ObjectInputStream ObjectWriter/ObjectReader
I/O流对象不属于内存对象,需要自己关闭释放;
(3)创建一个文件
//创建文件
String path =
"C:\Users\asus\Desktop\Android\Java\day2\src\main\java\swu\xwj\day8";
File file = new File(path.concat("\1.txt"));
//判断文件是否存在
if(file.exists() ==false){
try{
file.createNewFile(); }catch (IOException o){ System.out.println("IO异常");
}
file.createNewFile();
}
注:其中的异常处理也可以直接抛出,在main 函数后面加throws IOException
(4)向文件写入数据:
1,创建文件输出流对象
2,调用write方法写入
3,操作完毕需要关闭文件输出流对象
字节流:
// 创建文件输出流对象
FileOutputStream fos = new FileOutputStream(file);
//调用write方法写入
byte[] text = {'1','2','3','4'};
fos.write(text);
//操作完毕需要关闭文件输出流对象
fos.close();
字符流:
//写入数据—字符流
FileWriter fw = new FileWriter(file);
char[] name = {'安','卓','开','发'};
fw.write(name);
fw.close();
**(5)读取数据:
字节流:
//读取内容
FileInputStream fis = new FileInputStream(file);
byte[] name1 = new byte[12];
int count = fis.read(name1);
fis.close();
System.out.println(count+" "+new String(name1));
字符流:
FileReader fr = new FileReader(file);
char[] book = new char[4];
int count = fr.read(book);
fr.close();
System.out.println(count+" "+new String(book));
(6)向文件里保存一个对象
保存的对象必须是序列化 Serializable,即必须实现Serializable接口,若这个对象的属性里面引用了其他的对象,则引用的对象的那个类也要是实现Serializable接口
1,先定义一个类,实现Serializable接口
package swu.xwj.day8;
import java.io.Serializable;
public class Person implements Serializable {
public String name;
public int age;
}
2,创建一个对象,并保存
Person xw = new Person();
xw.name = "小王";
xw.age = 20;
OutputStream os = new FileOutputStream(file);
ObjectOutputStream oos = new ObjectOutputStream(os);
oos.writeObject(xw);
oos.close();
(7)读取对象
//从文件里读取一个对象
InputStream is = new FileInputStream(file);
ObjectInputStream ois = new ObjectInputStream(is);
Person xw =(Person) ois.readObject();
System.out.println(xw.name+" "+xw.age);
ois.close();
三、实例
将桌面上的图片拷贝到另一个文件中
long start = System.currentTimeMillis();//用于测量此种方法所用的时间
//将一个文件copy到另外一个位置
// 1,源文件路径
String sourcePath = "C:\Users\asus\Desktop\1.png";
// 2,目标文件的路径
String desPath = "C:\Users\asus\Desktop\Android\Java\day2\src\main\java\swu\xwj\day8\1.png";
// 3,图片,用字节流
FileInputStream fileInputStream = new FileInputStream(sourcePath);//读
FileOutputStream fileOutputStream = new FileOutputStream(desPath);//写
byte[] in = new byte[1024]; //一次读取1024个字节,直到文件读取完
while(true) {
int count = fileInputStream.read(in);//count=-1是到文件末尾
if(count != -1){
//读取到数据,还未到末尾 ,将这次循环读取的内容写到目标文件
fileOutputStream.write(in,0,count);//从数组的第一个元素写到第count个
}else{
break;
}
}
fileInputStream.close();
fileOutputStream.close();
long end = System.currentTimeMillis();
System.out.println(end-start+"毫秒");
}
注意:这种方法一点一点读取效率较低,耗费时间长。下面用缓存流:
class Copy{
public static void main(String[] args)throws IOException,ClassCastException{
long start = System.currentTimeMillis();
String sourcePath = "C:\Users\asus\Desktop\1.png";
String desPath = "C:\Users\asus\Desktop\Android\Java\day2\src\main\java\swu\xwj\day8\1.png";
InputStream is = new FileInputStream(sourcePath);
BufferedInputStream bis = new BufferedInputStream(is);
OutputStream os = new FileOutputStream(desPath);
BufferedOutputStream bos = new BufferedOutputStream(os);
byte[] in = new byte[1024]; //暂时保存读取的数据
int count = 0;
while((count = bis.read(in)) != -1){
bos.write(in,0,count);
}
bis.close();
bos.close();
long end = System.currentTimeMillis();
System.out.println(end-start+"毫秒");
}
}
由此可见两次结果耗费时间相差很大。因此缓存流提高了内存与外部设备之间的数据传输效率。
四、学习感悟
文件操作虽然不算很难,但却非常重要,在以后的编程中处处都会用到,因此需要非常熟练的掌握输入输出流的使用。