标签:java File String io new FFile public 入门
1.概述
java.io.File 类是文件和目录路径名的抽象表示,主要用于文件和目录的创建、查找和删除等操作。
1.构造方法
public File(String pathname) :通过将给定的路径名字符串转换为抽象路径名来创建新的 File实例。
public File(String parent, String child) :从父路径名字符串和子路径名字符串创建新的 File实例。
public File(File parent, String child) :从父抽象路径名和子路径名字符串创建新的 File实例。
代码如下
package com.xjggb.file;
import java.io.File;
public class Demo01 {
public static void main(String[] args) {
//方式一
File file1 = new File("D:\\li\\1.txt");
System.out.println("方式一" + file1);
//方式二
String url="D:\\li";
String s="1.txt";
File file = new File(url,s);
System.out.println("方式二" + file);
//方式三
File file2 = new File("D:\\li");
String o="1.txt";
File file3 = new File(file2,o);
System.out.println("方式三" + file3);
}
}
小结:
-
一个File对象代表硬盘中实际存在的一个文件或者目录。
-
无论该路径下是否存在文件或者目录,都不影响File对象的创建。
2.常用的方法
public String getAbsolutePath() :返回此File的绝对路径名字符串。
public String getPath() :将此File转换为路径名字符串。
public String getName() :返回由此File表示的文件或目录的名称。
public long length() :返回由此File表示的文件的长度。
package com.xjggb.file;
import java.io.File;
public class Demo02 {
public static void main(String[] args) {
//方式一
File file1 = new File("D:\\li\\1.txt");
System.out.println("获取文件的名称和目录名称 " + file1.getName());
System.out.println("文件构造路径" + file1.getPath());
System.out.println("文件长度 " + file1.length());
System.out.println("文件绝对路径 " + file1.getAbsolutePath());
//方式一
File file2= new File("D:\\li");
System.out.println("获取文件的名称和目录名称2 " + file2.getName());
System.out.println("文件构造路径2" + file2.getPath());
System.out.println("文件长度2 " + file2.length());
System.out.println("文件绝对路径2 " + file2.getAbsolutePath());
}
}
小结
绝对路径和相对路径
绝对路径:从盘符开始的路径,这是一个完整的路径。
相对路径:相对于项目目录的路径,这是一个便捷的路径,开发中经常使用。
3.判断功能的方法
public boolean exists() :此File表示的文件或目录是否实际存在。
public boolean isDirectory() :此File表示的是否为目录。
public boolean isFile() :此File表示的是否为文件。
package com.xjggb.file;
import java.io.File;
public class Demo02 {
public static void main(String[] args) {
//方式一
File file1 = new File("D:\\li\\1.txt");
File file2 = new File("D:\\li");
System.out.println("是否存在" + file1.exists());
System.out.println("是否是文件" + file1.isFile());
System.out.println("是否是文件夹" + file2.isDirectory());
}
}
4.创建和删除功能
public boolean createNewFile() :当且仅当具有该名称的文件尚不存在时,创建一个新的空文件。
public boolean delete() :删除由此File表示的文件或目录。
public boolean mkdir() :创建由此File表示的目录。
public boolean mkdirs() :创建由此File表示的目录,包括任何必需但不存在的父目录。
代码如下
package com.xjggb.file;
import java.io.File;
import java.io.IOException;
public class Demo03 {
public static void main(String[] args) throws IOException {
//方式一
File file1 = new File("D:\\li\\2.txt");
//文件的创建
System.out.println("文件是否纯在" + file1.exists());
System.out.println("是否创建一个空的文件" + file1.createNewFile());
System.out.println("文件是否纯在" + file1.exists());
//
// //文件夹的创建
File file2 = new File("D:\\lu");
// System.out.println("判断文件夹是否纯在" + file2.exists());
// System.out.println("file2.mkdir() = " + file2.mkdir());
// System.out.println("判断文件夹是否纯在" + file2.exists());
//创建多级目录
File file3 = new File("D:\\lu\\aaa\\ss");
// System.out.println("file3 判断目录是否纯在 " + file3.exists());
// System.out.println("file3.创建多级目录 = " + file3.mkdirs());
// System.out.println("file3 判断目录是否纯在 " + file3.exists());
//文件删除
System.out.println("file3.delete() = 文件删除" + file2.delete());
}
}
小结:
多级目录不能一起删除,只能一步一步的删除
5.目录的遍历
public String[] list() :返回一个String数组,表示该File目录中的所有子文件或目录。
public File[] listFiles() :返回一个File数组,表示该File目录中的所有的子文件或目录。
package com.xjggb.file;
import java.io.File;
public class Demo04 {
public static void main(String[] args) {
File file1 = new File("D:\\li");
//获取当前文件夹的文件夹的名称
String[] list = file1.list();
for (String s : list) {
System.out.println("s = " + s);
}
//获取当前目录下的文件以及文件夹对象,只要拿到了文件对象,那么就可以获取更多信息
File[] files = file1.listFiles();
for (File file : files) {
System.out.println("file = " + file);
}
/*
* s = 1.txt
s = 2.txt
s = aaa
file = D:\li\1.txt
file = D:\li\2.txt
file = D:\li\aaa
* */
}
}
6.递归
:num的累和 = num + (num-1)的累和,所以可以把累和的操作定义成一个方法,递归调用。
package com.xjggb.file;
public class Demo05 {
public static void main(String[] args) {
int num=5;
int show = getShow(num);
System.out.println("show = " + show); //15
}
public static int getShow(int num){
if (num==1){
return 1;
}
return num+getShow(num-1);
}
}
文件收索
package com.xjggb.file;
import java.io.File;
public class Demo05 {
public static void main(String[] args) {
File file = new File("D:\\li");
getShow(file);
}
public static void getShow(File file){
File[] files = file.listFiles();
for (File file1 : files) {
if (file1.isFile()){
if (file1.getName().endsWith(".txt")){
System.out.println("文件名" + file1.getAbsolutePath());
}
}else {
//是文件夹继续遍历
getShow(file);
}
}
}
}
2.IO概述
生活中,你肯定经历过这样的场景。当你编辑一个文本文件,忘记了 ctrl+s ,可能文件就白白编辑了。当你电脑上
插入一个U盘,可以把一个视频,拷贝到你的电脑硬盘里。那么数据都是在哪些设备上的呢?键盘、内存、硬盘、外
接设备等等。
我们把这种数据的传输,可以看做是一种数据的流动,按照流动的方向,以内存为基准,分为 输入input 和 输出
output ,即流向内存是输入流,流出内存的输出流。
Java中I/O操作主要是指使用 java.io 包下的内容,进行输入、输出操作。输入也叫做读取数据,输出也叫做作写出
数据。
1.IO流的分类
- 输入流:把数据从其他设备上读取到内存中的流
- 输出流: 把数据从内存中写道其他设备上的流
格局数据类型分为:字节流和字符流
- 字节流 :以字节为单位,读取数据流
- 字符流:以字符为单位,读取数据的流
2.IO的流说明图
说明 | 输入流 | 输出流 |
---|---|---|
字节流 | 字节输出流 InputStream | 字节输出流 OutputStream |
字符流 | 字符输入流 Reader | 字符输出流 Writer |
1.字节流输出流【OutputStream】
一切文件数据(文本、图片、视频等)在存储时,都是以二进制数字的形式保存,都一个一个的字节,那么传输时一样
如此。所以,字节流可以传输任意文件数据。在操作流的时候,我们要时刻明确,无论使用什么样的流对象,底层传
输的始终为二进制数据。
1.字节输出
java.io.OutputStream 抽象类是表示字节输出流的所有类的超类,将指定的字节信息写出到目的地。它定义了字
节输出流的基本共性功能方法。
public void close() :关闭此输出流并释放与此流相关联的任何系统资源。
public void flush() :刷新此输出流并强制任何缓冲的输出字节被写出。
public void write(byte[] b) :将 b.length字节从指定的字节数组写入此输出流。
public void write(byte[] b, int off, int len) :从指定的字节数组写入 len字节,从偏移量 offff开始
输出到此输出流。
public abstract void write(int b) :将指定的字节输出流。
小贴士:
close方法,当完成流的操作时,必须调用此方法,释放系统资源
2.写入字节数据
package com.xjggb.strram;
public class Demo01 {
public static void main(String[] args) throws IOException {
//获取文件
File file1 = new File("D:\\li\\1.txt");
//创建流对象
FileOutputStream fileOutputStream = new FileOutputStream(file1);
System.out.println("fileOutputStream = " + fileOutputStream);
byte[] bytes = "行健乖乖霸".getBytes();
//写入字节
fileOutputStream.write(bytes);
//关闭流
fileOutputStream.close();
}
}
3.写出指定长度字节数组
write(byte[] b, int off, int len) ,每次写出从offff索引开始,len个字节,代码
使用演示:
package com.xjggb.strram;
public class Demo01 {
public static void main(String[] args) throws IOException {
//获取文件
File file1 = new File("D:\\li\\1.txt");
//创建流对象
FileOutputStream fileOutputStream = new FileOutputStream(file1);
System.out.println("fileOutputStream = " + fileOutputStream);
byte[] bytes = "abdce".getBytes();
// 写出从索引2开始,2个字节。索引2是d,两个字节,也就是dc。
fileOutputStream.write(bytes,2,2);
//关闭流
fileOutputStream.close();
}
}
4.数据追加续写
经过以上的演示,每次程序运行,创建输出流对象,都会清空目标文件中的数据。如何保留目标文件中数据,还能继
续添加新数据呢?
public FileOutputStream(File file, boolean append) : 创建文件输出流以写入由指定的 File对象表示
的文件。
public FileOutputStream(String name, boolean append) : 创建文件输出流以指定的名称写入文件。
这两个构造方法,参数中都需要传入一个boolean类型的值, true 表示追加数据, false 表示清空原有数据。这样
创建的输出流对象,就可以指定是否追加续写了,代码使用演示:
package com.xjggb.strram;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
public class Demo01 {
public static void main(String[] args) throws IOException {
//获取文件
File file1 = new File("D:\\li\\1.txt");
//创建流对象
FileOutputStream fileOutputStream = new FileOutputStream(file1,true);
System.out.println("fileOutputStream = " + fileOutputStream);
byte[] bytes = "abdce".getBytes();
// 写出从索引2开始,2个字节。索引2是d,两个字节,也就是dc。
fileOutputStream.write(bytes,2,2);
//关闭流
fileOutputStream.close();
}
}
5.写出换行
Windows系统里,换行符号是 \r\n 。把
以指定是否追加续写了,代码使用演示
package com.xjggb.strram;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
public class Demo01 {
public static void main(String[] args) throws IOException {
//获取文件
File file1 = new File("D:\\li\\1.txt");
//创建流对象
FileOutputStream fileOutputStream = new FileOutputStream(file1,true);
//定义数组
byte [] words={97,98,99,100,101};
//遍历数组
for (int i = 0; i < words.length; i++) {
fileOutputStream.write(words[i]);
// 写出一个换行, 换行符号转成数组写出
fileOutputStream.write("\r\n".getBytes());
}
//关闭资源
fileOutputStream.close();
}
}
回车符 \r 和换行符 \n :
回车符:回到一行的开头(return)。
下一行(newline)。
系统中的换行:
Windows系统里,每行结尾是 回车+换行 ,即 \r\n ;
Unix系统里,每行结尾只有 换行 ,即 \n ;
Mac系统里,每行结尾是 回车 ,即 \r 。从 Mac OS X开始与Linux统一。
2.字节输入流【InputStream】
java.io.InputStream 抽象类是表示字节输入流的所有类的超类,可以读取字节信息到内存中。它定义了字节输入
流的基本共性功能方法。
public void close() :关闭此输入流并释放与此流相关联的任何系统资源。
public abstract int read() : 从输入流读取数据的下一个字节。
public int read(byte[] b) : 从输入流中读取一些字节数,并将它们存储到字节数组 b中
1.FilelInputStream类
java.io.FileInputStream 类是文件输入流,从文件中读取字节
构造方法
FileInputStream(File file) : 通过打开与实际文件的连接来创建一个 FileInputStream ,该文件由文件系
统中的 File对象 fifile命名。
FileInputStream(String name) : 通过打开与实际文件的连接来创建一个 FileInputStream ,该文件由文件
系统中的路径名 name命名。
代码如下
package com.xjggb.strram;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
public class Demo02 {
public static void main(String[] args) throws IOException {
//获取文件
File file1 = new File("D:\\li\\1.txt");
//方式一
FileInputStream fileInputStream = new FileInputStream(file1);
//方式二
FileInputStream fileInputStream1 = new FileInputStream("D:\\li\\1.txt");
}
}
读取字节数据
- 读取字节: read 方法,每次可以读取一个字节的数据,提升为int类型,读取到文件末尾,返回 -1 ,代码使用
演示
package com.xjggb.strram;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
public class Demo02 {
public static void main(String[] args) throws IOException {
//获取文件
File file1 = new File("D:\\li\\1.txt");
//方式一
FileInputStream fileInputStream = new FileInputStream(file1);
int b;
while ((b=fileInputStream.read())!=-1){
System.out.println("b = " +(char) b);
}
//关闭资源
fileInputStream.close();
}
}
小结:
流操作完后必须关闭流
2.字节流练习 图片复制
package com.xjggb.strram;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
public class Demo03 {
public static void main(String[] args) throws IOException {
//创建流对象读书数据
FileInputStream fileInputStream = new FileInputStream("C:\\Users\\lenovo\\Pictures\\Saved Pictures\\1.jpg");
//写入数据
FileOutputStream fileOutputStream = new FileOutputStream("D:\\li\\1.jpg");
//定义数组
byte [] b=new byte[1024*1000];
//定义长度
int len;
while ((len=fileInputStream.read(b))!=-1){
fileOutputStream.write(b,0,len);
}
//关闭流
fileInputStream.close();
fileOutputStream.close();
}
}
3.字符流输入流【Reader】
当使用字节流读取文本文件时,可能会有一个小问题。就是遇到中文字符时,可能不会显示完整的字符,那是因为一
个中文字符可能占用多个字节存储。所以Java提供一些字符流类,以字符为单位读写数据,专门用于处理文本文件。
5.1 **字符输入流【Reader】
java.io.Reader 抽象类是表示用于读取字符流的所有类的超类,可以读取字符信息到内存中。它定义了字符输入流
的基本共性功能方法。
public void close() :关闭此流并释放与此流相关联的任何系统资源。
public int read() : 从输入流读取一个字符。
public int read(char[] cbuf) : 从输入流中读取一些字符,并将它们存储到字符数组 cbuf中 。
1. FileReader类
java.io.FileReader 类是读取字符文件的便利类。构造时使用系统默认的字符编码和默认字节缓冲区。
构造方法
FileReader(File file) : 创建一个新的 FileReader ,给定要读取的File对象。
FileReader(String fileName) : 创建一个新的 FileReader ,给定要读取的文件的名称。
当你创建一个流对象时,必须传入一个文件路径。类似于FileInputStream 。
代码如下
package com.xjggb.strram;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileReader;
public class Demo04 {
public static void main(String[] args) throws FileNotFoundException {
//方式1
// 使用File对象创建流对象
File file = new File("D:\\li\\1.txt");
FileReader fileReader1 = new FileReader(file);
//方式二
// 使用文件名称创建流对象
FileReader fileReader = new FileReader("D:\\li\\1.txt");
}
}
2.读取字符数据
读取字符: read 方法,每次可以读取一个字符的数据,提升为int类型,读取到文件末尾,返回 -1 ,循环读
取,代码使用演示:
package com.xjggb.strram;
import java.io.*;
public class Demo04 {
public static void main(String[] args) throws IOException {
//方式二
// 使用文件名称创建流对象
FileReader fileReader = new FileReader("D:\\li\\1.txt");
int b;
while ((b=fileReader.read())!=-1){
System.out.println("b = " + (char)b);
}
//关闭资源
fileReader.close();
}
}
3.使用字节数组读取
\2. 使用字符数组读取: read(char[] cbuf) ,每次读取b的长度个字符到数组中,返回读取到的有效字符个数,
读取到末尾时,返回 -1 ,代码使用演示:
package com.xjggb.strram;
import java.io.*;
public class Demo04 {
public static void main(String[] args) throws IOException {
//方式二
// 使用文件名称创建流对象
FileReader fileReader = new FileReader("D:\\li\\1.txt");
int read ;
char[] chars = new char[1024*10];
while ((read=fileReader.read(chars))!=-1){
System.out.println(new String(chars,0,read));
}
//关闭流
fileReader.close();
}
}
4.字符输出流
java.io.Writer 抽象类是表示用于写出字符流的所有类的超类,将指定的字符信息写出到目的地。它定义了字节输
出流的基本共性功能方法。
public abstract void close() :关闭此输出流并释放与此流相关联的任何系统资源。
public abstract void flush() :刷新此输出流并强制任何缓冲的输出字符被写出。
public void write(int c) :写出一个字符。
public void write(char[] cbuf) :将 b.length字符从指定的字符数组写出此输出流。
public abstract void write(char[] b, int off, int len) :从指定的字符数组写出 len字符,从偏移
量 offff开始输出到此输出流。
public void write(String str) :写出一个字符串
1.构造方法
FileWriter(File file) : 创建一个新的 FileWriter,给定要读取的File对象。
FileWriter(String fileName) : 创建一个新的 FileWriter,给定要读取的文件的名称。
package com.xjggb.strram;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
public class Demo05 {
public static void main(String[] args) throws IOException {
//使用file对象创建流
File file = new File("D:\\li\\1.txt");
FileWriter fileWriter1 = new FileWriter(file);
// 使用文件名称创建流对象
FileWriter fileWriter = new FileWriter("D:\\li\\1.txt");
}
}
2.写出基本数据
写出字符: write(int b) 方法,每次可以写出一个字符数据,代码使用演示:
package com.xjggb.strram;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
public class Demo05 {
public static void main(String[] args) throws IOException {
//使用file对象创建流
File file = new File("D:\\li\\1.txt");
FileWriter fileWriter1 = new FileWriter(file);
// 使用文件名称创建流对象
FileWriter fileWriter = new FileWriter("D:\\li\\1.txt");
fileWriter.write("来了老弟");
/*【注意】关闭资源时,与FileOutputStream不同。
如果不关闭,数据只是保存到缓冲区,并未保存到文件。
*/
fileWriter.close();
}
}
3.关闭和刷新
因为内置缓冲区的原因,如果不关闭输出流,无法写出字符到文件中。但是关闭的流对象,是无法继续写出数据的。
如果我们既想写出数据,又想继续使用流,就需要 flush 方法了。
flush :刷新缓冲区,流对象可以继续使用。
close :关闭流,释放系统资源。关闭前会刷新缓冲区。
package com.xjggb.strram;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
public class Demo05 {
public static void main(String[] args) throws IOException {
//使用file对象创建流
File file = new File("D:\\li\\1.txt");
FileWriter fileWriter1 = new FileWriter(file);
// 使用文件名称创建流对象
FileWriter fileWriter = new FileWriter("D:\\li\\1.txt");
fileWriter.write("来了老弟");
fileWriter.flush();
fileWriter.write("你好啊");
fileWriter.flush();
fileWriter.write("关");
/*【注意】关闭资源时,与FileOutputStream不同。
如果不关闭,数据只是保存到缓冲区,并未保存到文件。
*/
fileWriter.close();
}
}
4.写其他数据
写出字符串: write(String str) 和 write(String str, int off, int len) ,每次可以写出字符串中
的数据,更为方便,代码使用演示:
package com.xjggb.strram;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
public class Demo05 {
public static void main(String[] args) throws IOException {
// 使用文件名称创建流对象
FileWriter fileWriter = new FileWriter("D:\\li\\1.txt");
String s = "行健乖乖霸";
fileWriter.write(s);
fileWriter.write(s,2,2);
/*【注意】关闭资源时,与FileOutputStream不同。
如果不关闭,数据只是保存到缓冲区,并未保存到文件。
*/
fileWriter.close();
}
}
5.续写和换行
package com.xjggb.strram;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
public class Demo05 {
public static void main(String[] args) throws IOException {
// 使用文件名称创建流对象
FileWriter fileWriter = new FileWriter("D:\\li\\1.txt");
String s = "行健乖乖霸";
fileWriter.write(s);
fileWriter.write("\r\n");
fileWriter.write("是我");
/*【注意】关闭资源时,与FileOutputStream不同。
如果不关闭,数据只是保存到缓冲区,并未保存到文件。
*/
fileWriter.close();
}
}
5.IO资源的异常处理
1.JDK7前的处理
之前的入门练习,我们一直把异常抛出,而实际开发中并不能这样处理,建议使用 try…catch…finally 代码
块,处理异常部分,代码使用演示:
package com.xjggb.io;
import java.io.FileWriter;
import java.io.IOException;
public class Demo01 {
public static void main(String[] args) {
FileWriter fileWriter=null;
try {
fileWriter = new FileWriter("fw.txt");
fileWriter.write("行健乖乖把");
} catch (IOException e) {
e.printStackTrace();
}finally {
try {
if (fileWriter!=null){
fileWriter.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
2.JDk7的处理
还可以使用JDK7优化后的 try-with-resource 语句,该语句确保了每个资源在语句结束时关闭。所谓的资源
(resource)是指在程序完成后,必须关闭的对象。
格式:
try (创建流对象语句,如果多个,使用';'隔开) {
// 读写数据
} catch (IOException e) {
e.printStackTrace();
}
package com.xjggb.io;
import java.io.FileWriter;
import java.io.IOException;
public class Demo01 {
public static void main(String[] args) {
try(FileWriter fileWriter1 = new FileWriter("fw.txt");
FileWriter fileWriter2 = new FileWriter("fw.txt");
) {
fileWriter1.write("来了老弟");
fileWriter2.write("来了老弟");
} catch (IOException e) {
e.printStackTrace();
}
}
}
6.Properties类
java.util.Properties 继承于 Hashtable ,来表示一个持久的属性集。它使用键值结构存储数据,每个键及其
对应值都是一个字符串。该类也被许多Java类使用,比如获取系统属性时, System.getProperties 方法就是返回
一个 Properties 对象。
1.Properties类构造方法
public Properties() :创建一个空的属性列表。
2.基本方法
public Object setProperty(String key, String value) : 保存一对属性。
public String getProperty(String key) :使用此属性列表中指定的键搜索属性值。
public Set stringPropertyNames() :所有键的名称的集合
package com.xjggb.io;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Properties;
import java.util.Set;
public class Demo01 {
public static void main(String[] args) {
//创建属性对象
Properties properties = new Properties();
//添加属性值
properties.setProperty("add","oooo");
properties.setProperty("acc","来了老弟");
properties.setProperty("abb","行健乖乖把");
properties.setProperty("aaa","你好坏");
//打印属性对象
System.out.println("properties = " + properties);
//获取所有的键
Set<String> strings = properties.stringPropertyNames();
for (String string : strings) {
System.out.println("properties.getProperty(string) = " + properties.getProperty(string));
}
}
}
3.与流相关的方法
public void load(InputStream inStream) : 从字节输入流中读取键值对。
package com.xjggb.io;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Properties;
import java.util.Set;
public class Demo02 {
public static void main(String[] args) throws IOException {
show2();
}
//读取数据
public static void show2() throws IOException {
final Properties properties = new Properties();
//读取数据
properties.load(new FileInputStream("D:\\text-ex\\demo01\\adn\\a.txt"));
//获取所有的key
final Set<String> strings = properties.stringPropertyNames();
for (String string : strings) {
System.out.println("properties.getProperty(string) = " + properties.getProperty(string));
}
}
//写入数据
public static void show1() throws IOException {
Properties properties = new Properties();
properties.setProperty("name","凤姐");
properties.setProperty("age","18");
properties.store(new FileOutputStream("D:\\text-ex\\demo01\\adn\\a.txt"),"我喜欢你");
}
}
小结:
- getProperty(String key)的作用? 通过键获取值
- setProperty(String key,String value)的作用? 添加键值对
- stringPropertyNames()的作用? 获取所有的键
- void load(InputStream inStream) 从流中读取键值对
- store(OutputStream out, String comments) 往流中写入键值对
7.缓冲流
前面我们学习了一些基本的流,作为IO流的入门,今天我们要见识一些更强大的流。比如能够高效读写的缓冲流,能够转
换编码的转换流,能够持久化存储对象的序列化流等等。这些功能更为强大的流,都是在基本的流对象基础之上创建
而来的,就像穿上铠甲的武士一样,相当于是对基本流对象的一种增强。
1.字节缓冲流
缓冲流,也叫高效流,是对4个基本的 FileXxx 流的增强,所以也是4个流,按照数据类型分类:
字节缓冲流: BufferedInputStream , BufferedOutputStream
字符缓冲流: BufferedReader , BufferedWriter
缓冲流的基本原理,是在创建流对象时,会创建一个内置的默认大小的缓冲区数组,通过缓冲区读写,减少系统IO次
数,从而提高读写的效率。
1.字节缓冲流 构造方法
public BufferedInputStream(InputStream in) :创建一个 新的缓冲输入流。
public BufferedOutputStream(OutputStream out) : 创建一个新的缓冲输出流。
代码如下:
package com.xjggb.buff;
import java.io.*;
public class Demo01 {
public static void main(String[] args) throws FileNotFoundException {
// 创建字节缓冲输入流
BufferedInputStream bis = new BufferedInputStream(new FileInputStream("bis.txt"));
// 创建字节缓冲输出流
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("bos.txt"));
}
}
2.字节缓冲流入门
package com.xjggb.buff;
import java.io.*;
public class Demo01 {
public static void main(String[] args) throws Exception {
show1();
}
//写入操作
public static void show2() throws Exception {
//创建io流
FileOutputStream stream = new FileOutputStream("D:\\text-ex\\demo01\\adn\\a.txt");
// 创建字节缓冲输出流
BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(stream);
//写入数据
final byte[] bytes = "来了老弟".getBytes();
bufferedOutputStream.write(bytes);
bufferedOutputStream.close();
stream.close();
}
//读取操作
public static void show1() throws IOException {
FileInputStream fos = new FileInputStream("demo01\\adn\\a.txt");
BufferedInputStream bis = new BufferedInputStream(fos);
int b;
while ((b = bis.read()) != -1) {
System.out.println((char)b);
}
bis.close();
}
}
3.效率测试
四种方式复制:
基本流读取一个字节
基本流读取一个字节数组
缓冲流读取一个字节
缓冲流读取一个字节字节数组
package com.xjggb.io;
import java.io.*;
import java.util.Date;
public class Demo03 {
public static void main(String[] args) throws IOException {
/*
*
四种方式复制:
基本流读取一个字节
基本流读取一个字节数组
缓冲流读取一个字节
缓冲流读取一个字节字节数组
*
* */
/* //基本流读取一个字节
long l = System.currentTimeMillis();
show1();
long l1 = System.currentTimeMillis();
System.out.println("l1 = " + (l1-l)); // 用了 15961 毫秒
*/
/* //基本读取一个字节数组
long l = System.currentTimeMillis();
show2();
long l1 = System.currentTimeMillis();
System.out.println("l1 = " + (l1-l)); // 用了 16 毫秒
*/
/* //缓冲流读取一个字节
long l = System.currentTimeMillis();
show3();
long l1 = System.currentTimeMillis();
System.out.println("l1 = " + (l1-l)); // 用了 110 毫秒*/
long l = System.currentTimeMillis();
show4();
long l1 = System.currentTimeMillis();
System.out.println("l4 = " + (l1-l)); // 用了 43 毫秒
}
//缓冲流读取一个字节数组
public static void show4() throws IOException {
File file = new File("C:\\Users\\lenovo\\Pictures\\Saved Pictures\\1.jpg");
//读取数据流
FileInputStream fileInputStream = new FileInputStream(file);
//写入数据流
FileOutputStream fileOutputStream = new FileOutputStream("D:\\li\\xiwa.jpg");
//创建缓冲输入流
BufferedInputStream bufferedInputStream = new BufferedInputStream(fileInputStream);
//创建缓冲输出流
BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(fileOutputStream);
//创建数组
byte[] bytes = new byte[1024];
//定义接收变量
int len;
while ((len=bufferedInputStream.read(bytes))!=-1){
bufferedOutputStream.write(bytes,0,len);
}
//关闭资源
bufferedOutputStream.close();
bufferedInputStream.close();
fileOutputStream.close();
fileInputStream.close();
}
//缓冲流读取一个字节
public static void show3() throws IOException {
File file = new File("C:\\Users\\lenovo\\Pictures\\Saved Pictures\\1.jpg");
//读取数据流
FileInputStream fileInputStream = new FileInputStream(file);
//写入数据流
FileOutputStream fileOutputStream = new FileOutputStream("D:\\li\\xiwa.jpg");
//创建缓冲输入流
BufferedInputStream bufferedInputStream = new BufferedInputStream(fileInputStream);
//创建缓冲输出流
BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(fileOutputStream);
int len;
while ((len=bufferedInputStream.read())!=-1){
//写入数据
bufferedOutputStream.write(len);
}
//关闭资源
bufferedOutputStream.close();
bufferedInputStream.close();
fileOutputStream.close();
fileInputStream.close();
}
//读取一个字节数组
public static void show2() throws IOException {
File file = new File("C:\\Users\\lenovo\\Pictures\\Saved Pictures\\1.jpg");
//读取数据流
FileInputStream fileInputStream = new FileInputStream(file);
//写入数据流
FileOutputStream fileOutputStream = new FileOutputStream("D:\\li\\xiwa.jpg");
//创建数组
byte[] bytes = new byte[1024*8];
//定义变量
int len;
while ((len=fileInputStream.read(bytes))!=-1){
//写数据
fileOutputStream.write(bytes,0,len);
}
//关闭资源
fileOutputStream.close();
fileInputStream.close();
}
//读取一个字节
public static void show1() throws IOException {
File file = new File("C:\\Users\\lenovo\\Pictures\\Saved Pictures\\1.jpg");
//读取数据流
FileInputStream fileInputStream = new FileInputStream(file);
//写入数据流
FileOutputStream fileOutputStream = new FileOutputStream("D:\\li\\xiwa.jpg");
int len;
while ((len=fileInputStream.read())!=-1){
//写入数据
fileOutputStream.write(len);
}
//关闭资源
fileOutputStream.close();
fileInputStream.close();
}
}
2.字符缓冲流
1.构造方法
public BufferedReader(Reader in) :创建一个 新的缓冲输入流。
public BufferedWriter(Writer out) : 创建一个新的缓冲输出流。
代码如下
package com.xjggb.io;
import java.io.*;
public class Demo04 {
public static void main(String[] args) throws IOException {
//创建字符缓冲流输入流
BufferedReader bufferedReader = new BufferedReader(new FileReader("a.txt"));
//创建字符缓冲输出流
BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter("a.txt"));
}
}
2.特有方法
字符缓冲流的基本方法与普通字符流调用方式一致,不再阐述,我们来看它们具备的特有方法。
BufferedReader: public String readLine() : 读一行文字。
BufferedWriter: public void newLine() : 写一行行分隔符,由系统属性定义符号。
package com.xjggb.io;
import java.io.*;
public class Demo04 {
public static void main(String[] args) throws IOException {
// show1();
show2();
}
//一行一行的读取
public static void show1() throws IOException {
BufferedReader bufferedReader = new BufferedReader(new FileReader("D:\\text-ex\\demo01\\adn\\a.txt"));
//定义字符串
String len=null;
while ((len=bufferedReader.readLine())!=null){
System.out.println("len = " + len);
}
bufferedReader.close();
}
//换行写入
public static void show2() throws IOException {
BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter("D:\\text-ex\\demo01\\adn\\a.txt"));
bufferedWriter.write("行健");
//换行
bufferedWriter.newLine();
bufferedWriter.write("乖乖");
//换行
bufferedWriter.newLine();
bufferedWriter.write("霸");
bufferedWriter.close();
}
}
3.练习文本排序
3.侍中、侍郎郭攸之、费祎、董允等,此皆良实,志虑忠纯,是以先帝简拔以遗陛下。愚以为宫中之事,事无大小,悉以咨 之,然后施行,必得裨补阙漏,有所广益。
8.愿陛下托臣以讨贼兴复之效,不效,则治臣之罪,以告先帝之灵。若无兴德之言,则责攸之、祎、允等之慢,以彰其咎;陛 下亦宜自谋,以咨诹善道,察纳雅言,深追先帝遗诏,臣不胜受恩感激。
4.将军向宠,性行淑均,晓畅军事,试用之于昔日,先帝称之曰能,是以众议举宠为督。愚以为营中之事,悉以咨之,必能使 行阵和睦,优劣得所。
2.宫中府中,俱为一体,陟罚臧否,不宜异同。若有作奸犯科及为忠善者,宜付有司论其刑赏,以昭陛下平明之理,不宜偏 私,使内外异法也。
1.先帝创业未半而中道崩殂,今天下三分,益州疲弊,此诚危急存亡之秋也。然侍卫之臣不懈于内,忠志之士忘身于外者,盖 追先帝之殊遇,欲报之于陛下也。诚宜开张圣听,以光先帝遗德,恢弘志士之气,不宜妄自菲薄,引喻失义,以塞忠谏之路 也。
9.今当远离,临表涕零,不知所言。
6.臣本布衣,躬耕于南阳,苟全性命于乱世,不求闻达于诸侯。先帝不以臣卑鄙,猥自枉屈,三顾臣于草庐之中,咨臣以当世 之事,由是感激,遂许先帝以驱驰。后值倾覆,受任于败军之际,奉命于危难之间,尔来二十有一年矣。 7.先帝知臣谨慎,故临崩寄臣以大事也。受命以来,夙夜忧叹,恐付托不效,以伤先帝之明,故五月渡泸,深入不毛。今南方 已定,兵甲已足,当奖率三军,北定中原,庶竭驽钝,攘除奸凶,兴复汉室,还于旧都。此臣所以报先帝而忠陛下之职分也。 至于斟酌损益,进尽忠言,则攸之、祎、允之任也。
5.亲贤臣,远小人,此先汉所以兴隆也;亲小人,远贤臣,此后汉所以倾颓也。先帝在时,每与臣论此事,未尝不叹息痛恨于 桓、灵也。侍中、尚书、长史、参军,此悉贞良死节之臣,愿陛下亲之信之,则汉室之隆,可计日而待也。
代码如下
package com.xjggb.io;
import java.io.*;
import java.util.HashMap;
public class Demo05 {
public static void main(String[] args) throws IOException {
//创建map
HashMap<String , String> map = new HashMap<>();
//字符输入流
BufferedReader bufferedReader = new BufferedReader(new FileReader("E:\\资料\\javaee资料\\day10\\source\\in.txt"));
//创建字符输出流
BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter("D:\\text-ex\\demo01\\adn\\a.txt"));
String len;
//一行一行的读取
while ((len=bufferedReader.readLine())!=null){
//解析文本 . 代表全部,需要转义
String[] split = len.split("\\.");
map.put(split[0],split[1]);
}
//释放资源
bufferedReader.close();
//遍历集合
for (int i = 1; i < map.size(); i++) {
//获取全部的key
String key = String.valueOf(i);
//获取vlue
String value = map.get(key);
//拼接文本
bufferedWriter.write(key+"."+value);
//换行
bufferedWriter.newLine();
}
//释放资源
bufferedWriter.close();
}
}
排序后
1.先帝创业未半而中道崩殂,今天下三分,益州疲弊,此诚危急存亡之秋也。然侍卫之臣不懈于内,忠志之士忘身于外者,盖追先帝之殊遇,欲报之于陛下也。诚宜开张圣听,以光先帝遗德,恢弘志士之气,不宜妄自菲薄,引喻失义,以塞忠谏之路也。
2.宫中府中,俱为一体,陟罚臧否,不宜异同。若有作奸犯科及为忠善者,宜付有司论其刑赏,以昭陛下平明之理,不宜偏私,使内外异法也。
3.侍中、侍郎郭攸之、费祎、董允等,此皆良实,志虑忠纯,是以先帝简拔以遗陛下。愚以为宫中之事,事无大小,悉以咨之,然后施行,必得裨补阙漏,有所广益。
4.将军向宠,性行淑均,晓畅军事,试用之于昔日,先帝称之曰能,是以众议举宠为督。愚以为营中之事,悉以咨之,必能使行阵和睦,优劣得所。
5.亲贤臣,远小人,此先汉所以兴隆也;亲小人,远贤臣,此后汉所以倾颓也。先帝在时,每与臣论此事,未尝不叹息痛恨于桓、灵也。侍中、尚书、长史、参军,此悉贞良死节之臣,愿陛下亲之信之,则汉室之隆,可计日而待也。
6.臣本布衣,躬耕于南阳,苟全性命于乱世,不求闻达于诸侯。先帝不以臣卑鄙,猥自枉屈,三顾臣于草庐之中,咨臣以当世之事,由是感激,遂许先帝以驱驰。后值倾覆,受任于败军之际,奉命于危难之间,尔来二十有一年矣。
7.先帝知臣谨慎,故临崩寄臣以大事也。受命以来,夙夜忧叹,恐付托不效,以伤先帝之明,故五月渡泸,深入不毛。今南方已定,兵甲已足,当奖率三军,北定中原,庶竭驽钝,攘除奸凶,兴复汉室,还于旧都。此臣所以报先帝而忠陛下之职分也。至于斟酌损益,进尽忠言,则攸之、祎、允之任也。
8.愿陛下托臣以讨贼兴复之效,不效,则治臣之罪,以告先帝之灵。若无兴德之言,则责攸之、祎、允等之慢,以彰其咎;陛下亦宜自谋,以咨诹善道,察纳雅言,深追先帝遗诏,臣不胜受恩感激。
小结:
特有的方法
- readLine() 只读取一行
- newLine() 换行写
8.转换流
字符编码
计算机中储存的信息都是用二进制数表示的,而我们在屏幕上看到的数字、英文、标点符号、汉字等字符是二进制数
转换之后的结果。按照某种规则,将字符存储到计算机中,称为编码 。反之,将存储在计算机中的二进制数按照某
种规则解析显示出来,称为解码 。比如说,按照A规则存储,同样按照A规则解析,那么就能显示正确的文本f符号。
反之,按照A规则存储,再按照B规则解析,就会导致乱码现象。
1.InputStreamReader
转换流 java.io.InputStreamReader ,是Reader的子类,是从字节流到字符流的桥梁。它读取字节,并使用指定
的字符集将其解码为字符。它的字符集可以由名称指定,也可以接受平台的默认字符集。
1.构造方法
InputStreamReader(InputStream in) : 创建一个使用默认字符集的字符流。
InputStreamReader(InputStream in, String charsetName) : 创建一个指定字符集的字符流。
package com.xjggb.io;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
public class Demo06 {
public static void main(String[] args) throws FileNotFoundException, UnsupportedEncodingException {
FileInputStream fileInputStream = new FileInputStream("D:\\text-ex\\demo01\\adn\\gbk.txt");
InputStreamReader inputStreamReader1 = new InputStreamReader(fileInputStream);
InputStreamReader inputStreamReader2= new InputStreamReader(fileInputStream,"GBK");
}
}
2.指定编码读取数据
package com.xjggb.io;
import java.io.*;
public class Demo06 {
public static void main(String[] args) throws IOException {
show2();
}
//根据utf-8编码读取数据
public static void show2() throws IOException {
FileInputStream fileInputStream = new FileInputStream("D:\\text-ex\\demo01\\adn\\gbk.txt");
InputStreamReader inputStreamReader2= new InputStreamReader(fileInputStream,"utf-8");
//定义变量
int len;
while ((len=inputStreamReader2.read())!=-1){
System.out.println("len = " + (char)len);
/*
* len = 来
len = 了
len = 老
len = 弟
* */
}
}
//根据GBK编码读取
public static void show1() throws IOException {
FileInputStream fileInputStream = new FileInputStream("D:\\text-ex\\demo01\\adn\\gbk.txt");
InputStreamReader inputStreamReader2= new InputStreamReader(fileInputStream,"gbk");
//定义变量
int len;
while ((len=inputStreamReader2.read())!=-1){
System.out.println("len = " + (char)len);
/*
输出
* len = 鏉
len = ヤ
len = 簡
len = 鑰
len = 佸
len = 紵
*/
}
}
}
2.OutputStreamWriter
转换流 java.io.OutputStreamWriter ,是Writer的子类,是从字符流到字节流的桥梁。使用指定的字符集将字符
编码为字节。它的字符集可以由名称指定,也可以接受平台的默认字符集。
1.构造方法
OutputStreamWriter(OutputStream in) : 创建一个使用默认字符集的字符流。
OutputStreamWriter(OutputStream in, String charsetName) : 创建一个指定字符集的字符流。
2.指定编码写出
package com.xjggb.io;
import java.io.*;
public class Demo07 {
public static void main(String[] args) throws IOException {
show2();
}
//指定utf-8写入
public static void show2() throws IOException {
OutputStreamWriter outputStreamWriter = new OutputStreamWriter(new FileOutputStream("D:\\text-ex\\demo01\\adn\\utf-8.txt"),"utf-8");
//写入
outputStreamWriter.write("来了老弟");
//关闭资源
outputStreamWriter.close();
}
//指定gbk写出
public static void show1() throws IOException {
OutputStreamWriter outputStreamWriter = new OutputStreamWriter(new FileOutputStream("D:\\text-ex\\demo01\\adn\\gbk.txt"),"GBK");
//写入
outputStreamWriter.write("来了老弟");
//关闭资源
outputStreamWriter.close();
}
}
3.序列化
概述
Java 提供了一种对象序列化的机制。用一个字节序列可以表示一个对象,该字节序列包含该 对象的数据 、 对象的类型
和 对象中存储的属性 等信息。字节序列写出到文件之后,相当于文件中持久保存了一个对象的信息。
反之,该字节序列还可以从文件中读取回来,重构对象,对它进行反序列化。 对象的数据 、 对象的类型 和 对象中存储
的数据 信息,都可以用来在内存中创建对象。看图理解序列化:
1.ObjectOutputStream类
1.构造方法
public ObjectOutputStream(OutputStream out) : 创建一个指定OutputStream的 ObjectOutputStream。
package com.xjggb.io;
import java.io.*;
public class Demo08 {
public static void main(String[] args) throws IOException {
FileOutputStream fileOutputStream = new FileOutputStream("D:\\text-ex\\demo01\\adn\\xuliehua.txt");
ObjectOutputStream objectOutputStream = new ObjectOutputStream(fileOutputStream);
}
}
2.序列化操作
\1. 一个对象要想序列化,必须满足两个条件:
该类必须实现 java.io.Serializable 接口, Serializable 是一个标记接口,不实现此接口的类将不会使任
何状态序列化或反序列化,会抛出 NotSerializableException 。
该类的所有属性必须是可序列化的。如果有一个属性不需要可序列化的,则该属性必须注明是瞬态的,使用
transient 关键字修饰。
实体类
package com.xjggb.entity;
import java.io.Serializable;
public class Employee implements Serializable {
private static final long serialVersionUID = 666666666666666666L;
private String name;
private String address;
private transient int age; // transient瞬态修饰成员,不会被序列化
public Employee() {
}
public Employee(String name, String address, int age) {
this.name = name;
this.address = address;
this.age = age;
}
/**
* 获取
* @return name
*/
public String getName() {
return name;
}
/**
* 设置
* @param name
*/
public void setName(String name) {
this.name = name;
}
/**
* 获取
* @return address
*/
public String getAddress() {
return address;
}
/**
* 设置
* @param address
*/
public void setAddress(String address) {
this.address = address;
}
/**
* 获取
* @return age
*/
public int getAge() {
return age;
}
/**
* 设置
* @param age
*/
public void setAge(int age) {
this.age = age;
}
public String toString() {
return "Employee{name = " + name + ", address = " + address + ", age = " + age + "}";
}
}
代码如下
package com.xjggb.io;
import com.xjggb.entity.Employee;
import java.io.*;
public class Demo08 {
public static void main(String[] args) throws IOException {
show1();
}
//写入对象
public static void show1() throws IOException {
FileOutputStream fileOutputStream = new FileOutputStream("D:\\text-ex\\demo01\\adn\\xuliehua.txt");
ObjectOutputStream objectOutputStream = new ObjectOutputStream(fileOutputStream);
Employee employee = new Employee();
employee.setAddress("来了老弟");
employee.setAge(456);
employee.setName("行健乖乖霸");
//写入数据
objectOutputStream.writeObject(employee);
//释放资源
objectOutputStream.close();
}
}
2.ObjectInputStream类
ObjectInputStream反序列化流,将之前使用ObjectOutputStream序列化的原始数据恢复为对象。
1.构造方法
public ObjectInputStream(InputStream in) : 创建一个指定InputStream的ObjectInputStream。
2.反序列化操作
如果能找到一个对象的class文件,我们可以进行反序列化操作,调用 ObjectInputStream 读取对象的方法:
public final Object readObject () : 读取一个对象。
代码如下
package com.xjggb.io;
import com.xjggb.entity.Employee;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.ObjectInputStream;
public class Demo09 {
public static void main(String[] args) throws IOException, ClassNotFoundException {
FileInputStream fileInputStream = new FileInputStream("D:\\text-ex\\demo01\\adn\\xuliehua.txt");
//创建反序列化流
ObjectInputStream objectInputStream = new ObjectInputStream(fileInputStream);
Employee o = (Employee)objectInputStream.readObject();
System.out.println("o = " + o);
//释放资源
objectInputStream.close();
fileInputStream.close();
}
}
3.序列化集合
package com.xjggb.io;
import com.xjggb.entity.Employee;
import java.io.*;
import java.util.ArrayList;
public class Demo08 {
public static void main(String[] args) throws IOException, ClassNotFoundException {
show1();
show2();
}
//写入对象
public static void show1() throws IOException {
FileOutputStream fileOutputStream = new FileOutputStream("D:\\text-ex\\demo01\\adn\\xuliehua.txt");
ObjectOutputStream objectOutputStream = new ObjectOutputStream(fileOutputStream);
Employee employee1 = new Employee("来了老弟","行健乖乖霸",456);
Employee employee2 = new Employee("来了","行健乖",45);
Employee employee3 = new Employee("来了老","行健乖乖霸",6);
ArrayList<Employee> employees = new ArrayList<>();
employees.add(employee1);
employees.add(employee2);
employees.add(employee3);
//写入数据
objectOutputStream.writeObject(employees);
//释放资源
objectOutputStream.close();
}
//读取对象
public static void show2() throws IOException, ClassNotFoundException {
FileInputStream fileInputStream = new FileInputStream("D:\\text-ex\\demo01\\adn\\xuliehua.txt");
ObjectInputStream objectInputStream = new ObjectInputStream(fileInputStream);
ArrayList<Employee> o = (ArrayList<Employee>) objectInputStream.readObject();
for (Employee employee : o) {
System.out.println("employee = " + employee);
}
}
}
小结
- 写入对象 ObjectOutputStream类
- 读去文件对象ObjectInputStream类
4随机访问文件
package com.xjggb.io;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;
public class Demo10 {
public static void main(String[] args) throws IOException {
/*
RandomAccessFile(File file, String mode)
RandomAccessFile(String name, String mode)
String name: 指定文件
String mode: 操作的模式 r: 只读 rw: 可读可写
*/
RandomAccessFile rw = new RandomAccessFile("D:\\text-ex\\demo01\\adn\\random.txt", "rw");
// 读取第5个字节: seek: 可以移动操作的指针
rw.seek(5);
int read = rw.read();
System.out.println("read = " + (char)read);
//往第七个位置写65
rw.seek(7);
rw.write(65);
rw.close();
}
}
5.加密或者解密
package com.itheima.demo17扩展2;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
/*
目标:加密和解密
加密:改变原本的字节
解密:还原成原本的字节
^异或: boolen
true ^ true false
false ^ false false
false ^ true true
true ^ false true
相同为false,不同为true
^异或数字, 数字异或时,会先转成二进制再一位一位的异或
1表示true,0表示false
一个数字异或另一个数字两次等于本身
97 0110 0001
^ 5 0000 0101
-------------------
加密 100 0110 0100
^ 5 0000 0101
------------------------
97 0110 0001
小结:
加密和解密的本质是什么?
得到每个字节,修改
*/
public class Demo17 {
public static void main(String[] args) throws IOException {
// encode();
decode();
}
// 解密
public static void decode() throws IOException {
FileInputStream fis = new FileInputStream("C:\\MyFileTest\\加密.png");
FileOutputStream fos = new FileOutputStream("C:\\MyFileTest\\解密.png");
int b;
while ((b = fis.read()) != -1) {
// 加密,改变读取到的字节
// b = b ^ 5;
b ^= 5;
fos.write(b);
}
fis.close();
fos.close();
}
// 加密
public static void encode() throws IOException {
FileInputStream fis = new FileInputStream("day10demo\\abc\\xyz.png");
FileOutputStream fos = new FileOutputStream("C:\\MyFileTest\\加密.png");
int b;
while ((b = fis.read()) != -1) {
// 加密,改变读取到的字节
// b = b ^ 5;
b ^= 5;
fos.write(b);
}
fis.close();
fos.close();
}
}
标签:java,File,String,io,new,FFile,public,入门 来源: https://blog.csdn.net/qq_56113699/article/details/119381526
本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享; 2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关; 3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关; 4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除; 5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。