一、JavaIO流
1、File
File类是Java I/O库中用于操作文件和目录的类。它提供了一系列的方法来操作文件路径以及文件本身。
创建File对象: 可以通过以下方式来创建File对象:
- 使用文件路径字符串创建File对象:
File file = new File("C:/path/to/file.txt");
- 使用父路径和子路径字符串创建File对象:
File file = new File("C:/path/to", "file.txt");
- 使用父路径File对象和子路径字符串创建File对象:
File parent = new File("C:/path/to"); File file = new File(parent, "file.txt");
public void test1(){
//构造器1
File file1 = new File("hello.txt");//相对于当前module
File file2 = new File("E:\\Me\\src\\study1\\he.txt");
System.out.println(file1);
System.out.println(file2);
//构造器2:
File file3 = new File("D:\\workspace_idea1","JavaSenior");
System.out.println(file3);
//构造器3:
File file4 = new File(file3,"hi.txt");
System.out.println(file4);
}
常用方法: 以下是File类常用的方法:
- 文件和目录操作:
boolean exists()
: 判断文件是否存在。boolean isDirectory()
: 判断是否为目录。boolean isFile()
: 判断是否为文件。boolean mkdir()
: 创建目录。boolean mkdirs()
: 创建目录,包括创建中间目录。boolean delete()
: 删除文件或目录。boolean renameTo(File dest)
: 重命名文件或目录。
- 文件信息获取:
String getName()
: 获取文件名或目录名。String getParent()
: 获取父路径。String getPath()
: 获取文件或目录路径。long length()
: 获取文件的大小(字节数)。long lastModified()
: 获取文件最后修改时间。
- 目录遍历:
String[] list()
: 返回目录中的文件和子目录的名称数组。File[] listFiles()
: 返回目录中的文件和子目录的File对象数组。
- 文件操作:
boolean createNewFile()
: 创建新的空文件。boolean canRead()
: 判断文件是否可读。boolean canWrite()
: 判断文件是否可写。boolean setReadable(boolean readable)
: 设置文件是否可读。boolean setWritable(boolean writable)
: 设置文件是否可写。
- 文件路径操作:
File getAbsoluteFile()
: 返回文件的绝对路径的File对象。String getAbsolutePath()
: 返回文件的绝对路径的字符串。String getParentFile()
: 返回文件的父目录的路径。
需要注意的是,File类的方法在执行时,可能会涉及到文件系统的操作,因此需要注意处理可能抛出的IOException异常。
- 总结: File类是Java I/O库中用于操作文件和目录的类,提供了一系列的方法来操作文件路径和文件本身。它可以用于判断文件是否存在、创建和删除文件和目录、重命名文件、获取文件信息等操作。使用File类可以简单地操作文件,但是对于更高级的文件操作建议使用Java NIO库中的Path类。
2、Path
Path类是Java中表示文件或目录路径的类。它提供了一系列的方法来操作路径,如获取路径的根部分、父路径、文件名等。
创建Path对象的方式有两种:使用Path类的静态方法of()
,以及使用Paths
类的静态方法get()
。
Path path1 = Path.of("path/to/file.txt");
Path path2 = Paths.get("path", "to", "file.txt");
Path类的常用方法包括:
toString()
:将Path对象转换为字符串表示。toAbsolutePath()
:返回Path对象的绝对路径。getParent()
:返回Path对象的父路径。getFileName()
:返回Path对象的文件名。getRoot()
:返回Path对象的根部分。isAbsolute()
:判断Path对象是否为绝对路径。normalize()
:返回一个标准化的Path对象,去除冗余的路径分隔符和.
、..
等部分。resolve()
:将给定的路径追加到当前路径后面,返回一个新的Path对象。relativize()
:计算当前路径相对于给定的路径的相对路径。
Path类还提供了一些方法用于操作文件或目录,如创建文件、创建目录、复制、删除等。
Path file = Paths.get("path/to/file.txt");
// 创建文件
Files.createFile(file);
// 创建目录
Path dir = Paths.get("path/to/dir");
Files.createDirectory(dir);
// 复制文件或目录
Path dest = Paths.get("path/to/destination");
Files.copy(file, dest);
// 删除文件或目录
Files.delete(file);
Files.delete(dir);
Path类在Java NIO中被广泛使用,它提供了一种更灵活、更高效的文件操作方式。它可以与File类互相转换,使得在使用新IO和传统IO之间切换变得更加容易。
3、IO流
1、IO流介绍
Java IO流指的是Java中用于读取和写入数据的机制。它提供了一组类和接口,用于在程序和外部数据源(如文件、网络、内存等)之间传输数据。
- 输入input:读取外部数据(磁盘、光盘等存储设备的数据)到程序(内存)中。
- 输出output:将程序(内存)数据输出到磁盘、光盘等存储设备中。
2、流
- 输入流
Java中的输入流(Input Stream)用于从数据源(例如文件、网络连接等)读取数据。Java提供了几种不同类型的输入流类,其中最常用的是FileInputStream和BufferedInputStream。
1、FileInputStream用于从文件中读取数据。它的构造函数接受文件名作为参数,并可以通过read()方法逐字节读取数据。
2、BufferedInputStream是对FileInputStream的包装,通过缓冲区提高了读取的效率。它的构造函数接受一个InputStream对象作为参数,并提供了read()方法以字节数组为单位读取数据。
除了FileInputStream和BufferedInputStream,Java还提供了其他输入流类,例如ByteArrayInputStream、PipedInputStream等,用于处理不同类型的输入源。
以下是使用FileInputStream读取文件内容的示例代码:
import java.io.FileInputStream;
import java.io.IOException;
public class InputStreamExample {
public static void main(String[] args) {
try {
FileInputStream fis = new FileInputStream("input.txt");
int data;
while ((data = fis.read()) != -1) {
System.out.print((char) data);
}
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
在上面的示例代码中,我们创建了一个FileInputStream对象来读取名为"input.txt"的文件。然后,我们使用read()方法读取文件中的每一个字节,并将其转换为字符输出到控制台。最后,我们通过调用close()方法关闭输入流。
请注意,IO操作可能会抛出IOException异常,因此我们需要在try-catch块中处理它们。
- 输出流
Java中的输出流(Output Stream)用于将数据写入目标位置,如文件、网络连接等。在Java IO中,有很多输出流类可供选择,每个类都有自己特定的用途和功能。下面是一些常用的输出流类:
-
FileOutputStream:用于写入文件的输出流。通过构造函数指定文件路径,并使用write()方法将数据写入文件。它还提供了一些其他的方法,如flush()用于刷新缓冲区,close()用于关闭流。示例代码见上面的回答。
-
BufferedOutputStream:通过缓冲区提高输出效率的输出流。它可以包装其他的输出流对象,如FileOutputStream。BufferedOutputStream有一个内部缓冲区,可以一次写入多个字节,而不是每个字节都进行独立的写入操作。同样地,它也提供了flush()和close()方法。
以下是使用BufferedOutputStream将数据写入文件的示例代码:
import java.io.BufferedOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;
public class BufferedOutputStreamExample {
public static void main(String[] args) {
try {
FileOutputStream fos = new FileOutputStream("output.txt");
BufferedOutputStream bos = new BufferedOutputStream(fos);
String data = "Hello, world!";
bos.write(data.getBytes());
bos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
在上面的示例代码中,我们先创建了一个FileOutputStream对象,然后再创建一个BufferedOutputStream对象,将FileOutputStream对象作为参数传递给BufferedOutputStream的构造函数。接着,我们使用write()方法将字符串转换为字节数组,并通过BufferedOutputStream将其写入文件中。最后,我们调用close()方法关闭输出流。
- 节点流
节点流(Node Stream)又叫做原始流,是Java IO中最基本的流类型,直接与数据源或目标进行交互。Java中提供了几种节点流,用于与不同类型的数据源或目标进行读写操作。
以下是一些常用的节点流:
- FileInputStream:用于从文件中读取数据。它继承自InputStream类,可以按字节方式读取数据。
import java.io.FileInputStream;
import java.io.IOException;
public class FileInputStreamExample {
public static void main(String[] args) {
try {
FileInputStream fis = new FileInputStream("input.txt");
int data;
while ((data = fis.read()) != -1) {
System.out.print((char) data);
}
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
在上面的示例代码中,我们通过创建一个FileInputStream对象来打开文件,并使用read()方法逐字节读取文件中的内容。当读取到文件末尾时,read()方法返回-1。
- FileOutputStream:用于向文件中写入数据。它继承自OutputStream类,可以按字节方式写入数据。
import java.io.FileOutputStream;
import java.io.IOException;
public class FileOutputStreamExample {
public static void main(String[] args) {
try {
FileOutputStream fos = new FileOutputStream("output.txt");
String data = "Hello, world!";
fos.write(data.getBytes());
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
在上面的示例代码中,我们通过创建一个FileOutputStream对象来创建或覆盖输出文件,并使用write()方法将字符串转换为字节数组后写入文件中。
- FileReader:用于从文件中读取字符数据。它继承自Reader类,可以按字符方式读取数据。
import java.io.FileReader;
import java.io.IOException;
public class FileReaderExample {
public static void main(String[] args) {
try {
FileReader reader = new FileReader("input.txt");
int data;
while ((data = reader.read()) != -1) {
System.out.print((char) data);
}
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
在上面的示例代码中,我们通过创建一个FileReader对象来打开文件,并使用read()方法逐字符地读取文件中的内容。
- FileWriter:用于向文件中写入字符数据。它继承自Writer类,可以按字符方式写入数据。
import java.io.FileWriter;
import java.io.IOException;
public class FileWriterExample {
public static void main(String[] args) {
try {
FileWriter writer = new FileWriter("output.txt");
String data = "Hello, world!";
writer.write(data);
writer.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
在上面的示例代码中,我们通过创建一个FileWriter对象来创建或覆盖输出文件,并使用write()方法将字符串写入文件中。
节点流直接与数据源或目标进行交互,对于小型数据和文本文件的读写操作非常方便。但对于大型数据或二进制文件,建议使用缓冲流或其他高级流来提高性能。
- 缓冲流
- 为了提高数据读写的速度,Java API提供了带缓冲功能的流类,在使用这些流类时,会创建一个内部缓冲区数组,缺省使用8192个字节(8Kb)的缓冲区。
- 缓冲流要“套接”在相应的节点流之上,根据数据操作单位可以把缓冲流分为:
- BufferedInputStream 和 BufferedOutputStream
- BufferedReader 和 BufferedWriter
- 当读取数据时,数据按块读入缓冲区,其后的读操作则直接访问缓冲区
- 当使用BufferedInputStream读取字节文件时,BufferedInputStream会一次性从文件中读取8192个(8Kb),存在缓冲区中,直到缓冲区装满了,才重新从文件中读取下一个8192个字节数组。
- 向流中写入字节时,不会直接写到文件,先写到缓冲区中直到缓冲区写满,BufferedOutputStream才会把缓冲区中的数据一次性写到文件里。使用方法flush()可以强制将缓冲区的内容全部写入输出流
- 关闭流的顺序和打开流的顺序相反。只要关闭最外层流即可,关闭最外层流也会相应关闭内层节点流
- flush()方法的使用:手动将buffer中内容写入文件
- 如果是带缓冲区的流对象的close()方法,不但会关闭流,还会在关闭流之前刷新缓冲区,关闭后不能再写出
- 关闭外层流的同时,内层流也会自动的进行关闭。关于内层流的关闭,我们可以省略.
@Test
public void BufferedStreamTest() throws FileNotFoundException {
BufferedInputStream bis = null;
BufferedOutputStream bos = null;
try {
//1.造文件
File srcFile = new File("爱情与友情.jpg");
File destFile = new File("爱情与友情3.jpg");
//2.造流
//2.1 造节点流
FileInputStream fis = new FileInputStream((srcFile));
FileOutputStream fos = new FileOutputStream(destFile);
//2.2 造缓冲流
bis = new BufferedInputStream(fis);
bos = new BufferedOutputStream(fos);
//3.复制的细节:读取、写入
byte[] buffer = new byte[10];
int len;
while((len = bis.read(buffer)) != -1){
bos.write(buffer,0,len);
// bos.flush();//刷新缓冲区
}
} catch (IOException e) {
e.printStackTrace();
} finally {
//4.资源关闭
//要求:先关闭外层的流,再关闭内层的流
if(bos != null){
try {
bos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(bis != null){
try {
bis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
//说明:关闭外层流的同时,内层流也会自动的进行关闭。关于内层流的关闭,我们可以省略.
// fos.close();
// fis.close();
}
}
- 转换流
转换流(转换器流)是Java IO中的一种高级流,用于在字节流和字符流之间进行转换。它主要由InputStreamReader和OutputStreamWriter两个类实现,能够提供字节流到字符流的转换和字符流到字节流的转换。
- InputStreamReader:将字节流转换为字符流。它是Reader的子类,可以读取字节流并将其解码为字符流。
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
public class InputStreamReaderExample {
public static void main(String[] args) {
try {
FileInputStream fis = new FileInputStream("input.txt");
InputStreamReader reader = new InputStreamReader(fis);
int data;
while ((data = reader.read()) != -1) {
System.out.print((char) data);
}
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
在上面的示例代码中,我们通过创建一个FileInputStream对象来打开文件,并将其传递给InputStreamReader构造函数。然后,我们使用reader对象的read()方法逐字符地读取文件中的内容。
- OutputStreamWriter:将字符流转换为字节流。它是Writer的子类,可以将字符流编码为字节流。
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
public class OutputStreamWriterExample {
public static void main(String[] args) {
try {
FileOutputStream fos = new FileOutputStream("output.txt");
OutputStreamWriter writer = new OutputStreamWriter(fos);
String data = "Hello, world!";
writer.write(data);
writer.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
在上面的示例代码中,我们通过创建一个FileOutputStream对象来创建或覆盖输出文件,并将其传递给OutputStreamWriter构造函数。然后,我们使用writer对象的write()方法将字符串写入文件中。
转换流是非常有用的工具,常用于处理带有不同字符编码的数据流。它们可以将不同编码的字节流转换为统一的字符流,使得读写操作更加方便和灵活。