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. 怎么查看SAS到期时间

    通过以下命令,可以查看SAS到期时间: proc setinit; run;

  2. (转)C#SocketAsyncEventArgs实现高效能多并发TCPSocket通信

    原文地址:http://freshflower.iteye.com/blog/2285272.http://freshflower.iteye.com/blog/2285286 一)服务器端 说到So ...

  3. Elasticsearch 2.4 安装

    Ubuntu 18.04.1 Part I. Elasticsearch 1. install JDK Note: >1.8 reference: <Linux下安装Tomcat> ...

  4. js第四天学习小结:

    (1)函数的四种形式小结: 无参无返回值 function tellstory(){     console.log("从前有座山");     console.log(" ...

  5. vmware workstation14嵌套安装kvm

    1.前言 我在2017-11-06使用virtualbox安装了centos,然后嵌套kvm(win7),链接地址如下: https://www.cnblogs.com/tcicy/p/7790956 ...

  6. [TJOI2015]弦论(后缀自动机)

    /* 一道在树上乱搞的题目 建立出parent树来, 然后就能搞出每个节点往后能扩展出几个串, 至于位置不同算同一个的话就强制让right集合大小为1即可 然后在树上类比权值线段树找第k大26分统计一 ...

  7. 常见sql注入的防范总结

    在平时的开发过程中,我们可能很少会刻意的去为项目做一个sql注入的防范,这是因为你可能因为使用了某些框架,而无意间已经有了对应sql注入的一些防范操作(比如mybatis使用#{XX}传参,属于预编译 ...

  8. windows 下安装 docker

    1. 使用阿里云的镜像进行安装: http://mirrors.aliyun.com/docker-toolbox/windows/docker-toolbox/ 2. 安装完成后点击图标 “Dock ...

  9. lunix nginx安装 报错页面 状态码

    web服务器软件IIS  (windows底下的web服务器软件) Nginx (Linux底下新一代高性能的web服务器)  Tengine   www.taobao.com  这是淘宝 Apach ...

  10. for循环执行时在,每执行一次for循环中弹出提示框,延时问题

    在需求中,ajax的返回值,根据数组内容的长度去做循环,每循环一次弹出提示框,发现for循环的执行速度非常之快,想到了延时,但是在for循环中延时并不能解决这个问题. 查到setTimeout的递归处 ...