I/O是Input和Output的缩写,用于处理设备之间的数据传输
Java程序中,对于数据的输入/输出操作以流的形式进行
java.io包中提供了各种各样的“流’和接口,用以获得不同种类的数据,并通过标准的方法输入和输出数据
字节流(8bit):图像、音乐、视频等
字符流:txt文件等
输入流、输出流
节点流:直接作用在文件上
处理流:在节点流上操作的流,将节点流包起来
抽象基类 节点流 处理流
InputStream FileInputStream BufferedInputStream
OutputStream FileOutputStream BufferedOutputStream
Reader FileReader BufferedReader
Writer FileWriter BufferedWriter
将day24下的hello.txt文件内容读入程序中,并输出到控制台
1.实例化File类的对象,要指明操作的文件
2.提供具体的流
3.数据的读入
4.流的关闭
@Test
public void test() {
//1.实例化File类的对象,要指明操作的文件
File file = new File("hello.txt");
//2.提供具体的流
FileReader fileReader = null;
try {
fileReader = new FileReader(file);
//3.数据的读入
int read = fileReader.read();
while (read != -1) {
System.out.println((char) read);
read = fileReader.read();
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (fileReader != null) {
//4.流的关闭
try {
fileReader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
对read方法的操作升级
@Test
public void test1() {
//1.实例化File类的对象,要指明操作的文件
File file = new File("hello.txt");
//2.提供具体的流
FileReader fileReader = null;
try {
fileReader = new FileReader(file);
//3.数据的读入
int len;
char[] chars = new char[5];
/* while ((len=fileReader.read(chars))!=-1){
for (int i = 0; i < len; i++) {
System.out.print(chars[i]);
}
}*/
//方法二
while ((len = fileReader.read(chars)) != -1) {
System.out.print(new String(chars, 0, len));
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (fileReader != null) {
//4.流的关闭
try {
fileReader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
从内存中写入数据到硬盘的文件中
当要写入数据的文件在硬盘中不存在,不会报错会自动常见并将数据写入
当要写入数据的文件在硬盘中存在
要观察我们使用的构造器,如果使用构造器为new FileWiter(file,false)或者new FileWriter(file),那么就会将原有内容覆盖
如果使用构造器new FileWiter(file,true),就会在原有内容后面追加
1.实例化File的对象,要指明输出的文件
2.创建FileWriter输出流
3.进行输出操作
4.流的关闭
public class FileWTest {
@Test
public void test() {
File file = new File("youdao.txt");
FileWriter fw = null;
try {
fw = new FileWriter(file);
fw.write("我爱中国\n");
fw.write("佩罗西必死!!!");
} catch (IOException e) {
e.printStackTrace();
} finally {
if (fw != null) {
try {
fw.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
实现文件的赋值操作
1.创建File类的对象,指明读入和写出的文件
2.创建输入流和输出流
3.数组的读入与写出操作
4.输入流与输出流关闭
public class CopyTest {
@Test
public void test() {
//被复制的文件
File file = new File("hello.txt");
//目标文件
File file1 = new File("helloCopy.txt");
//创建输入流和输出流
FileReader reader=null;
FileWriter writer=null;
try {
reader=new FileReader(file);
writer=new FileWriter(file1);
//读入写入操作
char[] chars = new char[5];
int len;
while ((len = reader.read(chars))!=-1){
writer.write(chars,0,len);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
//流关闭
if(reader!=null){
try {
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (writer!=null) {
try {
writer.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
注意:try—catch执行完后就会将异常创建,下面的代码不会受到影响
图片不能使用字符流进行输入输出
对于文本文件(txt,java,c,cpp),使用字符流处理
对于非文本文件(jpg,doc,MP3,MP4,avi ppt),使用字节流处理
1.缓冲流
BufferedInputStream
BufferedOutputStream
BufferedReader
BufferedWriter
2.作用:提取流的读取、写入速度
1.创建文件类的实例化
2.创建节点流,构造器中输入new 的文件类
3.创建缓存流,构造器中输入new 的节点流
4.利用缓冲流对象进行写入,读取操作
5.关闭流向关闭外层的流再关闭内部的流(我们只需要关闭外层的流,内层流会自动帮我们关闭)
在读入时,缓冲流可以使用readline方法,获得一行字符,但是有个缺点,不会包含换行符,我们可以收到+“\n”,也可以使用缓冲的newLine()方法进行换行
把存储流的数组中每个元素进行异或运算
public class MIMI {
public static void main(String[] args) {
BufferedInputStream bis = null;
BufferedOutputStream bos = null;
try {
FileInputStream fileInputStream = new FileInputStream("123.JPG");
FileOutputStream fileOutputStream = new FileOutputStream("123111.JPG");
bis = new BufferedInputStream(fileInputStream);
bos = new BufferedOutputStream(fileOutputStream);
byte[] bytes = new byte[10];
int len = 0;
//加密
while ((len = bis.read(bytes)) != -1) {
for (int i = 0; i < len; i++) {
bytes[i] = (byte) (bytes[i]^5);
}
bos.write(bytes,0,len);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (bis != null) {
try {
bis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (bos != null) {
try {
bos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
因为加密操作是通过异或符号进行的所以,再执行一遍就可以解密
InputStreamReader:将一个字节输入流转换为字符的输入流
OutputStreamWriter:将一个字符的输出流转换为字节的输出流
解码:字节、字节数组====》字符数组、字符串
编码:字符数组、字符串====》字节、字节数组
ASCII:美国标准信息交换码。用一个字节的7位可以表示。
1S08859-1:拉丁码表。欧洲码表。用一个字节的8位表示。
GB2312:中国的中文编码表。
最多两个字节编码所有字符
GBK:中国的中文编码表升级,融合了更多的中文文字符号。最多两个字节编码
Unicode:国际标准码,融合了目前人类使用的所有字符。为每个字符分配唯一的字符码。所有的
UTF-8:变长的编码方式,可用1-4个字节来表示一个字符。
1.标准的输入、输出流
1.1
System.in:标准的输入流,默认从键盘输入
System.out:标准的输出流,默认输出到控制台
1.2
System类的setIn(InputStream is) / setOut(PrintStream ps)方式重新指定输入输出的流
1.3练习
从键盘翰入字符串,要求将读取到的整行字符串转成大写输出。然后继续进行输入操作,直至当输入“e"或者"exit”时,退出程序。
使用System.in实现。System.in===>转换流===》BufferedReader的readLine()
public class Test {
public static void main(String[] args) {
InputStreamReader is = new InputStreamReader(System.in);
BufferedReader br = new BufferedReader(is);
try {
while (true){
String line = br.readLine();
if(line.equalsIgnoreCase("e")||"exit".equalsIgnoreCase(line)){
System.out.println("程序退出!!!");
break;
}else {
System.out.println(line.toUpperCase());
}
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if(br!=null){
try {
br.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
PrintStream PrintWriter
DataInputStream DataOutputStream
作用:用于读取或写出基本数据类型的变量和字符串
注意点:读取不同类型的数据的顺序要与当初写入文件时,保存的数据的顺序一致!
flush()刷新操作,将内存中的数据写入文件