Java语法学习IO流
大纲
- 文件
- IO流
具体案例
1. 文件
基本介绍
创建文件
第一种:
public static void main(String[] args) {
String filePathName = "d:\\news1.txt";
File file = new File(filePathName);
try {
file.createNewFile();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
第二种:
相当于把第一种分开写
public static void main(String[] args) {
File parentfile = new File("d:\\");
String fileName = "news2.txt";
File file = new File(parentfile,fileName);
try {
file.createNewFile();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
第三种:
与第二种差不多
public static void main(String[] args) {
String parentName = "d:\\";
String fileName = "news3.txt";
File file = new File(parentName, fileName);
try {
file.createNewFile();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
获取文件相关信息
System.out.println(file.getName());
//得到文件名字
System.out.println(file.getAbsolutePath());
//得到文件的绝对路径
System.out.println(file.getParent());
//得到父文件的名字
System.out.println(file.length());
//得到文件的字节大小
file.exists();
//判断文件是否存在
file.isFile();
//判断是不是一个文件
file.isDirectory();
//判断是不是一个目录
常用文件操作
2. IO流
IO流原理及其分类
原理:
分类:
字节流一般应用操作二进制文件,字符流操作文本文件
字节流
InputStream
FileInputStream
创建对象读取,使用read()
public static void readFile() {
String filePath = "d:\\hello.txt";
FileInputStream fileInputStream = null;
int content = 0;
try {
fileInputStream = new FileInputStream(filePath);
while ((content = fileInputStream.read()) != -1){
System.out.print((char) content);
}
} catch (IOException e) {
throw new RuntimeException(e);
}finally {
try {
fileInputStream.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
}
使用read(byte [ ]),返回读取到的字节的个数
再转换为字符串
public static void readFile() {
String filePath = "d:\\hello.txt";
FileInputStream fileInputStream = null;
byte[] bytes = new byte[5];
//创建一个字节的数组
int readLength = 0;
//设置读取到的字节长度
try {
fileInputStream = new FileInputStream(filePath);
while ((readLength = fileInputStream.read(bytes) )!= -1){
//把读取到的字节个数存入readLength
System.out.print(new String(bytes,0,readLength));
//把字节转换为字符串,新建字符串,传入数组,和起始位置与长度
}
} catch (IOException e) {
throw new RuntimeException(e);
}finally {
try {
fileInputStream.close();
//关闭字节流,节省资源
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
}
BufferedInputStream
注意体现在包装上 ,具体方法查询API
创建方式,传入一个InputStream对象即可
BufferedInputStream bufferedInputStream = new BufferedInputStream(new FileInputStream(srcPath));
OutputStream
FileOutputStream
覆盖文本原来的内容,使用的如下构造器
fileOutputStream = new FileOutputStream(fileName);
如果想要把我们写的内容加到原来文本的末尾,这需要这种构造器
fileOutputStream = new FileOutputStream(fileName,true);
方法:
创建对象,使用write方法,如果这个路径没有这个文件,那么会自己先创建再添加
public static void writeFile(){
String fileName = "d:\\hello.txt";
FileOutputStream fileOutputStream = null;
try {
fileOutputStream = new FileOutputStream(fileName);
fileOutputStream.write('H');
} catch (IOException e) {
throw new RuntimeException(e);
}finally {
try {
fileOutputStream.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
}
使用write(byte [ ])方法,把一个字符串转换为字节数组(可以利用String的getBytes)
public static void writeFile(){
String fileName = "d:\\hello.txt";
FileOutputStream fileOutputStream = null;
try {
fileOutputStream = new FileOutputStream(fileName);
String str = "hello,world";
fileOutputStream.write(str.getBytes());
} catch (IOException e) {
throw new RuntimeException(e);
}finally {
try {
fileOutputStream.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
}
使用write(byte [ ] ,int off, int len)方法,传入一字节数组,指定开始的位置和长度
fileOutputStream.write(str.getBytes(),2,5);
BufferedOutputStream
注意体现在包装上 ,具体方法查询API
创建方式,传入一个OutputStream对象即可
BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(new FileOutputStream(destPath));
文件拷贝
注意:
1.是一边读,一边写
2.注意使用 字节数组要考虑读取到字节的长度
采用节点流的方式
public static void fileCopy(){
String srcName = "D:\\java学习\\蛋糕.jpg";
String destName = "D:\\java学习\\av.jpg";
FileInputStream fileInputStream = null;
FileOutputStream fileOutputStream = null;
int readLength = 0;
//存储读取字节数组的字节的多少
byte[] bytes = new byte[1024];
try {
fileInputStream = new FileInputStream(srcName);
fileOutputStream = new FileOutputStream(destName);
while ((readLength = fileInputStream.read(bytes)) != -1){
//把读取到的字节个数返回readLength,并把读到的字节存入字节数组
fileOutputStream.write(bytes,0,readLength);
//把字节数组里面读到的内容写入目的文件,注意这里的是读取到字节的个数,而不是数字的长度
}
System.out.println("读取结束");
} catch (IOException e) {
throw new RuntimeException(e);
}finally {
//判断输入流,与输出流是否为空,并关闭
try {
if (fileInputStream != null){
fileInputStream.close();
}
if (fileOutputStream != null){
fileOutputStream.close();
}
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
}
采用包装流动方式
public static void fileCopy() throws FileNotFoundException {
String srcPath = "D:\\java学习\\蛋糕.jpg";
String destPath = "D:\\java学习\\蛋糕2.jpg";
BufferedInputStream bufferedInputStream = null;
BufferedOutputStream bufferedOutputStream = null;
try {
int readLength = 0;
byte[] bytes = new byte[1024];
bufferedInputStream = new BufferedInputStream(new FileInputStream(srcPath));
bufferedOutputStream = new BufferedOutputStream(new FileOutputStream(destPath));
while ((readLength = bufferedInputStream.read(bytes)) != -1){
bufferedOutputStream.write(bytes,0,readLength);
}
} catch (Exception e) {
throw new RuntimeException(e);
} finally {
try {
if (bufferedInputStream != null){
bufferedInputStream.close();
}
if (bufferedOutputStream != null){
bufferedOutputStream.close();
}
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
字符流
Reader
FileReader
与前面的FileInputStream使用方法相似
通过read方法
public static void main(String[] args) throws IOException {
String fileName = "d:\\hello.txt";
FileReader fileReader = null;
int date;
fileReader = new FileReader(fileName);
try {
while ((date = fileReader.read()) != -1) {
System.out.print((char) date);
}
} catch (IOException e) {
throw new RuntimeException(e);
} finally {
fileReader.close();
}
}
通过字符数组,和read方法
public static void main(String[] args) throws IOException {
String fileName = "d:\\hello.txt";
FileReader fileReader = null;
int charLength;
char[] chars = new char[3];
fileReader = new FileReader(fileName);
try {
while ((charLength = fileReader.read(chars)) != -1){
System.out.print(new String(chars,0,charLength));
}
} catch (IOException e) {
throw new RuntimeException(e);
} finally {
fileReader.close();
}
}
}
BufferedReader
具体见下面处理流
Writer
FileWriter
应用方式与前文的FileOutputStream差不多
覆盖文本原来的内容,使用的如下构造器
fileWriter = new FileWriter(fileName);
如果想要把我们写的内容加到原来文本的末尾,这需要这种构造器
fileWriter = new FileWriter(fileName,true);
下面是常见的写入的方法
write()
write(char [ ])
write(char [ ],int off, int len)
write(String)
write(String, int off, int len)
fileWriter.write('H');
fileWriter.write(chars);
fileWriter.write(chars,1,3);
fileWriter.write(str);
fileWriter.write(str,6,4);
fileWriter.write("只不过是些许风霜罢了".toCharArray(),6,4);
注意:写完之后要close或者flush该字符流,否则写不进去
BufferedWriter
具体见下面处理流
节点流和处理流
节点流:
是针对某一特殊的数据类型进行操作的,更为底层
处理流(包装流):
功能更加强大,把节点流封装进了包装流
BufferedReader
把所需要的节点流创建并传入包装流的构造器实现包装
String fileName = "d:\\hello.txt";
BufferedReader bufferedReader = new BufferedReader(new FileReader(fileName));
String line;
while ((line = bufferedReader.readLine()) != null ){
System.out.println(line);
}
bufferedReader.close();
BufferedWriter
对于是覆盖还是追加,是在传入字节流的时候创建的
String fileName = "d:\\hello.txt";
BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter(fileName, true));
bufferedWriter.write("天下真是英杰无数");
bufferedWriter.newLine();
//这个语句相当于换行
bufferedWriter.close();
对象流
序列化: 能够保证不仅保存了数据的值,还保存了其数据类型,这种我们称为序列化
**反序列化:**把我们保存的数据恢复他的数据类型和值
如果想要一个类可以实现序列化,就需要实现Serializable 或 Externalizable接口.
Serializable:这是一个标记接口,没有方法
Externalizable:这里面有方法,需要实现
对于第四点:
序列号对象时,static,transient修饰的成员不进行 序列化,反序列化后也得不到
对于第六点:
如果一个类实现了序列化的接口,而其里面又有其它类的对象,那么要求其它类也实现序列化的接口
ObjectOutputStream
在进行写入的时候,需要不同的write数据类型方法,写入不同的数据
public static void file() throws IOException {
String filePath = "d:\\hello";
ObjectOutputStream objectOutputStream = new ObjectOutputStream(new FileOutputStream(filePath));
objectOutputStream.write(100);
objectOutputStream.writeBoolean(true);
objectOutputStream.writeChar('a');
objectOutputStream.writeDouble(2.2);
objectOutputStream.writeLong(12);
objectOutputStream.writeUTF("字符串");
objectOutputStream.writeObject(new dog());
objectOutputStream.close();
}
class dog implements Serializable{
}
ObjectInputStream
在读取的时候要对应的顺序读取,并且应该注意访问的权限,而且在进行序列化时,在哪个包哪个位置都有具体储存,所以如果有某个类的话,我们不能在其它地方新建一个一模一样的类,来读取
public static void readFile() throws IOException, ClassNotFoundException {
String filePath = "d:\\hello.txt";
ObjectInputStream objectInputStream = new ObjectInputStream(new FileInputStream(filePath));
System.out.println(objectInputStream.readInt());
System.out.println(objectInputStream.readBoolean());
System.out.println(objectInputStream.readChar());
System.out.println(objectInputStream.readDouble());
System.out.println(objectInputStream.readLong());
System.out.println(objectInputStream.readUTF());
System.out.println(objectInputStream.readObject());
objectInputStream.close();
}
标准输入输出流
转换流
因为我们在用字符流读取信息时不能设置读取到的编码格式,而使用字节流可以指定,于是我们可以在字节流指定编码后,转换成字符流
因为字符流的处理效率更高,所以先把字节流通过转换流转换,再用包装流接收
混在一起写
String fileName = "d:\\hello.txt";
BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(fileName), "gbk"));
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(fileName), "gbk"));
分开写
String fileName = "d:\\hello.txt";
InputStreamReader inread = new InputStreamReader(new FileInputStream(fileName),"gbk");
BufferedReader br = new BufferedReader(inread);
OutputStreamWriter outwrite = new OutputStreamWriter(new FileOutputStream(fileName), "gbk");
BufferedWriter bw = new BufferedWriter(outwrite);
以上两种等价
打印流
只有输出流
PrintStream
打印字节流
public static void main(String[] args) throws IOException, ClassNotFoundException {
PrintStream out = System.out;
out.print("ad");
out.write("as".getBytes());
//也能正常调用字节流的方法
System.setOut(new PrintStream("d:\\hello.txt"));
//设置打印输出的地方
}
PrintWriter
public static void main(String[] args) throws IOException, ClassNotFoundException {
String fileName = "d:\\hello.txt";
PrintWriter out = new PrintWriter(new FileOutputStream(fileName));
out.print("ad");
out.write("ss");
}