一.IO简介
1.什么是IO
1.Input: 让程序从外部系统获得数据(核心是读,读取外部数据)
2.Output:程序输出数据给外部系统从而可以操作外部系统(核心是写,将数据写到外部系统)
2.什么是数据源
数据源分为:源设备、目标设备
1.源设备:为程序提供数据,一般对应输入流
2.目标设备:程序数据的目的地,一般对应输出流
3.流的概念
连接程序与其他地方的抽象动态集合
4.Java中四大IO抽象类
1.字节输入输出流:InputStream/OutputStream
InputStream:
int read():读取一个字符的数据,并将字节的值作为int类型返回(0-255之间的一个值),如果未读取出字节返回-1
void close():关闭输入流对象
OutputStream:
void write(int n):向目的地中写入一个字节
void close():关闭输出流对象
2.字符输入输出流:Reader/Writer
Reader:
int read():读取一个字符的数据,并将字符的值作为int类型返回(0-65535之间的一个值),如果未读取出字符则返回-1
void close():关闭流对象
Writer:
void write(int n):向输入流中写入一个字符
void close():关闭输出流对象
二、IO流入门案例
1.第一个简单的IO流程序
package IO;
import java.io.FileInputStream;//文件为ABC
public class FirstDemo {
public static void main(String[] args) {
//创造字节输入流对象
FileInputStream fis=null;
try{
fis=new FileInputStream(name:"d:/a.txt");//括号里为文件字符串路径
int s1=fis.read();//int read()只能读取一个字节,英文字符占一个字节,所以读出来一个
int s2=fis.read();//打印输出字符b对应的ascii码值98
int s3=fis.read();
int s4=fis.read();//由于文件内容已经读取完毕,则返回-1
System.out.println(s1);
System.out.println(s2);
System.out.println(s3);
System.out.println(s4);
}
catch (Exception e)
{
e.printStackTrace();//在命令行打印异常信息在程序中出错的位置及原因
}
finally {
if(fis!=null){
try {
fis.close();
}catch (Exception e)
{
e.printStackTrace();
}
}
}
}
}
运行结果:
2.改造入门案例
while循环进阶版
package IO;
import java.io.FileInputStream;
public class SecondDemo {
public static void main(String[] args) {
FileInputStream fis=null;
try {
//创造字节输入流对象
fis=new FileInputStream(name="d:/a.txt");
int temp=0;
while ((temp= fis.read())!=-1){
System.out.println(temp);
}
}
catch (Exception e)
{
e.printStackTrace();
}
finally {
try {
if(fis!=null){
fis.close();
}
}catch (Exception e)
{
e.printStackTrace();
}
}
}
}
三、File类
1.File简介
一个File对象可以代表一个文件或目录
2.操作文件
package IO;
import java.io.File;
public class FileDemo {
public static void main(String[] args)throws Exception {
//创建File对象
File file=new File(pathname:"d:/aa.txt");
System.out.println(file.createNewFile());//创建文件
System.out.println(file.delete());//从磁盘上删除
System.out.println(file.exists());//查询磁盘中文件是否存在
System.out.println(file.getName());//获取文件名
System.out.println(file.isFile());//判断是否为文件
System.out.println(file.isHidden());//判断是否为隐藏文件
}
}
3.操作目录
package IO;
import java.io.File;
public class DirectoryDemo {
public static void main(String[] args) {
File file=new File(pathname:"d:/a");
System.out.println(file.mkdir());//创建目录,mkdirs创建多级目录
System.out.println(file.exists());//判断目录是否存在
System.out.println(file.isDirectory());//判断是否为目录
System.out.println(file.getParent());//返回父级目录名字
}
}
四、常用IO流对象
1.文件字节流
1.文件字节输入流
package IO;
import java.io.FileInputStream;
public class FileStreamDemo {
public static void main(String[] args) {
FileInputStream fis=null;
try {
//创建文件字节输入流对象
fis=new FileInputStream(name:"d:/sxt.jpg");
int temp=0;
while((temp=fis.read()!=-1))//图片字节数多,需用while循环
{
System.out.println(temp);
}
}
catch (Exception e)
{
e.printStackTrace();
}finally {
try{
if (fis!=null){
fis.close();
}
}catch (Exception e){
e.printStackTrace();
}
}
}
}
2.文件的字节输出流
package IO;
import java.io.FileInputStream;
public class FileStreamDemo {
public static void main(String[] args) {
FileInputStream fis=null;
FileOutputStream fis=null;
try {
//创建文件字节输入流对象
fis=new FileInputStream(name:"d:/sxt.jpg");
//创建文件字节输出流对象
fos=new FileOutputStream(name:"d:/aa.jpg");
int temp=0;
while((temp=fis.read()!=-1))//图片字节数多,需用while循环
{
fos.write(temp);
}
fos.flush();//将数据从内存中写入磁盘中
}
catch (Exception e)
{
e.printStackTrace();
}finally {
try{
if (fis!=null){
fis.close();
}
if (fos!=null){
fos.close();
}
}catch (Exception e){
e.printStackTrace();
}
}
}
}
3.通过缓冲区提高读写效率
方式一:
创造指定长度的字节数组作为缓冲区
该方式适用于读取较大图片的缓冲区定义
缓冲区长度一定是2的整数幂,一般情况下定义1024长度
(将大米放进袋子)
方式二:
创造指定长度的字节数组作为缓冲区,数组长度通过输入流对象available()返回当前预估长度来定义
大文件不使用此方法
4.通过字节缓冲流提高读写效率
缓冲流在别的流的基础上加上缓冲功能提高效率,先将数据缓存起来,缓存区存满后或者手动一次读到程序或写入目的地
缓冲字节流:BufferedlnputStream和BudderedOutputStream
package IO;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
public class FileStreamBuffed3Demo {
public static void main(String[] args) {
FileInputStream fis=null;
FileOutputStream fos=null;
BufferedInputStream bis=null;
BufferedOutputStream bos=null;
try {
fis=new FileInputStream("e:/1.jfif");
bis=new BufferedInputStream(fis);
fos=new FileOutputStream("e:/2.jfif");
bos=new BufferedOutputStream(fos);
int temp=0;
while ((temp= bis.read())!=-1){
bos.write(temp);
}
bos.flush();
}catch (Exception e){
e.printStackTrace();
}finally {
try {//关闭流顺序:后开的先关闭
if (bis!=null){
bis.close();
}
if (fis!=null){
fis.close();
}
if(bos!=null){
bos.close();
}
if (fos!=null){
fos.close();
}
}catch (Exception e)
{
e.printStackTrace();
}
}
}
}
缓冲流中的byte数组长度默认是8192,2的13次方
5.定义文件拷贝工具类
package IO;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
public class FileCopyTools {
public static void main(String[] args) {
copyFile("e:/1.jfif","e:/3.jfif");
}
//文件拷贝方法
public static void copyFile(String src,String des){
FileInputStream fis=null;
BufferedInputStream bis=null;
FileOutputStream fos=null;
BufferedOutputStream bos=null;
try{
bis=new BufferedInputStream(new FileInputStream(src));
bos=new BufferedOutputStream(new FileOutputStream(des));
int temp=0;
while ((temp=bis.read())!=-1) {
bos.write(temp);
}
bos.flush();
}catch (Exception e){
e.printStackTrace();
}finally{
try {
if (bis!=null){
bis.close();
}
if (fis!=null){
fis.close();
}
if(bos!=null){
bos.close();
}
if (fos!=null){
fos.close();
}
}catch (Exception e){
e.printStackTrace();
}
}
}
}
2.文件字符流
以字符为单位进行操作
1.文件字符输入流
package IO;
import java.io.FileReader;
public class FileReaderDemo {
public static void main(String[] args) {
FileReader frd=null;
try{
//创建文件字符输入流对象
frd=new FileReader("e:/a.txt");
int temp=0;
while ((temp=frd.read())!=-1){
System.out.println(temp);
}
}catch (Exception e){
e.printStackTrace();
}finally {
try{
}catch (Exception e){
e.printStackTrace();
}
}
}
}
2.文件字符输出流
package IO;
import java.io.FileWriter;
public class FileWriterDemo {
public static void main(String[] args) {
FileWriter fw=null;
FileWriter fw2=null;
try{
//创键字符输出流对象
fw=new FileWriter("e:/a.txt");//FileWriter发现给定路径无此文件,会帮创造文件
fw.write("徐州彭于晏\r\n");//\r回车\n换行
fw.write("徐州陈冠希");
fw.flush();
fw2=new FileWriter("e:/a.txt",true);
//如果是true不会覆盖前面fw的,默认是false会覆盖
fw.write("徐州");
fw.flush();
}catch (Exception e){
e.printStackTrace();
}finally {
try{
if (fw!=null) {
fw.close();}
if (fw2!=null){
fw2.close();
}
} catch (Exception e){
e.printStackTrace();
}
}
}
}
3.使用字符流实现文本文件的拷贝处理
package IO;
import java.io.FileReader;
import java.io.FileWriter;
public class FileCopyTools2 {
public static void main(String[] args) {
FileReader fr=null;
FileWriter fw=null;
try {
fr=new FileReader("e:/2.txt");
fw=new FileWriter("e:/3.txt");
char []buffer=new char[1024];
int temp=0;
while ((temp=fr.read())!=-1){
fw.write(buffer,0,temp);
}
fw.flush();
}catch(Exception e){
e.printStackTrace();
}finally {
try{
if (fr!=null) {
fr.close();
}
}catch (Exception e)
{
e.printStackTrace();
}
}
}
}
3.字符缓冲流
1.字符输入缓冲流
package IO;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
public class BufferedReaderDemo {
public static void main(String[] args) {
FileReader fr=null;
BufferedReader br=null;
try{
fr=new FileReader("e:/a.txt");
br=new BufferedReader(fr);
String temp=" ";
while((temp=br.readLine())!=null){
System.out.println(temp);
}
}catch (Exception e){
e.printStackTrace();
}finally {
try{
if (br!=null){
br.close();
}
if (fr!=null){
fr.close();
}
}catch (Exception e){
e.printStackTrace();
}
}
}
}
2.字符输出缓冲流
在字符输出缓冲流中可以使用newline();方法实现换行处理
package IO;
import java.io.BufferedWriter;
import java.io.FileWriter;
public class BufferWriterDemo {
public static void main(String[] args) {
FileWriter fw=null;
BufferedWriter bw=null;
try{
fw=new FileWriter("e:/1.txt");
bw=new BufferedWriter(fw);
bw.write("你好大帅哥");
bw.write("你好蔡徐坤");
bw.newLine();
bw.write("你好彭于晏");
bw.newLine();
bw.write("你好陈冠希");
bw.flush();
}catch (Exception e){
e.printStackTrace();
}finally {
try{
if(bw!=null){
bw.close();
}
if (fw!=null){
fw.close();
}
}catch (Exception e){
e.printStackTrace();
}
}
}
}
3.通过字符缓冲流实现文本文件的拷贝
package IO;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileReader;
import java.io.FileWriter;
public class FileCopyTools3 {
public static void main(String[] args) {
copyFile("e:/1.txt","e:/22.txt");
}
//基于字符缓冲流实现文件拷贝
public static void copyFile(String src,String des){
BufferedReader br=null;
BufferedWriter bw=null;
try{
br=new BufferedReader(new FileReader(src));
bw=new BufferedWriter(new FileWriter(des));
String temp=" ";
while ((temp=br.readLine())!=null) {
bw.write(temp);
bw.newLine();
}
}catch (Exception e){
e.printStackTrace();
}finally {
try{
if (bw!=null) {
bw.close();
}
if (br!=null){
br.close();
}
}catch (Exception e){
e.printStackTrace();
}
}
}
}
4.通过字符缓冲流为文件中的内容添加行号
package IO;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileReader;
import java.io.FileWriter;
public class LineNumberDemo {
public static void main(String[] args) {
BufferedReader br=null;
BufferedWriter bw=null;
try{
br =new BufferedReader(new FileReader("e:/1.txt"));
bw=new BufferedWriter(new FileWriter("e:/4.txt"));
String temp=" ";
int i=1;
while ((temp=br.readLine())!=null){
bw.write(i+","+temp);
bw.newLine();
i++;
}
bw.flush();
}catch (Exception e){
e.printStackTrace();
}finally {
try{
if (bw!=null){
bw.close();
}
if (br!=null){
br.close();
}
}catch (Exception e){
e.printStackTrace();
}
}
}
}
4.转换流
1.通过转换流实现键盘输入屏幕输出
package IO;
import java.io.*;
public class ConvertStream {
public static void main(String[] args) {
BufferedReader br=null;
BufferedWriter bw=null;
try{
br=new BufferedReader(new InputStreamReader(System.in));
bw=new BufferedWriter(new OutputStreamWriter(System.out));
while (true){
bw.write("请输入:");
bw.flush();
String input=br.readLine();
if ("exit".equals(input)){
break;
}
bw.write("你输入的是"+input);
bw.newLine();
}
}catch (Exception e){
e.printStackTrace();
}finally {
try{
if (bw!=null){
bw.close();
}
if (br!=null){
br.close();
}
}catch (Exception e){
e.printStackTrace();
}
}
}
}
2.通过字节流读取文本文件并添加行号
package IO;
import java.io.*;
public class LineNumberDemo2 {
public static void main(String[] args) {
BufferedReader br=null;
BufferedWriter bw=null;
try {
br=new BufferedReader(new InputStreamReader(new FileInputStream("e:/1.txt")));
bw=new BufferedWriter(new OutputStreamWriter(new FileOutputStream("e:/2.txt")));
String temp=" ";
int i=1;
while ((temp=br.readLine())!=null){
bw.write(i+","+temp);
bw.newLine();
i++;
}
bw.flush();
}catch (Exception e){
e.printStackTrace();
}finally {
try{
if(bw!=null){
bw.close();
}
if (br!=null){
br.close();
}
}catch (Exception e){
e.printStackTrace();
}
}
}
}
5.字符输出流
用于字符输出的流对象PrintWriter
package IO;
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
public class LineNumberDemo03 {
public static void main(String[] args) {
BufferedReader br=null;
PrintWriter pw=null;
try{
br=new BufferedReader(new InputStreamReader(new FileInputStream("e:/1.txt")));
pw=new PrintWriter("e:/1.txt");
String temp=" ";
int i=1;
while ((temp=br.readLine())!=null){
pw.println(i+","+temp);
i++;
}
}catch (Exception e){
e.printStackTrace();
}finally {
try{
if (br!=null){
br.close();
}
}catch (Exception e){
e.printStackTrace();
}
}
}
}
6.字节数组流
1.字节数组输入流
ByteArrayInputStream
package IO;
import java.io.ByteArrayInputStream;
public class ByteArrayInputDemo {
public static void main(String[] args) {
byte [] arr="abcdefg".getBytes();
ByteArrayInputStream bis=null;
StringBuilder sb=new StringBuilder();
try {
//该构造方法的参数是一个字节数组,这个字节数组就是数据源
bis=new ByteArrayInputStream(arr);
int temp=0;
while ((temp=bis.read())!=-1)
{
sb.append((char)temp);
}
System.out.println(sb.toString());
}finally {
try {
bis.close();
}catch (Exception e){
e.printStackTrace();
}
}
}
}
2.字节数组输出流
ByteArrayOutputStream
package IO;
import java.io.ByteArrayOutputStream;
public class ByteArrayOutputDemo {
public static void main(String[] args) {
ByteArrayOutputStream bos=null;
try {
StringBuilder sb = new StringBuilder();
bos=new ByteArrayOutputStream();
bos.write('a');
bos.write('b');
bos.write('c');
byte [] arr=bos.toByteArray();
for (int i=0;i<arr.length;i++){
sb.append((char)arr[i]);
}
System.out.println(sb.toString());
}finally {
try {
if (bos!=null){
bos.close();
}
}catch (Exception e){
e.printStackTrace();
}
}
}
}
7.数据流
1.数据输出流
package IO;
import java.io.BufferedOutputStream;
import java.io.DataOutputStream;
import java.io.FileOutputStream;
public class DataOutputDemo {
public static void main(String[] args) {
DataOutputStream dos=null;
try {
dos= new DataOutputStream(new BufferedOutputStream(new FileOutputStream("e:/1.txt")));
dos.writeChar('a');
dos.writeInt(10);
dos.writeDouble(Math.random());
dos.writeBoolean(true);
dos.writeUTF("徐州彭于晏");
dos.flush();
}catch (Exception e){
e.printStackTrace();
}finally {
try {
if (dos!=null){
dos.close();
}
}catch (Exception e){
e.printStackTrace();
}
}
}
}
2.数据输入流
package IO;
import java.io.BufferedInputStream;
import java.io.DataInputStream;
import java.io.FileInputStream;
public class DataInputDemo {
public static void main(String[] args) {
DataInputStream dis=null;
try {
dis=new DataInputStream(new BufferedInputStream(new FileInputStream("e:/1.txt")));
//直接读取数据,注意:读取的数据要与写入的输入一致,否则不能输出数据
System.out.println("char:"+dis.readChar());
System.out.println("int: "+dis.readInt());
System.out.println("double: "+dis.readDouble());
System.out.println("boolean: "+dis.readBoolean());
System.out.println("String: "+dis.readUTF());
}catch (Exception e){
e.printStackTrace();
}finally {
try {
if (dis!=null){
dis.close();
}
}catch (Exception e){
e.printStackTrace();
}
}
}
}
8.对象流
1.Java对象的序列化和反序列化
无论何种类型数据,都会以二进制序列的形式在网络上传送
把Java对象转换为字节序列的过程称为对象的序列化,把字节序列恢复为Java对象的过程称为对象的反序列化
ObjectOutputStream:他的writeObject(Object obj)方法可将OBJ对象序列化
ObjectInputStram:他的readObject()方法读取字节序列,再把他们反序列化为一个对象
2.写出基本数据类型
package IO;
import java.io.BufferedOutputStream;
import java.io.FileOutputStream;
import java.io.ObjectOutputStream;
public class ObjectOutputStreamBasicTypeDemo {
public static void main(String[] args) {
ObjectOutputStream oos=null;
try {
oos=new ObjectOutputStream(new BufferedOutputStream(new FileOutputStream("e:/1.txt")));
oos.write(10);
oos.writeDouble(Math.random());
oos.writeChar('a');
oos.writeBoolean(true);
oos.writeUTF("你好彭于晏");
oos.flush();
}catch (Exception e){
e.printStackTrace();
}finally {
try {
if (oos!=null){
oos.close();
}
}catch (Exception e){
e.printStackTrace();
}
}
}
}
3.读取基本数据类型数据
package IO;
import java.io.ObjectInputStream;
public class ObjectInputStreamBasicTypeDemo {
public static void main(String[] args) {
ObjectInputStream ois=null;
try {
}catch (Exception e){
}finally {
try {
if (ois!=null){
ois.close();
}
}catch (Exception e){
e.printStackTrace();
}
}
}
}
4.将对象序列化到文件
package IO;
import java.io.Serializable;
public class User implements Serializable {
private int userid;
private String username;
private String userage;
public User(int userid, String username, String userage) {
this.userid = userid;
this.username = username;
this.userage = userage;
}
public User() {
}
public int getUserid() {
return userid;
}
public void setUserid(int userid) {
this.userid = userid;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getUserage() {
return userage;
}
public void setUserage(String userage) {
this.userage = userage;
}
}
package IO;
import java.io.FileOutputStream;
import java.io.ObjectOutputStream;
public class ObjectOutputStreamObjectTypeDemo {
public static void main(String[] args) {
ObjectOutputStream oos=null;
try {
oos=new ObjectOutputStream(new FileOutputStream("e:/1.txt"));
User users=new User(1,"lb","18");
oos.writeObject(users);
oos.flush();
}catch (Exception e){
e.printStackTrace();
}finally {
try {
if (oos!=null){
oos.close();
}
}catch (Exception e){
e.printStackTrace();
}
}
}
}
5.将对象反序列化到内存
package IO;
import oop.demo09.UserService;
import java.io.FileInputStream;
import java.io.ObjectInputStream;
public class ObjectInputStreamObjectTypeDemo {
public static void main(String[] args) {
ObjectInputStream ois=null;
try {
ois=new ObjectInputStream(new FileInputStream("e:/1.txt"));
User users=(User)ois.readObject();
System.out.println(users.getUserid()+"\t"+users.getUsername()+"\t"+users.getUserage());
}catch (Exception e){
e.printStackTrace();
}finally {
try {
if (ois!=null){
ois.close();
}
}catch (Exception e){
e.printStackTrace();
}
}
}
}
8.随机访问流
RandomAccessFile
package IO;
import java.io.RandomAccessFile;
public class RandomAccessFileDemo {
public static void main(String[] args) {
RandomAccessFile raf=null;
try {
raf=new RandomAccessFile("e:/1.txt","rw");//mode权限:r读,rw读写
//将若干数据写入到文件中
int []arr=new int[]{10,20,30,40,50,60,70,80,90,100};
for (int i=0;i<arr.length;i++){
raf.writeInt(arr[i]);
}
raf.seek(4);//从第几个字节开始,int类型一个数4个字节
System.out.println(raf.readInt());
//隔一个对一个数据
for (int i = 0; i < 10; i+=2) {
raf.seek(i*4);
System.out.print(raf.readInt()+"\t");
}
System.out.println();
//在第8个字节位置插入一个新的数据45,替换之前的数据30
raf.seek(8);
raf.writeInt(45);
for (int i = 0; i < 10; i+=2) {
raf.seek(i*4);
System.out.print(raf.readInt()+"\t");
}
}catch (Exception e){
e.printStackTrace();
}finally {
try {
if (raf!=null){
raf.close();
}
}catch (Exception e){
e.printStackTrace();
}
}
}
}
九、File类在IO中的作用
package IO;
import java.io.*;
public class FileInIoDemo {
public static void main(String[] args) {
BufferedReader br=null;
BufferedWriter bw=null;
try {
br=new BufferedReader(new FileReader(new File("e:/1.txt")));
bw=new BufferedWriter(new FileWriter(new File("e:/2.txt")));
String temp=" ";
int i=1;
while ((temp=br.readLine())!=null){
bw.write(i+","+temp);
bw.newLine();
i++;
}
bw.flush();
}catch (Exception e){
e.printStackTrace();
}finally {
try {
if (bw!=null){
bw.close();
}
if (br!=null){
br.close();
}
}catch (Exception e){
e.printStackTrace();
}
}
}
}