Java IO 编程

提供了大量的Input和output 方法。

一个类File 和五个接口四个抽象类

File 类

唯一一个与文件本身操作的类,这个类可以进行操作文件路径的指派,可以创建或者删除文件,还可以获取文件的相关内容信息。

No 方法名称 类型
01 File(String pathname) 构造 设置要操作文件的完整路径
02 File(File parent, String child) 构造 设置要操作文件的父目录和文件
03 public boolean createNewFile() throws IOException 方法 创建文件
04 public boolean exists() 方法 判断文件是否存在
05 public boolean delete() 方法 文件删除

文件的操作

public class TestDemo {public static void main(String[] args) throws  IOException {File file = new File("D:"+File.separator+"demo.txt");if (file.exists()){file.delete();System.out.println("文件已删除");}else{file.createNewFile();System.out.println("文件已经添加");}}
}

问题1:当前文件进行了磁盘文件的操作,添加删除文件有延迟。

问题2: java 本身是跨平台的编程模式,这种情况必须考虑各个系统的路径问题

*    windows 系统的路径分隔符 ”\“
*   Unix, 类Unix(Linux\Macos\AIX) 路径分隔符为“/”

但是在编写路径分隔符的时候,如果每次都使用大量的“\\” 或者“//” 进行转义处理。

public static final String separator

正确的编写方法

File file = new File("D:"+File.separator+"demo.txt");

在以后的编写代码中,所有的路径分隔符尽量都通过常量来进行定义

文件目录的操作

当前的程序是直接在“D” 盘的根目录中创建,但是很多时候,文件路径并不存在,

执行程序的时候会出现以下问题,系统找不到指定路径。

如果想要进行目录的创建,需要使用File 类的以下几种方法

No 方法名称 类型
01 public boolean mkdir() method 只创建单级目录
02 public boolean mkdirs() method 创建多级目录
03 public String getParent() method 获取父路径的信息(String)
04 public File getParentFile() method 获取父路径的File实例

范例:进行父目录的创建。

