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的更多相关文章

  1. (25)IO流之转换流InputStreamReader和OutputStreamWriter

    InputStreamReader:字节到字符的桥梁. OutputStreamWriter:字符到字节的桥梁. 它们有转换作用,而本身又是字符流.所以在构造的时候,需要传入字节流对象进来. 构造函数 ...

  2. java中的IO流(输入流与输出流)概述与总结

    Java中IO流,输入输出流概述与总结 总结的很粗糙,以后时间富裕了好好修改一下. 1:Java语言定义了许多类专门负责各种方式的输入或者输出,这些类都被放在java.io包中.其中, 所有输入流类都 ...

  3. IO流 简介 总结 API 案例 MD

    目录 IO 流 简介 关闭流的正确方式 关闭流的封装方法 InputStream 转 String 的方式 转换流 InputStreamReader OutputStreamWriter 测试代码 ...

  4. Java IO流详尽解析

    流的概念和作用 学习Java IO,不得不提到的就是JavaIO流. 流是一组有顺序的,有起点和终点的字节集合,是对数据传输的总称或抽象.即数据在两设备间的传输称为流,流的本质是数据传输,根据数据传输 ...

  5. Java笔记(二十六)……IO流上 字节流与字符流

    概述 IO流用来处理设备之间的数据传输 Java对数据的操作时通过流的方式 Java用于操作流的对象都在IO包中 流按操作的数据分为:字节流和字符流 流按流向不同分为:输入流和输出流 IO流常用基类 ...

  6. 常用的IO流

    常用的IO流 •根据处理数据类型的不同分为:字节流和字符流 •根据数据流向不同分为:输入流和输出流 字节流:字节流以字节(8bit)为单位,能处理所有类型的数据(如图片.avi等). 字节输入流:In ...

  7. JavaSE_ IO流 总目录(19~22)

    JavaSE学习总结第19天_IO流119.01 集合的特点和数据结构总结19.02 如何选择使用哪种集合19.03 集合常见功能和遍历方式总结19.04 异常的概述和分类19.05 JVM默认处理异 ...

  8. IO流大总结

    - - - - - - - - - - - - - - - 写在前面 - - - - - - - - - - - - - - - 1.概念 IO流用来处理设备之间的数据传输 Java对数据的操作是通过 ...

  9. 我爱Java系列之《JavaEE面试宝典》---【IO流面试总结】

    1.什么是比特(Bit),什么是字节(Byte),什么是字符(Char),它们长度是多少,各有什么区别 答案 Bit最小的二进制单位 ,是计算机的操作部分 取值0或者1 Byte是计算机操作数据的最小 ...

随机推荐

  1. 我的常用笔记(GetAndroid,ADBDemo,GetSJ,GetTB)

    一.授权相关格式(GetAndroid,ADBDemo,GetTB,GetSJ) [Mac]ID=0,     Mac=9918D2A363,    EndTime=2018-12-30 15:45: ...

  2. 【Unix网络编程】chapter8基本UDP套接字编程

    chapter8基本UDP套接字编程 8.1 概述 典型的UDP客户端/服务端的函数调用 8.2 recvfrom和sendto函数 #include <sys/socket.h> ssi ...

  3. Chapter1:Qt概念

    信号和槽1.信号与槽机制的连接方式(1):一个信号可以与另一个信号相连,代码如下: connect(Object1,SIGNAL(signal1),Object2,SIGNAL(signal1)); ...

  4. golang 入门之struct继承,嵌套

    package main import "fmt" type Jocongmin struct{ Name string Home string Want string } fun ...

  5. cas server

    Tomcat: V8.5.x Java: 1.8 x64 MySQL: 5.5.x OS: Win10 x64 I. war 0. clone git clone https://github.com ...

  6. Django中的中间件(middleware)

    中间件: 在研究中间件的时候我们首先要知道 1 什么是中间件? 官方的说法:中间件是一个用来处理Django的请求和响应的框架级别的钩子.它是一个轻量.低级别的插件系统,用于在全局范围内改变Djang ...

  7. jsfiddle将demo设置为public公开的

    jsfiddle的demo虽然可以通过链接分享给所有人,但是进入个人主页是没有的,需要将项目设置为公开public的 根据提示,打开demo项目页==>左侧菜单==>填写标题和描述==&g ...

  8. 操作MySQL

    1修改MySQL表结构数据类型:ALTER TABLE 表名 MODIFY 字段名 VARCHAR(50); 2.删除表:DROP TABLE 表名: 3.now() 日期时间函数 4.sysdate ...

  9. 重识linux-守护进程,系统服务,daemons

    重识linux-守护进程,系统服务,daemons 1分类 分为 单独的守护进程 和超级守护进程 2命名 服务的名称被创建之后,被挂上linux使用,通常在服务的名称之后会加上一个d,例如at和cro ...

  10. FreeMarker生成Word文档

    FreeMarker简介: FreeMarker是一款模板引擎:即一种基于模板和要改变的数据,并用来生成输出文本(HTML网页.电子邮件.配置文件.源代码等)的通用工具,它不是面向最终用户的,而是一个 ...