IO存在于java.io包中
File是io中表示文件和文件夹的类
路径分隔符,因为不知道代码需要循行的平台 java提供了
四大基流
字节输出输入流
字符输出输入流
字节输出流 OutputStream
字符输出流 Writer
字节输入流 InputStream
字符输入流 Reader
只能创建流的子类对象 任何流都有colse方法
操作对象必须有一个流 用完要关闭
操作io流的模板
1):创建源或者目标对象 比如文件 等
2):创建io流对象相当于水管
3):具体的io操作
4):关闭资源,释放资源(勿忘)
操作io流的六字真言
读进来:输入 read
写出去: 输出 write
/**********************************************
文件流;程序和文件之间的流
FileInputStraem文件的字节输入流
FileOnputStraem文件的字节输出流
FileReader文件的字节输入流
FileWriter 文件的字节输出流
(注)这里的文件是文本文件
//获取当前项目路径
String val=System.GETpROPERTY(“user.dir”);
操作汉字或者特殊符号语言使用字节流时容易乱码建议使用字符流
二进制文件时(使用记事本打开 能看你到内容的时文本 看不到的是二进制,(也不全是))使用字节流
文本使用字符流 如果不清楚 就使用字节流
字符流 flash(刷新)操作输出流中都有 使用close方法之前会自动调用
字符编码:最终发展成unicode
常见的字符集:
ASCLL:只能包含128个符号 栈一个字节
iso-8859-1:latin-1:西欧的一些符号 一个字节
ANSI:GB2312两个字节 常用的简体中文
GBK:支持繁体等GB2312的拓展
UTF-8:unicode的实现 三个字节表示一个汉字 又称万国码
注:
存储字母和数字 无论什么字符集都占一个字节 存储汉字对于GBK 2个字节 UTF-8 占2个字节;UTF-8 bom是微软的编码 默认会占3个字节,不要使用这个
/*******************************
字符的编码和解码
编码:把字符串转换成byte
解码:把byte回复成字符串
一定要保证编码和解码的字符集相同
网页服务器 一般用ISO-8859-1编码集解码的 所以要 应该将解码过后的字符串按 ISO-8859-1编码回byte 再按GBK进行解码,
包装流/处理流(相当于借点流更高级)底层还是节点流再操作 只是包装了节点流
包装流 区分:写代码的时候发现创建流对象的时候需要传递另一个流对象 如:new 包装流对象(另一个流对象);
缓冲流:是一个包装流 起缓冲作用字节字符缓冲流BufferInputStream……BufferRead…等
BufferWriter中有一个newLine()换行方法只能用子类接受
BufferRead中新增一个ReadLine()读取整行的方法
转换流 把字节流转成字符流
a.把字节输入流转化成字符输入流
字节流可操控一切文件
InputStreamReader
OutputStreamWriter
Reader re=new InputStreamReader(new FileInputStream(),”GBK”)
数组流(内存流)
先把数据临时存在数组中 再从数组中取出来
1):字节内存流ByteArrayInoutStream by=new ByteArrayInoutStream();
by.write(“abc”.getbyte)
byte [] buffer=by.tobyteArray();
ByteArrayOutputStream
2):字符内存流
charArrayReader
charArrayWriter
3):字符串流
数据存到字符串中
StringReader
StringWriter
StringWriter st=new StringWriter();
st.writer(“hhahha”)
st.toString
4):合并流(顺序流)
多个输入流 合并成一个流
SequenceInputStream(两个流)
/********************************
序列化和反序列化
序列化:
指把内存中的对象数据存储通过某种方式到磁盘文件中,或者传递给其他网络节点 我们称之为序列化
反序列化
反之 把磁盘文件中或者网络节点上的对象数据恢复成java对象的过程
序列化的原因:
再分布式系统中 需要共享的数据的javaBean对象,都得坐序列化 需要把对象在网络上传输
以后存储在HttpSession中的对象,都应该实现序列化接口(只有实现序列化接口的类 才能坐序列化操作)
2):服务器钝化:如果服务器某些对象好久都没有活动了,此时服务器就会把这些内存中的对象持久化在本地磁盘文件中(java->二进制文件)如果某些对象活动的时候,现在内存中取寻找,找到就使用
,找不到再去磁盘文件中反序列化我的对象数据,回复成java对象
需要做序列化的类都要实现序列化接口
java.lang.serializable接口,是一个标志接口(没有抽象方法)
底层会判断,如果对象是serializable接口才允许被序列化
在java中大部分类都实现了
使用对象流来序列化和反序列化操作:
ObjectInoutStream:通过readerObject序列化
ObjectOutputStream:反序列 化通过writererObject序列化
序列化的细节序列化的版本
某些数据不需要做序列化 某些静态或者瞬态不能序列化
关键字 transient 修饰 就不能被序列化 比如密码
序列化的版本:
该对象 增加或者删除字段 class文件就应该要更新 不然报错 java通过序列化版本号(seriaVersionUID)来判断字节码是否是同一份字节码
可让对象用 private static final long seriaVersionUID 来申请一个版本号 然后改变字段就不会报错
/**************************************************
打印流 打印数据
只能是输出流 不抛出异常
PrintStream:字节打印流
PrintWriter:字符打印流
调用print println format 会自动刷新
标准的IO操作:
标准的输入:通过键盘录入数据给程序
标准输出:在屏幕上显示程序
在SYStem类中 in 和out
标准流的重定向
重新定义输入的方向不是键盘而是文件等
此后System.in的来源就是setin指定的源
//重定向标准输入
System.setIn(new FileInputStream(“123/456.txt”));
InputStream in=System.in;
OutputStream out=System.out;
int data=in.read();//标准输入
扫描器类:表示输入
Scanner存在两大主方法 hasNextXxx();判断是否有下一种类型的数据Xxx
nextXxx()获取下一个数据
Scanner scan=new Scanner(“133/456.txt”);
scan.nextLine();//扫描整行
properties加载资源文件的问题:配置文件
把所有的数据储存到代码中 写死了 “硬编码”
比如账号密码
我们要把项目部署在另外一台电脑中 此时我们就得取项目中寻找哪里使用了账号和密码
此时专门为数据库提供配置文件,里面提供了数据库连接的相关文件
db.properties
#key=value
username=root
password=admin
java代码如何加载配置文件中的信息
必须使用Properties类
//加载Properties文件
Properties pro=new Properties();
InputStream in=new FileInputStream("F:/JAVA/课程练习/IOTrain/src/db.properties");
pro.load(in);
System.out.println(pro.getProperty("username"));
数据流:提供了可以写和读任意类型的方法
DataInputStream
提供了 writerXxx(xxx value)
DataOutputStream
readXxxx
两者需要对应比如writebyte和readbyte
DataOutputStream out=new DataOutputStream(new FileOutputStream(“123/123.txt”));
out.writeByte(65);
out.writeChar(‘h’);
out.writeUTF(“dasda”);
out.close();
//读一样 readbyte readchar ..
/***************************************
随机访问文件
RandomAccessFile
表示可以在文件的任何位置读取和写入操作
//表示可以在文件的任何位置读取和写入操作 实现了读和写
File f=new File("123/123.txt");
RandomAccessFile rd=new RandomAccessFile(f,"rw");
rd.writeByte(65);
rd.writeUTF("dasda");
//等等
byte b=rd.readByte();
String str=rd.readUTF();
//等等
System.out.println(rd.getFilePointer());//文件指针的位置
rd.seek(5);//设置文件指针的位置
rd.skipBytes(3);//文件指针跳过多少位置
rd.setLength(1024);//设置文件大小 经常用来做多线程的断点下载
rd.close();
/*****************
管道流:实现两个线程之间的交互
PipedInputStream
PipedOutputStream
class Athread extends Thread
{
/* (non-Javadoc)
* @see java.lang.Thread#run()
*/
private PipedOutputStream out=new PipedOutputStream();
/**
* @return the out
*/
public PipedOutputStream getOut() {
return out;
}
/**
* @param out the out to set
*/
public void setOut(PipedOutputStream out) {
this.out = out;
}
@Override
public void run() {
// TODO Auto-generated method stub
int b=2;
try {
out.write(b);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally
{
try {
out.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
class Bthread extends Thread
{
/* (non-Javadoc)
* @see java.lang.Thread#run()
*/
private PipedInputStream in=null;
public Bthread(Athread a)
{
try {
in=new PipedInputStream(a.getOut());
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
@Override
public void run() {
// TODO Auto-generated method stub
//读的操作
try {
in.read();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
in.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
public static class ThreadOut {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
Athread a=new Athread();
Bthread b=new Bthread(a);
}
}
}
/****************************************
NIO 可以把一快磁盤文件映射到内存中 java.nio包裏面
主要運用於服务器中对于写代码依然使用传统的IO
通道:
缓冲区:
NIO2.0文件拷贝 Files(文件工具类)copy
Path p=Paths.get(“”);
Files.copy(Paths.get(“123.txt”),Paths.get(“456.txt”))
walkFileTree 递归文件