public class TestDemo {public static void main(String[] args) throws  IOException {File file = new File("D:"+File.separator+"demo"+File.separator+"demo.txt");if(!file.getParentFile().exists()){//判断父目录是否存在file.getParentFile().mkdirs();//创建所有的父路径}if (file.exists()){file.delete();System.out.println("文件已删除");}else{file.createNewFile();System.out.println("文件已经添加");}}
}

多线程访问时,重复判断父目录是否存在浪费系统性能,修改程序父目录判断操作只执行一次

考虑使用静态代码块,静态代码优先于主程序执行

public class TestDemo {private static File file = new File("D:"+File.separator+"dem"+File.separator+"demo.txt");static {//只执行一次,if(!file.getParentFile().exists()){file.getParentFile().mkdirs();//创建所有的父路径}}public static void main(String[] args) throws  IOException {if (file.exists()){file.delete();System.out.println("文件已删除");}else{file.createNewFile();System.out.println("文件已经添加");}}
}

获取文件目录信息

No 方法名称 类型
01 public boolean canExecute() method 可执行
02 public boolean canRead() method 可读
03 public boolean canWrite() method 可写
04 public File getAbsoluteFile() method 文件的绝对路径实例
05 public String getName() method 获取文件或目录名
06 public boolean isDirectory() method 是目录
07 public boolean isFile() method 是文件
07 public long lastModified() method 文件最后修改时间
08 public long length() method 文件大小,返回 bytes,
09 public boolean isHidden() method 文件是否隐藏

范例:

import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.logging.SimpleFormatter;/*** Created by 逸足天涯* on 3/21/2020.*/
public class TestDemo2 {private static File file = new File("D:"+File.separator+"dem"+File.separator+"demo.txt");static {//只执行一次,if(!file.getParentFile().exists()){file.getParentFile().mkdirs();//创建所有的父路径}}public static void main(String[] args) throws  IOException {if (file.exists()){System.out.println("文件是否能执行?"+file.canExecute());System.out.println("文件是否能读?"+file.canRead());System.out.println("文件是否能写?"+file.canWrite());System.out.println("文件的绝对路径"+file.getAbsoluteFile());System.out.println("文件名称"+file.getName());System.out.println("文件是否是目录"+file.isDirectory());System.out.println("文件是否为文件"+file.isFile());System.out.println("文件的最后修改日期"+new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS").format(new Date(file.lastModified())));System.out.println("文件长度"+file.length());}}
}
public class TestDemo3 {private static File file = new File("D:"+File.separator+"cn_windows_10_consumer_edition_version_1809_updated_sept_2018_x64_dvd_f7b9c8a9.iso");public static void main(String[] args) throws  IOException {System.out.println(String.format("%5.2f",(file.length()/(double)1024/1024/1024))+"G");}
}

获取目录中所有子文件和目录

No 方法名称 类型
01 public String[] list() method 描述子路径信息(不包含父目录)
02 public File[] listFiles() method 列出所有路径信息,(File 对象数组)
public class TestDemo4 {public static void main(String[] args) {File file = new File("D:");String[] list = file.list();List<String> strings = Arrays.asList(list);strings.forEach(str-> System.out.println(str));}
}

输出结果:

360 R T L O G 360RTLOG 360RTLOG
$360Section
$RECYCLE.BIN
01尚硅谷SpringBoot核心技术篇
360Downloads
360安全浏览器下载
360极速浏览器下载
360驱动大师目录
app
BaiduNetdiskDownload
bootstrap4.zip
cn_windows_10_consumer_edition_version_1809_updated_sept_2018_x64_dvd_f7b9c8a9.iso
dem
downloads
Office_Professional_Plus_2016_x64_CN_2019.03.iso
Program Files (x86)
restful-crud-实验
springboot_001
ssmbuild
Struts 2+Hibernate+MyBatis+Spring 网站开发案例课堂
System Volume Information
WindowsImageBackup
中文年度加强版.rar
我的文档
新桌面
迅雷下载

结论: 获得子路径下所有的目录或者文件的名字。


public class TestDemo4 {public static void main(String[] args) {File file = new File("D:");File[] list = file.listFiles();Arrays.asList(list).forEach(str-> System.out.println(str));}
}

输出结果:

D:$360RTLOG$
D:$360Section
D:$RECYCLE.BIN
D:\01尚硅谷SpringBoot核心技术篇
D:\360Downloads
D:\360安全浏览器下载
D:\360极速浏览器下载
D:\360驱动大师目录
D:\app
D:\BaiduNetdiskDownload
D:\bootstrap4.zip
D:\cn_windows_10_consumer_edition_version_1809_updated_sept_2018_x64_dvd_f7b9c8a9.iso
D:\dem
D:\downloads
D:\Office_Professional_Plus_2016_x64_CN_2019.03.iso
D:\Program Files (x86)
D:\restful-crud-实验
D:\springboot_001
D:\ssmbuild
D:\Struts 2+Hibernate+MyBatis+Spring 网站开发案例课堂
D:\System Volume Information
D:\WindowsImageBackup
D:\中文年度加强版.rar
D:\我的文档
D:\新桌面
D:\迅雷下载

结论: 获取带路径的文件名。

范例 3: 获取目录下所有文件路径

public class TestDemo4 {public static void main(String[] args) {File file = new File("D:");lisrDir(file);}//使用递归遍历输出目录下所有文件路径public static void lisrDir(File file){if (file.isDirectory()){File[] files = file.listFiles();for (File f1 : files) {lisrDir(f1);}}System.out.println(file);}
}

文件名修改

public class TestDemo5 {public static void main(String[] args) throws IOException {File oldFile = new File("d:"+File.separator+"old.txt");oldFile.createNewFile();File newFile = new File("d:"+File.separator+"new.txt");if (oldFile.exists()){oldFile.renameTo(newFile);}// newFile.delete();}
}

批量修改字节文件名

package filenamecopy;import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;public class renameuserfilename {/*****   String类可能使用的方法substring(int beginIndex) 截取从beginIndex到末尾的字符串并返回substring(int beginIndex, int endIndex) 截取从beginIndex到endIndex的字符串并返回 concat(String str) 将指定字符串str连接到此字符串的结尾indexOf(int ch) 返回指定字符在此字符串中第一次出现处的索引indexOf(String str) 返回指定子字符串在此字符串中第一次出现处的索引lastIndexOf(int ch) 返回指定字符在此字符串中最后一次出现处的索引lastIndexOf(int ch, int fromIndex) 返回指定字符在此字符串中最后一次出现处的索引,从指定的索引处开始进行反向搜索 length()   返回此字符串的长度replace(CharSequence target, CharSequence replacement) 使用指定的字面值替换序列替换此字符串所有匹配字面值目标序列的子字符串replaceAll(String regex, String replacement) 使用给定的 replacement 替换此字符串所有匹配给定的正则表达式的子字符串* @param args* @throws IOException*/public static void main(String[] args) throws IOException {// TODO Auto-generated method stub// 在目标文件夹下重命名renamfile1("D:\\解密\\test\\10\\spark");//拷贝别的目录下重命名//reNameFile3("D:\\解密\\test\\10\\spark", "E:\\test\\10");}public static void reNameFile3(String oldfiles, String newfile)throws IOException {// File folder = new File("D:\\解密\\test\\10\\spark");File folder = new File(oldfiles);File newfiles = new File(newfile);// 如果不存在,创建文件夹if (!newfiles.exists()&&!newfiles.isDirectory()) {/** 创建单级目录* System.out.println("=====创建文件夹==========="+newfiles.mkdir());* newfiles.mkdir();*/// 创建多级目录newfiles.mkdirs();System.out.println("=====创建文件夹===========" + newfiles.mkdirs());}// 获取该目录下所有文件的File数组File[] fileArray = folder.listFiles();int i = 1;for (File f : fileArray) {// System.out.println(f);String name = f.getName();int index = name.indexOf(":");String newName = i + "." + name.substring(index + 1, name.length());System.out.println(newName);// File newFile = new File(folder,newName);// f.renameTo(newFile);i++;// 封装数据源/** //FileReader fr = new FileReader("c:\\a.txt"); FileReader fr =* new FileReader(oldfiles+"\\"+name); // 封装目的地 //FileWriter fw =* new FileWriter("d:\\b.txt"); FileWriter fw = new* FileWriter(newfile+"\\"+newName); // 读写数据 // int ch = 0; int ch;* while ((ch = fr.read()) != -1) { fw.write(ch); }* * //释放资源 fw.close(); fr.close();*/// 封装数据源BufferedReader br = new BufferedReader(new FileReader(oldfiles+ "\\" + name));// 封装目的地BufferedWriter bw = new BufferedWriter(new FileWriter(newfile+ "\\" + newName));// 读写数据String line = null;// 两种方式其中的一种一次读写一个字符数组char[] chs = new char[1024];int len = 0;while ((len = br.read(chs)) != -1) {bw.write(chs, 0, len);bw.flush();}// 释放资源bw.close();br.close();}}public static void reNamefile2(String oldfiles) {// File folder = new File("D:\\解密\\test\\10\\spark");File folder = new File(oldfiles);// 获取该目录下所有文件的File数组File[] fileArray = folder.listFiles();if (!folder.exists()) {return;// 重命名文件不存在}int i = 1;for (File f : fileArray) {// System.out.println(f);String name = f.getName();int index = name.indexOf(":");String newName = i + "." + name.substring(index + 1, name.length());System.out.println(newName);File newFile = new File(folder, newName);f.renameTo(newFile);i++;}}public static void renamfile1(String oldfiles) throws IOException {File file = new File(oldfiles);File[] list = file.listFiles();// 如果目录下文件存在if (file.exists() && file.isDirectory()) {for (int i = 0; i < list.length; i++) {// 取文件名子存入name中String name = list[i].getName();// 截取":"之前的字符串出来int index = name.indexOf(":");String name2 = name.substring(index + 1);// 重命名并存入int j = i + 1;File dest = new File(oldfiles + "\\" + j + "." + name2);list[i].renameTo(dest);System.out.println(dest.getName());/** if(newfile.exists())//若在该目录下已经有一个文件和新文件名相同,则不允许重命名* System.out.println(newname+"已经存在!"); else{* oldfile.renameTo(newfile); }*/}}}public static void reNameFile0(String filespath){File file = new File(filespath);File[] list = file.listFiles();// 如果目录下文件存在if (file.exists() && file.isDirectory()){for (int i = 0; i < list.length; i++){//取文件名子存入name中String name = list[i].getName();// 截取.之前的字符串出来int index = name.indexOf(".");// 截取后缀名字.qsv/.exe/.avi/.mp4出来int index2 = name.lastIndexOf(".");String name3 = name.substring(index2);// 拼接字符串String newName = "2019-4-18-" + (i + 1) + name3;//重命名File dest = new File(filespath + "\\" + newName);list[i].renameTo(dest);System.out.println(dest.getName());}}}}

处理前:

处理后:


字节流与字符流

输入流输出流

  • 字节操作流:OutputStream(字节输出流)和InputStream(字节输入流)
  • 字符操作流:Writer(字符输入流) 和 Reader(字符输出流)

不管使用哪一种操作流,

字节输出流OutputStream

是同一个操作输出流,实现了Closable 和 Flushable 接口,而Closeable 接口实现了AutoCloseable 接口

  • public abstract void write(int b) throws IOException
    

OutputStream 提供了三个输出方法

No 方法名称 类型 描述
01 public abstract void write(int b) throws IOException method 输出单个字节数据
02 public void write(byte[] b) throws IOException method 输出全部字节数组数据
03 public void write(byte[] b, int off, int len) throws IOException method 输出指定字节数组的数据

整个OutputStream 类中的write()方法都是针对字节数据进行处理的。

寻找FileOutputStream.

NO 方法名称 类型 描述
01 public FileOutputStream(File file) throws FileNotFoundException method 设置文件输出流,每次都对原始数据进行覆盖
02 public FileOutputStream(File file, boolean append) throws FileNotFoundException method 如果将append 的内容设置为true,对原始内容进行追加

范例:

public class Test1 {public static void main(String[] args) throws FileNotFoundException, IOException {//要进行磁盘输出的完整路径File file = new File("d:" + File.separator+"mldn"+File.separator+"message"+ File.separator+"info.txt");if(!file.getParentFile().exists()){file.getParentFile().mkdirs();}//append,值为true ,实现内容追加输出OutputStream outputStream = new FileOutputStream(file,true);//获得输出流//实现数据的输出需要将内容变为字节数组outputStream.write("\r\n肚子饿了吗".getBytes());outputStream.write("\r\n肚子饿了吗2".getBytes());outputStream.write("\r\n肚子饿了吗3".getBytes());//指定出数组第2个元素起输出5个元素。outputStream.write("hello world!".getBytes(),2,5);outputStream.close();//关闭输出流}
}

字节输出流InputStream

No 方法名称 类型 描述
01 public FileInputStream(File file) throws FileNotFoundException 构造
02 public abstract int read() throws IOException 方法 读取单个字节数据,如果没有自己数据了,返回“-1"
03 public int read(byte[] b) throws IOException 方法 将内容读取到字节数组之中,如果没有自己数据了,返回“-1"
04 public int read(byte[] b, int off, int len) throws IOException 方法 将内容兑取到字节数组中,返回部分数据,如果没有数据返回‘-1’

可以使用FileInputStream子类对其进行实例化,以实现文件流的操作。

范例:

package com.zdy.stream;import java.io.*;/*** Created by 逸足天涯* on 3/21/2020.*/
public class Test2{public static void main(String[] args) throws FileNotFoundException, IOException {//要进行磁盘输出的完整路径File file = new File("d:" + File.separator+"mldn"+File.separator+"message"+File.separator+"info.txt");if (file.exists()){InputStream inputStream = new FileInputStream(file);//实例化输入流byte data[] = new byte[1024];inputStream.read(data); //将输入流中的内容读取到字节数组之中System.out.println("{读取到的内容==\n=="+new String(data,0,data.length)+"}");//将读取到的字节数组内容转换为字符串在控制台输出inputStream.close();}}
}

从JDK1.9 开始InputStream 追加了一个疯狂的方法getAllBytes(),这种方法的好处在于,开发者再考虑使用多大的书数组了,直接全部返回了,但是数据一多就会崩溃。

字符输出流Writer

在使用Writer 类 进行操作时,最大的数据特征是其可以进行字符串数据处理

*  输出方法 public void write(String str) throws IOException
*  后续版本才有了 CharSequence 接口的支持,就可以实现String,Stringbuffer,StringBuilder的实例

范例:使用FileWaiter进行输出;

public class Test3 {public static void main(String[] args) throws FileNotFoundException, IOException {//要进行磁盘输出的完整路径File file = new File("d:" + File.separator+"mldn"+File.separator+"message"+ File.separator+"info2.txt");if(!file.getParentFile().exists()){file.getParentFile().mkdirs();}Writer out = new FileWriter(file);//实例化Writer类对象out.write("www.baidu.com");out.append("hello append");out.close();}
}

使用Writer 可以实现 与OutputStream 类似的功能,其最大的优势在于可以直接实现对字符的操作。

字符输入流(Reader)

范例

public class test4 {public static void main(String[] args) throws FileNotFoundException, IOException {//要进行磁盘输出的完整路径File file = new File("d:" + File.separator+"mldn"+File.separator+"message"+ File.separator+"info2.txt");if(!file.getParentFile().exists()){file.getParentFile().mkdirs();}Reader in = new FileReader(file);//实例化Writer类对象char[] data = new char[1024];int len = in.read(data);System.out.println(new String(data,0,len));in.close();}
}

使用try(){} 实现字节流的自动关闭。同理以上3个实例也可以实现自动关闭,因为他们都实现了InterfacAutoCloseable接口。

public class test4 {public static void main(String[] args)  {//要进行磁盘输出的完整路径File file = new File("d:" + File.separator+"mldn"+File.separator+"message"+ File.separator+"info2.txt");if(file.exists()){try( Reader in = new FileReader(file)) {char[] data = new char[1024];//新建一个字符数,int len = in.read(data);//把文件内容存入数组System.out.println(new String(data,0,len));//控制台输出}catch (Exception e){System.err.println(e);}}}
}

字节流和字符流的区别

要想明白字节流和字符流的区别,首先明白

字节和字符的区别

  • byte 是字节数据类型 ,是有符号型的,占1 个字节;大小范围为-128—127 。

  • char 是字符数据类型 ,是无符号型的,占2字节(Unicode码 );大小范围 是0—65535 ;char是一个16位二进制的Unicode字符,JAVA用char来表示一个字符 。

下面用实例来比较一下二者的区别:

  1. Char是无符号型的,可以表示一个整数,不能表示负数;而byte是有符号型的,可以表示-128—127 的数;如:
char c = (char) -3; // char不能识别负数,必须强制转换否则报错,即使强制转换之后,也无法识别
System.out.println(c);
byte d1 = 1;
byte d2 = -1;
byte d3 = 127; // 如果是byte d3 = 128;会报错
byte d4 = -128; // 如果是byte d4 = -129;会报错
System.out.println(d1);
System.out.println(d2);
System.out.println(d3);
System.out.println(d4);

结果为:

?
1
-1
127
-128

  1. char可以表中文字符,byte不可以,如:
char e1 = '中', e2 = '国';
byte f= (byte) '中';  //必须强制转换否则报错
System.out.println(e1);
System.out.println(e2);
System.out.println(f);

结果为:



45

  1. char、byte、int对于英文字符,可以相互转化,如:
byte g = 'b'; //b对应ASCII是98
char h = (char) g;
char i = 85;   //U对应ASCII是85
int j = 'h'; //h对应ASCII是104
System.out.println(g);
System.out.println(h);
System.out.println(i);
System.out.println(j);

结果:

98
b
U
104


已经接触了两种数据流操作,

字节操作,属于基础的二进制流操作。在网络、文件等操作。

字节数据不方便对于中文的处理,所以中文处理应该使用字符流。

在进行网络传输或者磁盘数据存储的时候,所有存放内容都属于字节数据。

范例: 体验字符流在转换过程中有缓冲区。

将test1 代码去掉 outputStream.close();//关闭输出流。执行程序,发现目标文件写入代码。

将test3 代码去掉 out.close(); //关闭输出流,执行程序,查看目标文件,内容未写入。

原因: 字符流具有缓冲区,数据流关闭后,数据写入目标文件,未关闭时,数据在缓冲区内,

可以添加 out.flush(); 方法清空缓冲区。再次执行程序。发现即使没有关闭输出流,数据依然写入文件。

转换流

为了方便的实现字节流和字符流的转换处理,提供了2个类OutputStreamWriter 和InputStreamReader

通过观察源码发现OutputStreamWriter 继承Writer类,构造方法里是一个OuputStream 实例。

InputStreamReader类继承Reader类,同时构造方法里是一个InputStream实例。

范例: 观察数据流的转化

package com.zdy.stream;import java.io.*;/*** Created by 逸足天涯* on 3/21/2020.*/
public class Test5 {public static void main(String[] args) throws FileNotFoundException, IOException {//要进行磁盘输出的完整路径File file = new File("d:" + File.separator+"mldn"+File.separator+"message"+ File.separator+"info3.txt");if(!file.getParentFile().exists()){file.getParentFile().mkdirs();}//append,值为true ,实现内容追加输出OutputStream outputStream = new FileOutputStream(file);//获得输出流OutputStreamWriter outputStreamWriter = new OutputStreamWriter(outputStream);//字节流转字符流outputStreamWriter.write("www.baidu.com");//直接输出字符串outputStreamWriter.write("\r\n你好世界");//直接输出字符串outputStreamWriter.append("\r\nnhello world");outputStreamWriter.close();//关闭输出流}
}

文件Copy

要复制的文件可能是文本文件也可能是二进制文件,所有考虑通用性,使用字节流

由于要因该cpoy 的文件很大,因该采用边读边写的模式。

范例:

class CopyUtil{private File srcFile;private File desFile;public CopyUtil(File srcFile,File desFile) {//如果没错,获取源文件和目标文件路径this.srcFile = srcFile;this.desFile = desFile;}/** 实现复制的操作处理* @return 返回本次花费的时间* */public int copy() throws IOException {long start = System.currentTimeMillis();if(!this.srcFile.exists()){throw new FileNotFoundException("源文件不存在");}if(!this.desFile.getParentFile().exists()){this.desFile.getParentFile().mkdirs();//创建目标父目录}InputStream input = null;OutputStream output = null;try{input = new FileInputStream(this.srcFile);output = new FileOutputStream(this.desFile);} catch (IOException e) {throw e;} finally {if (input!=null){try {input.close();} catch (IOException e) {e.printStackTrace();}}if (output!=null){try {output.close();} catch (IOException e) {e.printStackTrace();}}}long end = System.currentTimeMillis();return (int) (end-start);}
}
public class CopyDemo {public static void main(String[] args) throws IOException {File oldfile = new File("d:" + File.separator + "社会工程3本.pdf");File newfile = new File("d:" + File.separator + "images" + File.separator + "新社会工程3本.pdf");CopyUtil copyUtil = new CopyUtil(oldfile,newfile);int time = copyUtil.copy();System.out.println("复制文件花费的时间:" + time);}
}

但是JDK 1.9 开始,在InputStream中出现了一个新方法。

public long transferTo(OutputStream out) throws IOException

直接把输入流转成输出流。实现文件复制。

上面代码可以写成

class CopyUtil{private File srcFile;private File desFile;public CopyUtil(File srcFile,File desFile) {//如果没错,获取源文件和目标文件路径this.srcFile = srcFile;this.desFile = desFile;}/** 实现复制的操作处理* @return 返回本次花费的时间* */public int copy() throws IOException {long start = System.currentTimeMillis();if(!this.srcFile.exists()){throw new FileNotFoundException("源文件不存在");}if(!this.desFile.getParentFile().exists()){this.desFile.getParentFile().mkdirs();//创建目标父目录}InputStream input = null;OutputStream output = null;try{input = new FileInputStream(this.srcFile);output = new FileOutputStream(this.desFile);input.transferTo(output);} catch (IOException e) {throw e;} finally {if (input!=null){try {input.close();} catch (IOException e) {e.printStackTrace();}}if (output!=null){try {output.close();} catch (IOException e) {e.printStackTrace();}}}long end = System.currentTimeMillis();return (int) (end-start);}
}
public class CopyDemo {public static void main(String[] args) throws IOException {File oldfile = new File("d:" + File.separator + "社会工程3本.pdf");File newfile = new File("d:" + File.separator + "images" + File.separator + "新社会工程3本.pdf");CopyUtil copyUtil = new CopyUtil(oldfile,newfile);int time = copyUtil.copy();System.out.println("复制文件花费的时间:" + time);}
}

字符编码

  • GBK/GB2312:BGK 包含简体中文和繁体中文,BG2312只包含简体中文。
  • ISO8859-1: 是一个国际编码,可以描述任何文字,单对于图形文字则需要转码。
  • UNiCODE : 是一个不错的编码,使用16 进制,可世界上任何编码。占用空间大
  • UTF编码: 由ISO8859-1和UNICODE,在需要使用图形化文字的时候使用16 进制,在UTF-8使用1~4字节为每个字符编码:该编码主要由UTF-8 和UTF-16.

范例:获取当前系统的一些环境属性。

内存流

内存流实现临时文件的处理

//内存流操作
public class TestDemo {public static void main(String[] args) throws IOException {InputStream input = new ByteArrayInputStream("www.baidu.com".getBytes());OutputStream output = new ByteArrayOutputStream();int data=0;//input.read() 从输入流中读取下一个字节的数据。值字节是////*以<code>0</code>到范围内的<code>int</code>返回while((data=input.read()) !=-1){//将数据一个一个写入输出流output.write(Character.toUpperCase(data));}System.out.println(((ByteArrayOutputStream) output).toString());output.close();input.close();}
}

ByteArrayOutputStream一个特别重要的方法 public byte[] toByteArray()

public class TestDemo2 {public static void main(String[] args) throws IOException {File file = new File("d:" + File.separator+"mldn"+File.separator+"message"+ File.separator+"info4.txt");InputStream input = new FileInputStream(file);ByteArrayOutputStream output = new ByteArrayOutputStream();byte data[] = new byte[1024];int len = 0;while((len=input.read(data))!=-1){output.write(data,0,len);}System.out.println(new String(output.toByteArray()));output.close();input.close();}
}

JDK 1.9 后使用 public byte[] readAllBytes() throws IOException 替代上面的代码

public class TestDemo3 {public static void main(String[] args) throws Exception {File file = new File("d:" + File.separator+"mldn"+File.separator+"message"+ File.separator+"info4.txt");if(file.exists()){InputStream inputStream = new FileInputStream(file);byte bytes[] = inputStream.readAllBytes();System.out.println(new String(bytes));inputStream.close();}}
}

管道流

管道和线程有关,但是,实话讲,这样的设计有些啰嗦,多个线程可以实现一个进程的数据共享,但是多个进程的数据无法共享。因为cpu 的资源无法无法共享。

实现两个进程之间的通信,称作管道。

Java 提供2个线程之间的通信,叫做管道。

在Java 中实现线程之间的通信,提供了2个类。PipeOutputStream 和PipeInputStream两个类。

范例:

package com.zdy.管道;import java.io.IOException;
import java.io.PipedInputStream;
import java.io.PipedOutputStream;/*** Created by 逸足天涯* on 3/21/2020.*/
class SendThread implements Runnable{private PipedOutputStream pipedOutputStream = new PipedOutputStream();public void setPipedOutputStream(PipedOutputStream pipedOutputStream) {this.pipedOutputStream = pipedOutputStream;}public PipedOutputStream getPipedOutputStream() {return pipedOutputStream;}@Overridepublic void run() {try {this.pipedOutputStream.write("晚上不考试了,直接下课".getBytes());} catch (IOException e) {e.printStackTrace();}}
}
class ReceiveThread implements Runnable{private PipedInputStream pipedInputStream = new PipedInputStream();@Overridepublic void run() {byte data [] = new byte[1024];try {int len = this.pipedInputStream.read(data);System.out.println("接收数据"+ new String(data,0,len));} catch (IOException e) {e.printStackTrace();}}public PipedInputStream getPipedInputStream() {return pipedInputStream;}public void setPipedInputStream(PipedInputStream pipedInputStream) {this.pipedInputStream = pipedInputStream;}
}
public class TestDemo {public static void main(String[] args) throws IOException {SendThread sendThread = new SendThread();ReceiveThread receiveThread = new ReceiveThread();sendThread.getPipedOutputStream().connect(receiveThread.getPipedInputStream());//管道对接new Thread(sendThread).start();new Thread(receiveThread).start();}
}

RandomAccessFile

RandomAccessFile 访问文件内的信息读取需要的数据。不需要的不读取。

但是,所读取数据的长度必须统一。

RandomAcessFile 支持内容的输出与输入

范例

//写入数据
public class TestDemo {public static void main(String[] args) throws IOException {File file = new File("d:"+File.separator+"member.text");String name[] = new String[]{"张三","lisi","王五"};int ages [] = new int[]{17,18,19};RandomAccessFile randomAccessFile = new RandomAccessFile(file,"rw");//读写模式for (int x = 0;x< name.length;x++){randomAccessFile.write(name[x].getBytes()); //写入字符串randomAccessFile.writeInt(ages[x]);//写入数字}randomAccessFile.close();}
}

此时输出到文件的数据都属于二进制的数据内容,那么对于此时的内容只能够利用RandomAccessFile 读取

  • public int skipBytes(int n) throws IOException// 向下跳
  • public void seek(long pos) throws IOException//向回跳
    

读取数据

//读取数据
public class TestDemo1 {public static void main(String[] args) throws IOException {File file = new File("d:"+File.separator+"member.txt");RandomAccessFile randomAccessFile = new RandomAccessFile(file,"r");//只读{randomAccessFile.skipBytes(12);byte data[] = new byte[8];randomAccessFile.read(data);System.out.println(String.format("姓名: %s、年龄%s",new String(data),randomAccessFile.readInt()));//读取zhangsan 的数据randomAccessFile.seek(0);randomAccessFile.read(data);System.out.println(String.format("姓名: %s、年龄%s",new String(data),randomAccessFile.readInt()));//读取王五randomAccessFile.skipBytes(12);randomAccessFile.read(data);System.out.println(String.format("姓名: %s、年龄%s",new String(data),randomAccessFile.readInt()));}randomAccessFile.close();}
}

打印流

PrintWriter

设计一个类,实现个中数据类型的输出

范例: 最初的设计方案

package com.zdy.打印流;import java.io.*;/*** Created by 逸足天涯* on 3/22/2020.*/
class PrintUtil implements Closeable{//设计一个打印流的功能类,支持各种数据类型流输出private OutputStream outputStream;public PrintUtil(OutputStream outputStream){//设置输出位置this.outputStream = outputStream;}public void print(String str){try {this.outputStream.write(str.getBytes());} catch (IOException e) {e.printStackTrace();}}public void print(int num){this.print(String.valueOf(num));}public void println(String str){this.print(str+"\r\n");}public void println(int num){this.println(String.valueOf(num));}@Overridepublic void close() throws IOException {this.outputStream.close();}
}
//功能数据直接输出到文件内
public class TestDemo {public static void main(String[] args) throws IOException {PrintUtil pu = new PrintUtil(new FileOutputStream(new File("d:"+File.separator+"info.txt")));pu.print("姓名:dog");pu.println("、年龄");pu.println(64);System.out.println("内容已经添加到"+ " d:\\info.txt");pu.close();}
}

为了解决上述问题,JDK 提供了2个类 PrintStream 和 PrintWriter 两个类。

使用打印流输出 实现上述内容同样功能

//功能数据直接输出到文件内
public class TestDemo1 {public static void main(String[] args) throws IOException {PrintWriter pw = new PrintWriter(new FileOutputStream(new File("d:"+File.separator+"info.txt")));pw.print("姓名:dog");pw.println("、年龄");pw.println(64);System.out.println("内容已经添加到"+ " d:\\info.txt");pw.close();}
}
public PrintWriter printf(String format, Object... args)

实现格式化输出。

//功能数据直接输出到文件内
public class TestDemo1 {public static void main(String[] args) throws IOException {PrintWriter pw = new PrintWriter(new FileOutputStream(new File("d:"+File.separator+"info.txt")));String name= "god";int age = 10000000;double sorce = 100.12423432;pw.printf("姓名:%s、年龄:%d、成绩:%5.2f",name,age,sorce);System.out.println("内容已经添加到"+ " d:\\info.txt");pw.close();}
}

结论: 对于明文可以使用PrintWriter .对于二进制文件的优先建议使用PrintStream.尤其是中文。

打印流使用装饰设计模式

对象流的使用

使用对象流实现对对象的序列化和反序列化
要想使对象序列化,必须实现 Serializable 接口。

package com.zdy;import java.io.Serializable;/*** Created by 逸足天涯* on 3/22/2020.*/
//实现 Serializable 表示此对象可以序列化
public class Person implements Serializable {private static final long serialVersionUID = 7592930394427200495L;private String name;private int age;Person(String name, int age) {this.name = name;this.age = age;}@Overridepublic String toString() {return "姓名:"+name+"\n年龄:"+age;}
}

序列化

package com.zdy;import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;/*** Created by 逸足天涯* on 3/22/2020.*/
public class SerObject {public static void main(String[] args) throws IOException {//实例化一个需要序列化的Person对象Person jack = new Person("jack", 12);//生成一个文件对象,文件不存在将自动创建文件File f = new File( new File("").getAbsolutePath()+ File.separator + "serTest.txt");//构造一个对象输出流oosObjectOutputStream oos = null;//构造一个文件输出流FileOutputStream fileOutputStream = new FileOutputStream(f);//构造对象输出流oos = new ObjectOutputStream(fileOutputStream);//序列化一个对象到文件变成二进制内容oos.writeObject(jack);oos.close();}
}

反序列化

package com.zdy;import java.io.*;/*** Created by 逸足天涯* on 3/22/2020.*/
public class ReSerObject {public static void main(String[] args) throws Exception {//生成一个文件对象,文件不存在将自动创建文件File f = new File( new File("").getAbsolutePath()+ File.separator + "serTest.txt");//新建一个文件输入流FileInputStream fileInputStream = new FileInputStream(f);//新建一个对象输入流ObjectInputStream objectInputStream = new ObjectInputStream(fileInputStream);//读取输入流中对象Person o = (Person)objectInputStream.readObject();//输出对象System.out.println(o.toString());}
}

Java IO 编程相关推荐

  1. Java IO编程全解(五)——AIO编程

    转载请注明出处:http://www.cnblogs.com/Joanna-Yan/p/7794151.html 前面讲到:Java IO编程全解(四)--NIO编程 NIO2.0引入了新的异步通道的 ...

  2. Java IO编程全解(六)——4种I/O的对比与选型

    转载请注明出处:http://www.cnblogs.com/Joanna-Yan/p/7804185.html 前面讲到:Java IO编程全解(五)--AIO编程 为了防止由于对一些技术概念和术语 ...

  3. java IO编程详解

    java IO编程详解 一.Socket 1. Sock概述 Socket,套接字就是两台主机之间逻辑连接的端点.TCP/IP协议是传输层协议,主要解决数据如何在网络中传输,而HTTP协议是应用层协议 ...

  4. Java_09 快速入门 Java IO编程

    目录 第一章:Java IO编程 1.1  文件操作类:File 范例1-1:文件基本操作.任意给定一个文件路径,如果文件不存在则创建一个新的文件,如果文件存在则将文件删除. 范例1-2:创建带路径的 ...

  5. 【Java基础】Java IO编程:输入输出流、内存流、打印流、缓冲流BufferedReader、扫描流Scanner、序列化与反序列化

    文章目录 第11章.Java IO编程 11.1 文件操作类:File 11.2 字节流与字符流 字节输出流:OutputStream OutputStream类 FileOutputStream类 ...

  6. 第十一章 Java IO编程

    第十一章 Java IO编程 11.1 文件操作类:File java.io包中,如果要进行文件自身操作(创建,删除),只能依靠java.io.File类完成. NO. 方法 类型 描述 1 publ ...

  7. Java IO篇 Java IO编程

    Java IO 一.java io 概述 1.1 相关概念 二.Java IO类库的框架 2.1 Java IO的类型 2.2 IO 类库 三.Java IO的基本用法 3.1 Java IO :字节 ...

  8. java io编程_Java_IO编程

    如果要进行文件内容的操作,必须依靠数据流完成,而数据流分为两种: 字节流:InpuStream(字节输入流).OutputStream(字节输出流) 字符流:Reader(字符输入流).Writer( ...

  9. Java IO框架之BIO、NIO、AIO

    我是傲骄鹿先生,沉淀.学习.分享.成长. 如果你觉得文章内容还可以的话,希望不吝您的「一键三连」,文章里面有不足的地方希望各位在评论区补充疑惑.见解以及面试中遇到的奇葩问法 目录 一.概述 二.BIO ...

最新文章

  1. python爬虫入门实例-Python-入门的第一个爬虫例子
  2. c语言for循环加法,BigDecimal 在for循环中相加注意事项
  3. Transformer模型拆解分析
  4. 设计师不用下课了吧?小米突然官宣性价比之王旗舰:升降式摄像头
  5. thinkphp 二级域名绑定模块,导致设置的路由被多域名共用的问题解决方案
  6. 浅谈localStorage、sessionStorage 与cookie
  7. 在线html链接提取工具
  8. UE4之变量、定时器和事件
  9. dreamweaver 正则表达式为属性值加上双引号_IT兄弟连 HTML5教程 HTML5表单 新增的表单属性3...
  10. UG NX 12同步建模:调整面大小
  11. Ubuntu16.04安装网易云音乐后打不开
  12. SLAM【十】回环检测
  13. 服务器芯片和一般电脑芯片的区别,服务器CPU和PC的CPU区别
  14. IDEA包下不能建包问题
  15. 日期,手机号码正则表达式校验,身份证校验等常用工具
  16. Numpy攻略系列:repeat函数
  17. Solar Tracker
  18. JVM之垃圾收集算法
  19. microtime() 函数
  20. Footprint Analytics: 去中心化存储协议是否能取代中心化云存储?

热门文章

  1. java mail 发送邮件_JavaMail实现收发邮件——(二)发送邮件
  2. 【云图】自有数据的多边形检索(云检索)
  3. 【计算视觉】人脸属性识别算法 | 性别+种族+年龄+表情
  4. Ae 效果详解:音频频谱
  5. 北京师范大学网络教育计算机动画,北师大网络教育《计算机动画》在线作业.pdf...
  6. 什么是互动触摸屏?它有用途是什么?
  7. [小工具] 微信小程序代码压缩器
  8. gsap_使用GSAP的动画库为Bootstrap传送带制作动画
  9. [ java ] 坦克大战 5.0 ~ 最终完整版
  10. java 山寨qq源代码_求一个山寨qq的源代码,要java语言的~谢谢