为什么建设文化馆网站,上海网站建设推荐,创意设计一个网站,东营新闻进入java IO部分的学习#xff0c;首先学习IO基础#xff0c;内容如下。需要了解流的概念、分类还有其他一些如集合与文件的转换#xff0c;字符编码问题等#xff0c;这次先学到字节流的读写数据#xff0c;剩余下次学完。
一、IO基础
1、背景
1.1 数据存储问题
变量…进入java IO部分的学习首先学习IO基础内容如下。需要了解流的概念、分类还有其他一些如集合与文件的转换字符编码问题等这次先学到字节流的读写数据剩余下次学完。
一、IO基础
1、背景
1.1 数据存储问题
变量、数组、对象和集合中存储的数据是暂时存在的一旦程序结束它们就会丢失。 解决为了永久保存程序创建的数据需要将其保存到磁盘文件中。 1.2 流与IO
1流 是一种抽象概念是对数据传输的总称。即数据在设备间的传输称为流流的本质是数据传输
Java 中所有数据都是用流读写的。流是一组有序的数据序列以输入流的形式获取输出流的形式输出将数据从一个地方带到另一个地方。(可类比水管里水的流动) 输入将数据从各种输入设备包括文件、键盘等中读取到内存中输出将数据写入到各种输出设备比如文件、显示器、磁盘等 流相关的类都封装在 java.io 包中且每个数据流都是一个对象。
可分为输入和输出两种模式 输入流文件、网络、数据库及其他数据源—输入流—目的地 输出流源—(输出流)—文件、网络、数据库及其他数据源 2Java 的 I/O输入/输出技术 作用处理设备间数据传输问题 将数据保存到文本文件和二进制文件中 以达到永久保存数据的要求。常见应用文件复制文件上传文件下载 2、流的分类
2.1 按流的方向
1输入流input 用于读数据 所有输入流类都是 InputStream 抽象类字节输入流和 Reader 抽象类字符输入流的子类 InputStream字节输入流结构------了解即可
FileInputStream 文件输入流
PipedInputStream 管道输入流
ObjectInputStream 对象输入流FilterInputStream 过滤器输入流
- PushBackInputStream 回压输入流
- BufferedInputStream 缓冲输入流
- DataInputStream 数据输入流SequenceInputStream 顺序输入流
ByteArrayInputStream 字节数组输入流
StringBufferInputStream 缓冲字符串输入流InputStream 类常用方法------掌握
read()方法重载3个
- int read()从输入流读入一个 8 字节的数据将它转换成一个 0~ 255 的整数返回一个整数如果遇到输入流的结尾返回 -1
- int read(byte[] b)从输入流读取若干字节的数据保存到参数 b 指定的字节数组中返回的字节数表示读取的字节数如果遇到输入流的结尾返回 -1
- int read(byte[] b,int off,int len)从输入流读取若干字节的数据保存到参数 b 指定的字节数组中其中 off 是指在数组中开始保存数据位置的起始下标len 是指读取字节的位数。返回的是实际读取的字节数如果遇到输入流的结尾则返回 -1close()关闭数据流当完成对数据流的操作之后需要关闭数据流
available()返回可以从数据源读取的数据流的位数
skip(long n)从输入流跳过参数 n 指定的字节数目markSupported()判断输入流是否可以重复读取
mark(int readLimit)如果输入流可以被重复读取从流的当前位置开始设置标记readLimit 指定可以设置标记的字节数
reset()使输入流重新定位到刚才被标记的位置这样可以重新读取标记过的数据两点注意 最后 3 个方法一般结合使用先用 markSupported() 判断如果可以重复读取则用 mark(int readLimit) 方法进行标记标记完成后可以用 read() 方法读取标记范围内的字节数最后用 reset() 方法使输入流重新定位到标记的位置继而完成重复读取操作。 Java 中的字符是 Unicode 编码双字节而 InputerStream 是用来处理单字节的在处理字符文本时不是很方便。这时可以使用 Java 的文本输入流 Reader 类该类是字符输入流的抽象类即所有字符输入流的实现都是它的子类该类的方法与 InputerSteam 类的方法类似不再赘述。 2输出流Output 用于写数据 所有输出流类都是 OutputStream 抽象类字节输出流和 Writer 抽象类字符输出流的子类 OutputStream字节输出流结构------了解即可
FileOutputStream 文件输出流
PipedOutputStream 管道输出流
ObjectOutputStream 对象输出流
FilterOutputStream 过滤器输出流
PrintStream 打印输出流
BufferedOutputStream 缓冲输出流
DataOutputStream 数据输出流
ByteArrayOutputStream 字节数组输出流OutputStream 类常用方法------掌握
write()方法重载3个
- int write(b)将指定字节的数据写入到输出流
- int write(byte[] b)将指定字节数组的内容写入输出流
- int write(byte[] b,int off,int len)将指定字节数组从 off 位置开始的 len 字节的内容写入输出流
close()关闭数据流
flush()刷新数据流2.2 按数据单位
一般IO流是按数据单位即数据类型来分的
流的使用:
- 如果数据通过window自带的记事本软件打开还可以读懂里面的内容就用字符流否则用字节流
- 如果不知道使用哪种类型的流就用字节流字节流是万能的流1字节流 写数据 字节流抽象基类父类
InputStream是字节输入流的所有类的超类父类
OutputStream是字节输出流的所有类的超类
子类名特点子类名称都是以其父类名作为子类名的后缀 (可参考上一节的输入流和输出流内容)FileOutputStream文件输出流用于将数据写入File FileOutputStream(String name)创建文件输出流以指定的名称写入文件 使用字节输出流写数据的步骤(创建对象–写数据–释放资源)
1、创建字节输出流对象做了3件事情
- 调用系统功能创建了文件
- 创建字节输出流对象
- 让字节输出流对象指向文件2、调用字节输出流对象的写数据方法
3、释放资源关闭此文件输出流并释放与此流相关联的任何系统资源示例1
import java.io.FileOutputStream;
import java.io.IOException;public class FileOutputStreamDemo1 {public static void main(String[] args) throws IOException { // 抛出异常// 创建字节输出流对象// FileOutputStream(String name)创建文件输出流以指定的名称写入文件FileOutputStream fosnew FileOutputStream(C:\\Users\\ASUS\\Desktop\\project1\\src\\fos.txt);/*做了三件事情1:调用系统功能创建了文件2:创建字节输出流对象3:让字节输出流对象指向创建好的文件*///void write(int b)将指定的字节写入此文件输出流fos.write(97); // afos.write(57); // 9 (是字符不是数字)fos.write(55); // 7 (是字符不是数字)// 最后都要释放资源// void close()关闭此文件输出流并释放与此流相关联的任何系统资源fos.close();}
}运行结果(会生成一个fos.txt文件打开查看内容如下)
a97字节流写数据的三种方式write()方法的重载–3个
int write(b)将指定字节的数据写入到输出流
int write(byte[] b)将指定字节数组的内容写入输出流
int write(byte[] b,int off,int len)将指定字节数组从 off 位置开始的 len 字节的内容写入输出流示例2
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.charset.StandardCharsets;public class FileOutputStreamDemo2 {public static void main(String[] args) throws IOException { // 抛出异常/*** 1.创建对象*/// 创建字节输出流对象// FileOutputStream(String name)创建文件输出流以指定的名称写入文件FileOutputStream fos1new FileOutputStream(C:\\Users\\ASUS\\Desktop\\project1\\src\\fos.txt);/*** 2.写数据(3种方式)*/// void write(int b)将指定的字节写入此文件输出流
// fos1.write(97);
// fos1.write(98);
// fos1.write(99);
// fos1.write(100);
// fos1.write(101); // 结果abcde// void write(byte[] b)将指定字节数组的内容写入输出流
// byte[] bys{97,98,99,100,101}; //方法1创建数组byte[] bysabcde.getBytes(); //方法2getBytes()方法
// fos1.write(bys); // 结果abcde// void write(byte[] b,int off,int len)将指定字节数组从 off 位置开始的 len 字节的内容写入输出流
// fos1.write(bys,0,bys.length); // 结果abcdefos1.write(bys,1,3); // 结果bcd/*** 3.释放资源*/fos1.close();}
}getBytes()方法使用注意
getBytes(String charsetName): 使用指定的字符集将字符串编码为 byte 序列并将结果存储到一个新的 byte 数组中。getBytes(): 使用平台的默认字符集将字符串编码为 byte 序列并将结果存储到一个新的 byte 数组中。字节流写数据的两个小问题 a、实现换行添加换行符
windows\r\n
linux\n
mac\rb、实现追加写入
public FileOutputStream(String name,boolean append)创建文件输出流以指定名称写入文件。若第二个参数为true则字节将写入文件的末尾而不是开头开头覆盖末尾追加
- 默认是false即写在开头这样每运行一次都会覆盖原内容追加写入时要改为true。示例3
import java.io.FileOutputStream;
import java.io.IOException;public class FileOutputStreamDemo3 {public static void main(String[] args) throws IOException {// 创建字节输出流对象//boolean append为true实现追加(将字节写入末尾而不是开头)FileOutputStream fos3new FileOutputStream(C:\\Users\\ASUS\\Desktop\\project1\\src\\fos.txt,true);// 写数据for(int i0;i10;i){fos3.write(hello.getBytes()); // getBytes()方法fos3.write(\r\n.getBytes()); // 每写完一次做一个换行}// 释放资源fos3.close();}
}补充 try-catch异常处理一般文件相关的异常直接用throws抛出即可但try-catch异常捕获方式也要了解不懂的可以回去看异常处理部分 finally在异常处理时提供finally块来执行所有清除操作。如IO流中的释放资源。特点被finally控制的语句一定会执行除非JVM退出 示例4
import java.io.FileOutputStream;
import java.io.IOException;public class FileOutputStreamDemo4 {public static void main(String[] args) {FileOutputStream fos4 null; // 初始化文件对象为null全局初始化try {// 创建对象
// fos4 new FileOutputStream(Z:\\Ultimate JavaCode\\src\\test6\\fos4.txt); //文件不存在会抛出FileNotFoundException异常fos4 new FileOutputStream(C:\\Users\\ASUS\\Desktop\\project1\\src\\fos.txt);// 写入数据fos4.write(javaEE.getBytes());// 关闭资源fos4.close();// 若写入操作存在异常则直接跳到catch捕获不会执行关闭资源操作这时需要引入finally} catch (IOException e) { // 捕获异常e.printStackTrace(); //存在异常时追踪异常信息} finally { // 加入finally实现释放资源if(fos4!null){ // 文件不为null时才需要释放资源(防止文件为null时关闭资源出现空指针异常NullPointerException)try{fos4.close(); // 释放资源}catch (IOException e){e.printStackTrace();}}}}
}读数据 字节流读数据一次读一个字节数据
FileInputStream从文件系统中的文件获取输入字节
- FileInputStream(String name)通过打开与实际文件的连接来创建一个FileInputStream该文件由文件系统中的路径名name命名使用字节输入流读数据的步骤(创建对象--读数据--释放资源)
1、创建字节输入流对象做了3件事情
- 调用系统功能创建了文件
- 创建字节输出流对象
- 让字节输出流对象指向文件
2、调用字节输入流对象的读数据方法
3、释放资源关闭此文件输出流并释放与此流相关联的任何系统资源字节流读数据的3种方式read()方法重载–3个
int read()从输入流读入一个 8 字节的数据将它转换成一个 0~ 255 的整数返回一个整数如果遇到输入流的结尾返回 -1
int read(byte[] b)从输入流读取若干字节的数据保存到参数 b 指定的字节数组中返回的字节数表示读取的字节数如果遇到输入流的结尾返回 -1
int read(byte[] b,int off,int len)从输入流读取若干字节的数据保存到参数 b 指定的字节数组中其中 off 是指在数组中开始保存数据位置的起始下标len 是指读取字节的位数。返回的是实际读取的字节数如果遇到输入流的结尾则返回 -1案例1
import java.io.FileInputStream;
import java.io.IOException;public class FileInputStreamDemo1 {public static void main(String[] args) throws IOException {// 创建对象FileInputStream fisnew FileInputStream(C:\\Users\\ASUS\\Desktop\\project1\\src\\fos.txt);// 读数据
// int bys fis.read();
// System.out.println(bys); // 结果98(文件的字符是b)
// System.out.println((char)bys); // 大转小强制转换显示原字符(结果b)/*字节流读数据标准代码如下1.fis.read():读数据2.byfis.read():将读取的数据赋值给by3.by!-1:判断读取到的数据是否是-1到达文件末尾*/int by; // 类型声明while((byfis.read())!-1){System.out.print((char)by); // 强转显示原字符(结果bcd),注意用print而不是println}// 释放资源fis.close();}
}案例2字节流复制文本文件 需求把文本文件的内容从一个文件中读取出来数据源然后写入到另一个文件中目的地
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;public class FileInputStreamDemo2{public static void main(String[] args) throws IOException {// 创建对象FileInputStream fisnew FileInputStream(D:\\文本复制案例.txt); // 从指定路径下读取要复制的文本文件(数据源)FileOutputStream fosnew FileOutputStream(C:\\Users\\ASUS\\Desktop\\project1\\src\\fos.txt);//目的地// 先从数据源(fis)读取后写入目的地(fos)int by;while((byfis.read())!-1){ // 一次读取一个字节直到读完(到文件末尾)fos.write(by); // 一次写入一个字节}// 释放资源fos.close();fis.close(); // 先创建的后释放}
}案例3 需求字节流读数据(一次读一个字符数组)用到int read(byte[] b)构造方法
import java.io.FileInputStream;
import java.io.IOException;public class FileInputStreamDemo3 {public static void main(String[] args) throws IOException {// 创建对象FileInputStream fisnew FileInputStream(C:\\Users\\ASUS\\Desktop\\project1\\src\\fos.txt);byte[] bysnew byte[1024]; // 1024及其整数倍int len;// 读取数据while((lenfis.read(bys))!-1){ // 一次读一个字符数组用到int read(byte[] b)构造方法System.out.println(new String(bys,0,len)); // new String方法转换为字符串输出到控制台}// 释放资源fis.close();}
}字节缓冲流
BufferedOutputStream该类实现缓冲输出流。 通过设置这样的输出流应用程序可以将字节写入基础输出流而不必为写入的每个字节调用底层系统。
BufferedInputStream创建BufferedInputStream将创建一个内部缓冲区数组。当从流中读取或跳过字节时内部缓冲区将根据需要从所包含的输入流中重新填充一次很多字节。构造方法
字节缓冲输出流BufferedOutputStream(OutputStream out)
字节缓冲输入流BufferedInputStream(InputStream in)问题构造方法里需要的是字节流而不是具体的文件或路径
原因字节缓冲流仅仅提供缓冲区而真正的读写数据还得依靠基本的字节流对象进行操作。示例
import java.io.*;public class BufferStreamDemo1 {public static void main(String[] args) throws IOException {
// FileOutputStream fosnew FileOutputStream(C:\\Users\\ASUS\\Desktop\\project1\\src\\fos.txt);
// BufferedOutputStream bosnew BufferedOutputStream(fos);// 创建字节缓冲输出流对象BufferedOutputStream bosnew BufferedOutputStream(new FileOutputStream(C:\\Users\\ASUS\\Desktop\\project1\\src\\fos.txt));// 操作1写数据bos.write(hello\n.getBytes());bos.write(javaEE\n.getBytes());// 创建字节缓冲输入流对象用于读数据BufferedInputStream bisnew BufferedInputStream(new FileInputStream(C:\\Users\\ASUS\\Desktop\\project1\\src\\fos.txt));// 操作2读数据// 方法1一次读取一个字节数据
// int by;
// while((bybis.read())!-1){
// System.out.println((char)by);
// }// 方法2一次读取一个字节数组byte[] bysnew byte[1024]; // 1024及其整数倍int len;while((lenbis.read(bys))!-1){System.out.println(new String(bys,0,len)); // 转换为字符串输出到控制台}// 释放资源bos.close();}
}运行结果打开fos.txt文件显示如下
hello
javaEE