25. IO流.md
IO分类:
字节流&字符流的IO操作:
- 字节流:输入输出和字符有关的操作
- IO类:FileInputStream和FileOutPutStream;缓冲:BufferedInputStream和BufferedOutStream
- 字符流:输入输出和字符无关的操作
- IO类:FileReader和 FileWriter;缓冲:BufferedReader和BufferedWriter
1.FIle类
1.1目录分隔符
不同机器上目录分隔符是不一样的,所以用File类的成员变量separator来表示:
public static final String separator = "" + separatorChar;
注意:windows上认两种目录分隔符,也就是正(/)反(\)都可以
1.2常用方法
- 创建:
createNewFile() 在指定位置创建一个空文件,成功就返回true,如果已存在就不创建然后返回false
mkdir() 在指定位置创建目录,这只会创建最后一级目录,如果上级目录不存在就抛异常。
mkdirs() 在指定位置创建目录,这会创建路径中所有不存在的目录。
renameTo(File dest) 重命名文件或文件夹,也可以操作非空的文件夹,文件不同时相当于文件的剪切,剪切时候不能操作非空的文件夹。移动/重命名成功则返回true,失败则返回false。
- 删除:
delete() 删除文件或一个空文件夹,如果是文件夹且不为空,则不能删除,成功返回true,失败返回false。
deleteOnExit() 在虚拟机终止时,请求删除此抽象路径名表示的文件或目录,保证程序异常时创建的临时文件也可以被删除
- 判断:
exists() 文件或文件夹是否存在。
isFile() 是否是一个文件,如果不存在,则始终为false。
isDirectory() 是否是一个目录,如果不存在,则始终为false。
isHidden() 是否是一个隐藏的文件或是否是隐藏的目录。
isAbsolute() 测试此抽象路径名是否为绝对路径名。
- 获取:
getName() 获取文件或文件夹的名称,不包含上级路径。
getPath() 返回绝对路径,可以是相对路径,但是目录要指定
getAbsolutePath() 获取文件的绝对路径,与文件是否存在没关系
length() 获取文件的大小(字节数),如果文件不存在则返回0L,如果是文件夹也返回0L。
getParent() 返回此抽象路径名父目录的路径名字符串;如果此路径名没有指定父目录,则返回null。
lastModified() 获取最后一次被修改的时间。
文件夹相关:
staic File[] listRoots() 列出所有的根目录(Window中就是所有系统的盘符)
list() 返回目录下的文件或者目录名,包含隐藏文件。对于文件这样操作会返回null。
list(FilenameFilter filter) 返回指定当前目录中符合过滤条件的子文件或子目录。对于文件这样操作会返回null。
listFiles() 返回目录下的文件或者目录对象(File类实例),包含隐藏文件。对于文件这样操作会返回null。
listFiles(FilenameFilter filter) 返回指定当前目录中符合过滤条件的子文件或子目录。对于文件这样操作会返回null
2.FileInputStream类
2.1读取文件
使用FileInputStream类可以用read方法,这个方法的不同重载都可以实现读取文件:
package per.liyue.code.filedemo;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
public class Demo1 {
public static void main(String[] args) throws IOException {
// TODO Auto-generated method stub
File file = new File("");
String separator = file.separator;
ReadFile1(separator);
ReadFile2(separator);
}
//直接读取
public static void ReadFile1(String separator) throws FileNotFoundException, IOException {
File fileOpen = new File("d:" + separator + separator + "a.txt");
if (fileOpen.exists()) {
FileInputStream in = new FileInputStream(fileOpen);
//read方法
int concent = 0;
System.out.println("read方法while读取:");
while(-1 != concent){
concent = in.read();
System.out.print((char)concent);
}
in.close();
}
}
//byte数组读取
public static void ReadFile2(String separator) throws FileNotFoundException, IOException {
File fileOpen = new File("d:" + separator + separator + "a.txt");
if (fileOpen.exists()) {
FileInputStream in = new FileInputStream(fileOpen);
//byte方法-一般数组大小为1024倍数
byte[] b = new byte[2];
System.out.println("byte方法while读取:");
int length = 0;
while(-1 != (length = in.read(b))){
System.out.print(new String(b, 0, length));
}
in.close();
Arrays
}
}
}
读取文件的注意事项
使用byte的方法效率高!
重要的事情说三遍:一定要关闭资源!一定要关闭资源!一定要关闭资源!
3.FileOutputStream类
FileOutputStream 的write方法可以写:
每次写之前先清空目标文件
public static void WriteNew(String separator) throws FileNotFoundException, IOException {
File fileWrite = new File("d:" + separator + separator + "a.txt");
FileOutputStream out = new FileOutputStream(fileWrite);
String concent = "1234567890abcdef";
out.write(concent.getBytes());
out.close();
}
每次追加到最后
public static void WriteEnd(String separator) throws FileNotFoundException, IOException {
File fileWrite = new File("d:" + separator + separator + "a.txt");
FileOutputStream out = new FileOutputStream(fileWrite, true);
String concent = "1234567890abcdef";
out.write(concent.getBytes());
out.close();
}
拷贝文件
拷贝文件需要边读边拷写:
public static void main(String[] args) throws IOException {
// TODO Auto-generated method stub
File file = new File("");
String separator = file.separator;
//缓冲
byte[] b = new byte[1024];
//拷贝源
File fileSour = new File("D:" + separator + "a.bmp");
FileInputStream fileIn = new FileInputStream(fileSour);
//目标源
File fileTar = new File("D:" + separator + "b.bmp");
FileOutputStream FileOut = new FileOutputStream(fileTar, true);
//开始拷贝
int concent = 0;
while(-1 != (concent = fileIn.read(b))){
FileOut.write(b, 0, concent);
//这样拷贝会增大文件,因为最后不满1024也按照1024拷贝了
//out.write(b);
}
fileIn.close();
FileOut.close();
}
4.缓冲流
4.1 BufferedInputStream
BufferedInputStream其实只是在内部维护了一个8KB的字节数组,快的原因和上面byte[]一样,每次从缓冲数组中读取,减少IO次数
BufferedInputStream的close实际上是调用父类的方法。
4.2 BufferedOutputStream
BufferedOutputStream的内部也是维护了一个字节数组。
BufferedOutputStream真正写入文件的时机:
调用其close方法
调用其flush方法
当内部缓冲数组满了也会写入
5.字符流
字符流的操作和字节流类似
5.1BufferedReader
5.2 BufferedWriter
6.序列流
- Serializable称作标志接口,对象的输入输出必须实现此接口,称作序列化。
- 这个接口没有方法,输出中只需要实现此接口!
- 对象的反序列化并不会创建对象
- 反序列化读取的时候,使用serialVersionUID来判断是否是同一个序列化对象,如果反序列化的时候,类对象经过变更,不同于序列化时候,反序列化就会失败。对于需要的情况,可以使用默认的serialVersionUID(在类名上Ctrl+1`)来避免无法序列化的问题,但是要注意,反序列化必须对应的是同一个类
- 如果序列化的类中包含了另一个没有序列化的类是不可以的
package per.liyue.code.serializabledemo;
import java.io.Serializable;
public class Employee implements Serializable{
//使用默认的serialVersionUID
private static final long serialVersionUID = 1L;
private int id;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
private int age;
}
package per.liyue.code.serializabledemo;
import java.io.Serializable;
public class User implements Serializable{
//使用默认的serialVersionUID
private static final long serialVersionUID = 1L;
private String name;
//可以下序列化写文件以后,增加这个成员变量,用反序列化读取实验serialVersionUID的作用
//private int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
// TODO Auto-generated method stub
return "用户的名字是:" + this.name;
}
}
package per.liyue.code.serializabledemo;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
public class DemoPrint {
public static void main(String[] args) throws IOException, ClassNotFoundException{
//序列化对象
WriteData();
//反序列化对象
ReadData();
}
public static void ReadData() throws IOException, FileNotFoundException, ClassNotFoundException {
ObjectInputStream inStream = new ObjectInputStream(new FileInputStream(new File("D:\\a.txt")));
//这里直接强转了,并没有创建新的类对象,克隆的时候也是一样的没有创建类对象
User u = (User)inStream.readObject();
System.out.println(u);
//如果下面反序列化的是Employee类,那么必定会报错
// Employee u = (Employee)inStream.readObject();
// System.out.println(u);
inStream.close();
}
public static void WriteData() throws IOException, FileNotFoundException {
ObjectOutputStream outStream = new ObjectOutputStream(new FileOutputStream(new File("D:\\a.txt")));
User u = new User();
u.setName("张三");
outStream.writeObject(u);
outStream.close();
}
}
如果一个成员变量不想被序列化,可用关键字**transient **修饰:
//使用transient关键字修饰后不会被序列化
private transient String id;
7.配置文件:Properties类
这个类是集合体系下的类(uitl),基础map类。
7.1写文件
- 写的时候要注意,api推荐使用 setProperty 方法而不是Properties类继承map的put方法,因为前者有类型检查,强制使用String类安全
- 传入store方法的stream要注意,默认Java使用ISO 8859-1,不支持中文,所以要用字符流来写而不是字节流
7.2读文件
Properties类继承于map,所以用迭代器可遍历
7.3修改文件
修改Properties类对象后,要写入文件才能生效!
Demo:
package per.liyue.code.properities;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Map.Entry;
import java.util.Properties;
import java.util.Set;
public class ProperitiesMain {
public static void main(String[] args) throws IOException{
Properties p = new Properties();
WriteProperties(p);
ReadProperties(p);
UpdateProperties(p);
}
public static void UpdateProperties(Properties p) throws IOException {
p.setProperty("张三", "000");
//必须要写进去才生效,但是会覆盖原来的
p.store(new FileWriter(new File("D:\\a.properties")), "这是一个属性文件例子");
}
public static void ReadProperties(Properties p) throws IOException, FileNotFoundException {
p.load(new FileReader(new File("D:\\a.properties")));
//注意,这里必须写明是Object类
Set<Entry<Object, Object>> entrys = p.entrySet();
for (Entry<Object, Object> entry : entrys) {
System.out.println("键:" + entry.getKey() + "值:" + entry.getValue());
}
}
public static void WriteProperties(Properties p) throws IOException {
p.setProperty("张三", "123");
p.setProperty("李四", "456");
p.setProperty("王五", "789");
p.store(new FileWriter(new File("D:\\a.properties")), "这是一个属性文件例子");
}
}
8.打印流
可以对System.out.println重新定位输出对象到文件
System.setOut(new PrintStream(new File("D:\\errorlog.txt")));
System.out.println("输出到文件");
异常的情况也是一样
try {
//...
} catch (Exception e) {
//追加模式,否则会每次覆盖原来的日志
PrintStream error = new PrintStream(new FileOutputStream("D:\\errorlog.txt"), true);
e.printStackTrace(error); }
9.转换流
InputStreamReader和OutputStreamReader是字符流FileReader和FileWriter的父类。用于字节流和字符流的转换。在网络编程中用的比较多。
- InputStreamReader:字节流->字符流
- OutputStreamWriter:字符流->字节流
25. IO流.md的更多相关文章
- (25)IO流之转换流InputStreamReader和OutputStreamWriter
InputStreamReader:字节到字符的桥梁. OutputStreamWriter:字符到字节的桥梁. 它们有转换作用,而本身又是字符流.所以在构造的时候,需要传入字节流对象进来. 构造函数 ...
- java中的IO流(输入流与输出流)概述与总结
Java中IO流,输入输出流概述与总结 总结的很粗糙,以后时间富裕了好好修改一下. 1:Java语言定义了许多类专门负责各种方式的输入或者输出,这些类都被放在java.io包中.其中, 所有输入流类都 ...
- IO流 简介 总结 API 案例 MD
目录 IO 流 简介 关闭流的正确方式 关闭流的封装方法 InputStream 转 String 的方式 转换流 InputStreamReader OutputStreamWriter 测试代码 ...
- Java IO流详尽解析
流的概念和作用 学习Java IO,不得不提到的就是JavaIO流. 流是一组有顺序的,有起点和终点的字节集合,是对数据传输的总称或抽象.即数据在两设备间的传输称为流,流的本质是数据传输,根据数据传输 ...
- Java笔记(二十六)……IO流上 字节流与字符流
概述 IO流用来处理设备之间的数据传输 Java对数据的操作时通过流的方式 Java用于操作流的对象都在IO包中 流按操作的数据分为:字节流和字符流 流按流向不同分为:输入流和输出流 IO流常用基类 ...
- 常用的IO流
常用的IO流 •根据处理数据类型的不同分为:字节流和字符流 •根据数据流向不同分为:输入流和输出流 字节流:字节流以字节(8bit)为单位,能处理所有类型的数据(如图片.avi等). 字节输入流:In ...
- JavaSE_ IO流 总目录(19~22)
JavaSE学习总结第19天_IO流119.01 集合的特点和数据结构总结19.02 如何选择使用哪种集合19.03 集合常见功能和遍历方式总结19.04 异常的概述和分类19.05 JVM默认处理异 ...
- IO流大总结
- - - - - - - - - - - - - - - 写在前面 - - - - - - - - - - - - - - - 1.概念 IO流用来处理设备之间的数据传输 Java对数据的操作是通过 ...
- 我爱Java系列之《JavaEE面试宝典》---【IO流面试总结】
1.什么是比特(Bit),什么是字节(Byte),什么是字符(Char),它们长度是多少,各有什么区别 答案 Bit最小的二进制单位 ,是计算机的操作部分 取值0或者1 Byte是计算机操作数据的最小 ...
随机推荐
- 怎么查看SAS到期时间
通过以下命令,可以查看SAS到期时间: proc setinit; run;
- (转)C#SocketAsyncEventArgs实现高效能多并发TCPSocket通信
原文地址:http://freshflower.iteye.com/blog/2285272.http://freshflower.iteye.com/blog/2285286 一)服务器端 说到So ...
- Elasticsearch 2.4 安装
Ubuntu 18.04.1 Part I. Elasticsearch 1. install JDK Note: >1.8 reference: <Linux下安装Tomcat> ...
- js第四天学习小结:
(1)函数的四种形式小结: 无参无返回值 function tellstory(){ console.log("从前有座山"); console.log(" ...
- vmware workstation14嵌套安装kvm
1.前言 我在2017-11-06使用virtualbox安装了centos,然后嵌套kvm(win7),链接地址如下: https://www.cnblogs.com/tcicy/p/7790956 ...
- [TJOI2015]弦论(后缀自动机)
/* 一道在树上乱搞的题目 建立出parent树来, 然后就能搞出每个节点往后能扩展出几个串, 至于位置不同算同一个的话就强制让right集合大小为1即可 然后在树上类比权值线段树找第k大26分统计一 ...
- 常见sql注入的防范总结
在平时的开发过程中,我们可能很少会刻意的去为项目做一个sql注入的防范,这是因为你可能因为使用了某些框架,而无意间已经有了对应sql注入的一些防范操作(比如mybatis使用#{XX}传参,属于预编译 ...
- windows 下安装 docker
1. 使用阿里云的镜像进行安装: http://mirrors.aliyun.com/docker-toolbox/windows/docker-toolbox/ 2. 安装完成后点击图标 “Dock ...
- lunix nginx安装 报错页面 状态码
web服务器软件IIS (windows底下的web服务器软件) Nginx (Linux底下新一代高性能的web服务器) Tengine www.taobao.com 这是淘宝 Apach ...
- for循环执行时在,每执行一次for循环中弹出提示框,延时问题
在需求中,ajax的返回值,根据数组内容的长度去做循环,每循环一次弹出提示框,发现for循环的执行速度非常之快,想到了延时,但是在for循环中延时并不能解决这个问题. 查到setTimeout的递归处 ...