**IO流**
File 类的使用
1.FIle 类的一个对象,代表一个文件或一个文件目录(俗称: 文件夹)
2 File 类声明在java,io包下
如何创建File类的实例
File 的构造器
public File (String pathname) 以pathname为路径 创建File 对象 可以是绝对路径或者相对路径 如果是相对路径 则默认的当前路径在系统属性user,dir中存储(工程目录下)
绝对路径: 是一个固定的路径 从盘符开始 (JAVA为了区分分隔符 需要两个 " \ \ " 表示路径)
windows 和DOS系统默认使用 ”\“来表示
UNIX 和 URL使用”/“来表示
相对路径 : 相对于某个位置开始
public File(String parent,String child)
以parent 为父路径 child 为子路径 创建File 对象
public FIle(File parent,String child)
根据一个父File 对象和子文件路径创建File对象
三个构造器举例
File f =new File("1.txt");//相对路径
File f1 =new File("C:\\Users\\尤呈祥\\Desktop\\1.txt");//构造器一
File f3 =new File("C:\\Users","尤呈祥");//构造器二
File f4= new File (f3,"1.txt");//构造器三
File 类的获取功能
类型 | 方法 | 功能 |
---|---|---|
public String | getAbsolutePath() ; | 获取绝对路径 |
public String | getPath(); | 获取路径 |
public String | getNanme(); | 获取名称 |
public String | getParent(); | 获取上层文件目录 若无 返回null |
public long | length(); | 获取文件长度 即字节数 不能获取目录的长度 |
public String[] | list(); | 获取指定目录下的所有文件或者文件目录的名称数据 |
public File[] | listFies(); | 获取指定目录下的所有文件或者文件目录的FIle 数组 |
public Boolean | renameTo(File dest); | 把文件重命名为指定的文件路径(被改名的要存在 要改的那个名的文件需要不存在) |
File 类的判断功能方法
类型 | 方法 | 作用 |
---|---|---|
public boolean | isDirector() | 判断是否是文件目录 |
public boolean | isFile() | 判断是否是文件 |
public boolean | exists() | 判断是否存在 |
public boolean | canRead() | 判断是否可读 |
public boolean | canWrite() | 判断是否可写 |
public boolean | isHidden() | 判断是否隐藏 |
File 类的创建功能方法
注意:如果你创建文件或者文件目录没有写盘符路径 那么默认在项目路径下
类型 | 作用 | 方法 |
---|---|---|
public boolean | createNewFile() | 创建文件 若文件存在则不创建 返回false |
public boolean | mkdir() | 创建文件目录 若存在则不创建 此文件的上层目录不存在也不创建 |
public booelan | mkdirs() | 创建文件目录 如果上层文件目录不存在 一并创建 |
FIle类的删除功能
注意: java中删除不走回收站 如果要删除一个文件目录 请注意该文件目录内不能包含文件或者文件目录
类型 | 作用 | 方法 |
---|---|---|
public boolean | delete() | 删除文件或者文件夹 |
File类中涉及到关羽文件或者文件目录的创建 删除 重命名 修改时间 文件大小等方法 并未涉及到写入或读取文件内容的操作 ,如果需读取或者写入文件内容必须使用IO流来完成
后续File类的对象常作为 参数传递到流的构造器中 指明读取或写入的 ”终点"
JAVA IO
输入input : 读取外部数据到程序中
输出output 将程序数据输出到磁盘光盘等存储设备中
流的分类
按操作数据单位不同 分为: 字节流(8bit) 字符流(16bit)
按数据流的刘翔不同分为: 输入流,输出流
按流的角色的不同分为: 字节流,处理流。
抽象基类 | 字节流 | 字符流 |
---|---|---|
输入流 | InputStream | Reader |
输出流 | OutputStream | Writer |
IO流体系
分类 | 字节输入流 | 字符输入流 | 字符输入流 | 字符输出流 |
---|---|---|---|---|
抽象基类 | InputStream | OutputStream | reader | Wriiter |
访问文件 | FileInputStream | FileOutputStream | FileReader | FileWriter |
访问数组 | ByteArrayInputStream | ByteArrayOuputStream | CharArrayReader | CharArrayWriter |
访问管道 | PipedlnputStream | PipedOutputStream | PipedReader | PipedWriter |
访问字符串 | StringReader | StringWriter | ||
缓冲流 | BufferedInputSream | BufferedOutoutStream | BufferedReader | BufferedWriter |
转换流 | InputStreamReader | OutputStreamWeiter | ||
对象流 | ObjectInpuStream | ObjectOutputSrtream | ||
FilerInputStream | FileterOutPutStream | FilterReader | FilterWriter | |
打印流 | PrintStream | PrintWriter | ||
退回输入流 | PushbackInputStream | PushbackReader | ||
特殊流 | DataInputStream | DataOutputStream |
流的分类
操作数据单位 ::字节流 字符流
数据的流向 :输入流 输出流
流的角色 :节点流 处理流
read();返回读入的一个字符 如果达到文件末尾返回-1(阿斯克码)
读入的文件一定要存在 不然就会报文件找不到的异常
读数据流程
1.File类的实例化
2,FileReader流的实例化
3.读入操作
4.资源关闭
public static void main(String[] args) throws IOException {
//将文件内容读入程序 并输出到控制台
//实例化File类对象 指明要操作的文件
File f = new File("1.txt");//相对路径
//用到输入字符流
FileReader f1 =new FileReader(f);
//数据读入过程
int read = f1.read();
while(read!=-1)
{
System.out.print( (char)read);
read =f1.read();
}
//4.流的关闭操作
f1.close();
}
关于异常处理 :
为了保证流资源一定执行关闭操作 需要执行try catch 处理异常
public static void main(String[] args) {
//将文件内容读入程序 并输出到控制台
//实例化File类对象 指明要操作的文件
//用到输入字符流
FileReader f1 = null;
try {
File f = new File("1.txt");//相对路径
f1 = new FileReader(f);
//数据读入过程
int read = f1.read();
while(read!=-1)
{
System.out.print( (char)read);
read =f1.read();
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally
{
try {//未实例化的不需要关闭因此需要判断是否实例化了
if(f1!=null)
{
f1.close();
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
//4.流的关闭操作
}
read(char [] c) 返回每次读入到c数组中的字符个数 如果达到文件末尾 返回-1
public static void main(String[] args) throws IOException {
//对read ()操作升级 使用read 重载方法
//1.File类的实例化
File f1 =new File ("1.txt");
//2,FileReader流的实例化
FileReader ft = new FileReader(f1);
//3.读入操作
char[] c =new char [5];
int len;
while((len=ft.read(c))!=-1)
{
for(int i=0;i<len ;i++)
{
//System.out.println(ft.read(c));
System.out.print(c[i]);
}
}
//4.资源关闭
ft.close();
}
错误
错误
while((len=ft.read(c))!=-1)
{
String str =new String (c);// 把字符数组转换成字符串 数组是覆盖 会有没覆盖到的
System.out.print(str);
正确
while((len=ft.read(c))!=-1)
{
String str =new String (c,0,len); 把字符数组c 从 0开始 转换 len个长度成为字符串
System.out.print(str);
}
写出数据
1,提供File类的对象指明写出到的文件
2 提供FileWriter 的对象 用于数据的写出
3. 写出的操作
4, 流资源的关闭
说明 : 输出操作 对应的File 文件可以不存在 不存在的话 会自动创建此文件(Eclipse 可能不显示 右键项目点击Refresh刷新)
如果存在, 若 声明FileWriter fw =new FileWriter(f); 没有给定true 或false 则默认覆盖
若FileWriter fw =new FileWriter(f ,true); 则是在默认文件上的添加 false 亦然
(这种异常处理的方式不对 这样好理解 异常处理需要使用try-catch ) 使 不管抛不抛异常都让 资源关闭
public static void main(String[] args) throws IOException {
//1,提供File类的对象指明写出到的文件
File f = new File("2.txt");
//2 提供FileWriter 的对象 用于数据的写出
FileWriter fw =new FileWriter(f);
//3.写出的操作
fw.write("I have a dream");
//4,流资源的关闭
fw.close();
}
读入和写出操作连在一起
先读后写
1.创建File 类 对象 两个 指明读入写出的文件
2. 创建流的对象 输入出 和 输出流
3. 数据的写入的写出操作
4. 关闭资源流
(异常也是没有正确处理)
不能使用字符流来处理图片等字节数据
public static void main(String[] args) throws IOException {
//创建File 类 对象 两个 指明读入写出的文件
File f =new File("1.txt");
File f1 =new File("2.txt");
// 2. 创建流的对象 输入出 和 输出流
FileReader fr =new FileReader(f);
FileWriter fw = new FileWriter(f1,true);
//3 ,数据的写入的写出操作
char [] c =new char[3];
fr.read();
int len ;
fw.write("\n");
while((len =fr.read(c))!=-1)
{
String str =new String(c,0,len);
fw.write(str);
}
//4 . 关闭资源流
fw.close();
fr.close();
}
图片或视频
要使用字节流
文本文件如果使用字节流会出现乱码
实现对文件的复制
1.造文件
2.造流
3,读数据
4.关闭资源
public static void main(String[] args) throws IOException {
//测试FileInputStream 和FileOutputStream的使用
//1.造文件
File f =new File("2.gif");
File f1 =new File ("3.gif");
//2.造流
FileInputStream fis =new FileInputStream(f);
FileOutputStream fos = new FileOutputStream(f1);
//3,读数据
byte[] b=new byte[20];
int len;
while((len=fis.read(b))!=-1)
{
fos.write(b,0, len);//把b 从 0 到 len 写入
}
fis.close();
fos.close();
}
结论 : 对于文本文件(.txt java, c , cpp)使用字符流
对于非文本文件(.jpg ,.mp3 mp4, avi,doc ,ppt)使用字节流处理
可以封装成一个方法
缓冲流
1.BufferedInputStream
2.BufferedOutputStream
3.BufferedReader
4.BufferedWriter
作用: 提高流的读取写入速度
1.造文件
2.1造节点流
2.2造缓冲流
3 读取 写入操作
4.资源关闭: 先关闭外层流(缓冲流)再关内层的流 关闭外层流的同时 内层流也会自动的进行关闭 关于内层流的关闭我们可以省略
(下面代码异常还没处理)
public static void main(String[] args) throws IOException {
//实现非文本文件复制
File f =new File("2.gif");
File f1 =new File("4.gif");
//造文件
//2.1 造节点流
FileInputStream fis =new FileInputStream(f);
FileOutputStream fos = new FileOutputStream(f1);
//造缓冲流
BufferedInputStream bis =new BufferedInputStream(fis);
BufferedOutputStream bos =new BufferedOutputStream(fos);
//3,读取 写入
byte [] b =new byte [10];
int len ;
while ((len=bis.read(b))!=-1)
{
bos.write(b,0,len);
}
//资源关闭: 先关闭外层流(缓冲流)再关内层的流
bis.close();
bos.close();
//fos.close();
//fis.close();
}
bos.flush() 刷新缓冲区
提高读写速度的的的原因 有一个缓冲区当读满时一次性取出来提高速度
缓冲流处理
public static void main(String[] args) throws IOException {
// File f = new File("1.txt");
// File f1 = new File ("5.txt");
// FileReader fr =new FileReader(f);
// FileWriter fw = new FileWriter(f1);
// BufferedReader br = new BufferedReader(fr);
// BufferedWriter bw =new BufferedWriter(fw);
//可以使用匿名
BufferedReader br = new BufferedReader(new FileReader(new File("1.txt")));
BufferedWriter bw =new BufferedWriter(new FileWriter(new File("5.txt")));
char [] c = new char [5];
int len;
while((len = br.read(c))!=-1)
{
String str =new String (c,0,len);
bw.write(str);
}
br.close();
bw.close();
}
也可以使用方式二(默认不换行)
String data;
while((data=br.readLine())!=null)
{
bw.write(data);
bw.newLine();//提供换行的操作
}
转换流
1.InputStreamReader 将一个字节的输入流转换为字符的输入流
2.OutputStreamwriter 将一个字符的输出流转换为字节的输出流
作用: 提供字节流与字符流之间的转换
3
解码:字节 字节数组 —>字符数组 字符串
编码 : 字符数组 字符串---->字节 字节数组
public static void main(String[] args) throws IOException {
FileInputStream fis =new FileInputStream("1.txt");
InputStreamReader isr = new InputStreamReader(fis);//使用系统默认字符集
//指明了字符集 使用哪个字符集取决于文件保存时使用的字符集
//InputStreamReader isr1 = new InputStreamReader(fis,"UTF-8");
int len;
char c [] =new char[3];
while((len=isr.read(c))!=-1)
{
String str = new String(c,0,len);
System.out.print(str);
}
isr.close();
}
字符集
##常见的编码表
ASCII:美国标准信息交换表。用一个字节的7位可以表示。
ISO8859-1:拉丁码表。欧洲码表,用一个字节8位表示。
GB2312:中国的中文编码表。最多支持两个字节编码所有字符。
GBK:中国的中文编码表升级版,加入了更多的中文字符,最多两个字节编码。
Unicode:国际标准码,融入了目前人类对的所有字符。每一个字符对应唯一的字符码。两个字节表示。
UTF-8:变长的编码方式,可用1-4个字节表示所有的字符。
##注:
1.GB2312 和 GBK 通过首位判断当前字符是占用1个还是2个字符。0表示1个,1表示2个。
2.Unicode并不特别完美,存在一定的问题如:
英文符号只占用一个字节,如何区分Unicode和ascii?
如果使用最高位区分占用1个字节还是2个字节,就会少很多值无法显示。
3.UTF-8就是每次8个位传输数据,UTF-16就是每次16个位。
4.Unicode只是定义了一个字符集,规定了每个字符对应的编号,具体存储长成什么样子取决于编码方案。(UTF-8,UTF-16)
对象流
用于存储和读取基本数据类型数据或对象的处理流 。它的强大之处就是可以把JAVA中的对象写入到数据源中也能把对象从数据源中还原回来
序列化": :ObjectOutputStream 类奥村基本类型数据或对象的机制
反序列化ObjectInputStream类读取基本类型数据或对象的机制
注意: 不能序列化static 和 transient修饰的 成员变量
对象序列化机制 : 允许把内存中的JAVA对象转换成平台无关的二进制流,从而允许把这种二进制流持久地保存在磁盘上 或通过网络将这种二进制流传输到另一个网络节点 当其它的程序获取了这种二进制流 就可以恢复成原来的JAVA对象
public static void main(String[] args) throws FileNotFoundException, IOException, ClassNotFoundException {
//序列化过程:将内存中的JAVA对象保存到磁盘中或通过网络传输出去
// 使用ObjectOutputStream 实现
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("1.dat"));
oos.writeObject(new String("我爱吃饭"));
oos.flush();
oos.close();
//反序列化过程
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("1.dat"));
Object obj = ois.readObject();
String str =(String) obj;
System.out.println(str);
ois.close();
}
要想一个JAVA对象可序列化需要满足
1.需要实现Seriaizable接口(该接口没有方法 是一个标识接口)
2.在类中要声明一个全局常量 public static final long serialVersionUID=12737812637;(数字随便写的)
3.除了当前类要实现Serializable接口外 还必须保证其内部所有属性也必须是可序列化的。(默认基本数据类型都是可序列化的)