I/O流
流:
流的概念:
“流”可以看作是一个流动的数据缓冲区,数据从数据源流向数据目的地。
java中流可以看做是数据在文件或程序之间的传递。
流的两种基本形式:
输入流和输出流
1、通过输入流,程序可以从数据文件读取数据;
2、通过输出流,程序可以向数据文件中写入数据。
根据传输的数据单位,将流分为两类:
字节流:
从InputStream和OutputStream派生出来的一系列类,以字节(byte)为基本处理单位。
字符流:
从Reader和Writer派生出的一系列类,以16位的Unicode码表示的字符为基本处理单位。
文件流:
要对本机文件系统上的文件进行读写,需要使用文件流。Java的文件流类包括字符流的FileReader、FileWriter和字节流的FileInputStream、FileOutputStream。
文件与目录的描述类——File:
File类用来描述文件对象的属性,既可以表示文件,也可以表示目录。使用它提供的方法,我们可以得到所指对象的描述信息,包括名称、存在否、读/写权限、路径等等。
File类的一些方法的详解:
1、getAbsolutePath()、getPath()、getCanonicalPath()三个方法的区别:
import java.io.File;
import java.io.IOException;
public class FileTest {
public static void main(String[] args) throws IOException {
File file = new File("..//大话设计/src/设计/test.txt");
System.out.println(file.exists());
if(file.exists()){
//输出处理前绝对路径
System.out.println(file.getAbsolutePath());
//输出文件定义时的路径
System.out.println(file.getPath());
//输出处理后的绝对路径
System.out.println(file.getCanonicalPath());
}else{
System.out.println("该文件不存在或路径不正确!");
}
File file1 = new File("D://java/test5.txt");
System.out.println(file1.exists());
if(file1.exists()){
System.out.println(file.getAbsolutePath());//输出绝对路径
}else{
System.out.println("该文件不存在或路径不正确!");
}
}
}
运行结果:
从运行结果中可以看出:使用三个函数输出的路径并不一样。
首先file.getAbsolutePath()方法输出的是未经过处理的文件的绝对路径,如输出的第一条结果,文件定义的路径中的..还存在(使用..表示该文件在当前目录下);
接着file.getPath()方法输出的是文件定义时的路径
File file = new File(“..//大话设计/src/设计/test.txt”);路径:..//大话设计/src/设计/test.txt;
最后file.getCanonicalPath()方法输出的路径才是文件的正确的绝对路径。
2、getName()、String getParent( )、String renameTo(File newName)、boolean exists( )
import java.io.File;
public class FileTest1 {
public static void main(String[] args) {
File file = new File("D://java/test.txt");
//返回文件名称
System.out.println(file.getName());
//返回文件上一级路径
System.out.println(file.getParent());
//将当前文件名更名为给定文件的完整路径
File file1 = new File("D://java/testRename.txt");
System.out.println(file.renameTo(file1));
System.out.println(file.exists());
System.out.println(file1.exists());
}
}
运行前:先查看该目录下的文件:
运行结果:
第一行:test.txt 为getName()输出的文件的名称;
第二行:D:\java 为getParent()方法返回的文件的上一级目录;
第三行:true 为renameTo()方法,将名字修改成功,返回true;
第四行:false 为使用file.exists()查看file文件在所定义的目录中是否存在,名字已被修改,不存在。
第五行:true 为使用file1.exists()查看file1文件是否存在,结果为存在。
然后查看目录中是否真的修改成功:
3、file.exists()、file.canRead()、file.canWrite()、file.length()
import java.io.File;
public class FileTest2 {
public static void main(String[] args) {
File file = new File("D://java/testRename.txt");
//文件在目录中是否存在
System.out.println(file.exists());//true
//文件是否可读
System.out.println(file.canRead());//true
//文件是否可写
System.out.println(file.canWrite());//true
//文件中内容的长度
System.out.println(file.length());//33
}
}
运行结果:
true
true
true
33
练习
1、将一个字符串,保存到指定的文件中。
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
public class BufferedReaderWriter {
//在文件原有的基础上添加定义的字符串
public static void main(String[] args) throws IOException {
String str = "qqwweerrtt";//添加的字符串
File file = new File("D://java/test1.txt");
if(!file.exists()){
System.out.println("指定文件不存在!创建文件。");
file.createNewFile();
}else{
System.out.println("指定文件存在!");
}
String s1 = new String();
BufferedReader input = new BufferedReader(new FileReader(file));
while ((s1 = input.readLine()) != null) {
System.out.println(s1);
str = s1 + str + "\n";
}
System.out.println(str);
input.close();
BufferedWriter output = new BufferedWriter(new FileWriter(file));
output.write(str);
output.close();
}
}
文件中原来的内容:
程序运行结果:
我们再来看一下文件中的内容:
可以看出,文件中原来有两行内容,在程序运行后,第二行的内容跑到了前面,而第一行的内容跑到了后面,并且所有内容之间没有换行,这是因为:
while ((s1 = input.readLine()) != null) {
System.out.println(s1);
str = s1 + str + "\n";
}
在上面的循环语句中:打印出第一行内容后,在第一行内容后加上需要添加或保存的字符串str,str = s1 + str + “\n”;此时要添加的内容为语句str = s1 + str + “\n”执行后的str;循环,输出第二行内容,第二行内容在与执行后的str进行字符串拼接,以此类推,故得到了最后保存后的结果。
若把上面循环语句 str = s1 + str + “\n”;改写成 str += s1 + “\n”;则运行结果如下:
这样运行结果,只是在第一行前面添加要保存的字符串,而其他的内容则和文件中原来的内容一样,且有换行。
2、读取文件中的信息并输出到控制台
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
public class ReadFile {
public static void main(String[] args) throws IOException {
//创建对象
FileReader fr = new FileReader("..//大话设计/src/设计/test.txt");
//对文件实现按行读取,达到一行一行输出的目的
BufferedReader br = new BufferedReader(fr);
//读取一行文本
String line = br.readLine();
//如果读取的某一行文本为空,则结束循环
while(line!=null){
System.out.println(line);
line = br.readLine();
}
br.close();
}
}
运行结果:
3、文件的复制
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
public class ByteInputStream {
@SuppressWarnings("resource")
public static void main(String[] args) {
try{
//文件输入流
FileInputStream fileInputStream = new FileInputStream("D://java/test1.txt");
int size = fileInputStream.available();
System.out.println(size);
byte[] b = new byte[size];
//一次性读取一个字节数组的数据
int read = fileInputStream.read(b);
File file = new File("D://java/test2.txt");
if(!file.exists())
file.createNewFile();
//文件输出流
FileOutputStream fileOutputStream = new FileOutputStream(file);
while(read!=-1){
//一次性写入一个字节数组的数据;在指定 byte数组中从偏移量 off 开始的 len 个字节写入此文件输出流。
fileOutputStream.write(b, 0, size);
read = fileInputStream.read(b);
}
fileOutputStream.flush();
fileOutputStream.close();
}catch(Exception e){
}
}
}
test1中的内容:
原目录中的文件:没有test2文件
执行程序后目录中的文件:
test2中的内容:
总结:今天的学习并不深刻,只学习了极少的一部分。关于i/o流这块,还有很多类的很多方法没有进行学习,希望之后可以深刻学习i/o流泪的其它相关类及其方法。