File操作
文件的创建、立即删除、程序结束后删除、重命名:
import java.io.File;
import java.io.IOException;
public class TextDemo {
public static void main(String[] args) {
File newFile = new File("my_new_file.txt");
printFileDetails(newFile);
//Create a new file
try{
newFile.createNewFile();
System.out.println(newFile + " is created!");
}
catch (IOException e){
e.printStackTrace();
System.out.println(newFile + " could not be crated.");
}
printFileDetails(newFile);
//Delete the new file
newFile.delete();
System.out.println("After deleting the new file:");
printFileDetails(newFile);
// recreate the file
try {
newFile.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
printFileDetails(newFile);
// Let's tell the JVM to delete this file on exit
newFile.deleteOnExit();
System.out.println("After using deleteOnExit() method:");
printFileDetails(newFile);
// Create a new file and rename it
File firstFile = new File("my_first_file.txt");
File secoundFile = new File("my_secound_file.txt");
try{
boolean fileCreated = firstFile.createNewFile();
if (fileCreated || firstFile.exists()){
printFileDetails(firstFile);
printFileDetails(secoundFile);
boolean renamedFlag = firstFile.renameTo(secoundFile);
if (!renamedFlag){
System.out.println("Could not rename " + firstFile);
}
printFileDetails(firstFile);
printFileDetails(secoundFile);
}
}
catch (IOException e){
e.printStackTrace();
}
}
public static void printFileDetails(File f){
System.out.println("Absolute Path: " + f.getAbsoluteFile());
System.out.println("File exists: " + f.exists());
}
}
===================== =========================================
输入流
从文件输入流一次读取一个字节:
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
public class TextDemo {
public static void main(String[] args) {
String dataSourceFile = "asdf.txt";
try (FileInputStream fin = new FileInputStream(dataSourceFile)){
byte byteData;
//循环输出文件输入流中的内容,一次输出一个字符
while ((byteData = (byte) fin.read()) != -1) {
System.out.println((char) byteData);
}
} catch (FileNotFoundException e){
e.printStackTrace();
} catch (IOException e){
e.printStackTrace();
}
}
}
=====================================================
BufferedInputStream
通过缓冲数据向输入流添加功能。
它维护一个内部缓冲区以存储从底层输入流读取的字节。
我们创建缓冲区输入流如下:
String srcFile =“test.txt";BufferedInputStream bis = new BufferedInputStream(new FileInputStream(srcFile));
以下代码显示如何使用BufferedInputStream从文件读取。
============================================================
PushbackInputStream
向输入流添加功能,允许我们使用其unread()方法推回读取的字节。
有三个版本的unread()方法。一个让我们推回一个字节,另外两个让我们推回多个字节。
=============================================================
DataInputStream
可以从输入流中读取Java基本数据类型值。
DataInputStream类包含读取数据类型值的读取方法。例如,要读取int值,它包含一个readInt()方法;读取char值,它有一个readChar()方法等。它还支持使用readUTF()方法读取字符串。
import java.io.DataInputStream;
import java.io.FileInputStream;
public class Main {
public static void main(String[] args) {
String srcFile = "primitives.dat";
try (DataInputStream dis = new DataInputStream(new FileInputStream(srcFile))) {
// Read the data in the same order they were written
int intValue = dis.readInt();
double doubleValue = dis.readDouble();
boolean booleanValue = dis.readBoolean();
String msg = dis.readUTF();
System.out.println(intValue);
System.out.println(doubleValue);
System.out.println(booleanValue);
System.out.println(msg);
} catch (Exception e) {
e.printStackTrace();
}
}
}
输出流
在抽象超类OutputStream中定义了三个重要的方法:write(),flush()和close()。
write()方法将字节写入输出流。
它有三个版本,允许我们一次写一个字节或多个字节。
flush()方法用于将任何缓冲的字节刷新到数据宿。
close()方法关闭输出流。
文件输出流
import java.io.File;
import java.io.FileOutputStream;
public class Main {
public static void main(String[] args) {
String destFile = "luci2.txt";
// Get the line separator for the current platform
String lineSeparator = System.getProperty("line.separator");
String line1 = "test";
String line2 = "test1";
String line3 = "test2";
String line4 = "test3";
try (FileOutputStream fos = new FileOutputStream(destFile)) {
fos.write(line1.getBytes());
fos.write(lineSeparator.getBytes());
fos.write(line2.getBytes());
fos.write(lineSeparator.getBytes());
fos.write(line3.getBytes());
fos.write(lineSeparator.getBytes());
fos.write(line4.getBytes());
// Flush the written bytes to the file
fos.flush();
System.out.println("Text has been written to "
+ (new File(destFile)).getAbsolutePath());
} catch (Exception e2) {
e2.printStackTrace();
}
}
}
DataOutputStream
可以将Java基本数据类型值写入输出流。
DataOutputStream类包含一个写入数据类型的写入方法。它支持使用writeUTF(String text)方法将字符串写入输出流。
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileOutputStream;
public class Main {
public static void main(String[] args) {
String destFile = "primitives.dat";
try (DataOutputStream dos = new DataOutputStream(new FileOutputStream(
destFile))) {
dos.writeInt(765);
dos.writeDouble(6789.50);
dos.writeBoolean(true);
dos.writeUTF("Java Input/Output is cool!");
dos.flush();
System.out.println("Data has been written to "
+ (new File(destFile)).getAbsolutePath());
} catch (Exception e) {
e.printStackTrace();
}
}
}
管道连接输入流和输出流
管道 I/O基于生产者 - 消费者模式,其中生产者产生数据并且消费者消费数据。
在管道 I/O中,我们创建两个流代表管道的两端。 PipedOutputStream对象表示一端,PipedInputStream对象表示另一端。我们使用两个对象上的connect()方法连接两端。
管道流具有固定容量的缓冲器,以在写入管道和从管道读取之间存储数据。
我们可以设置管道容量,当我们创建它。如果管道的缓冲区已满,则尝试在管道上写入将被阻止。
管道用于将数据从一个线程传输到另一个线程。两个线程之间的同步由阻塞读和写来处理。
import java.io.IOException;
import java.io.PipedInputStream;
import java.io.PipedOutputStream;
public class TextDemo {
public static void main(String[] args) {
// 实例输入和输出管道
PipedInputStream pis = new PipedInputStream();
PipedOutputStream pos = new PipedOutputStream();
// 连接管道,并处理抛出异常
try {
pos.connect(pis);
} catch (IOException e) {
e.printStackTrace();
}
// 应用lambda表达式,先实例化一个Runnable接口,在覆写run()方法中实现调用对应的静态方法
Runnable producer = () -> produceData(pos);
Runnable consumer = () -> consumeData(pis);
// 实例化线程并开始运行
new Thread(producer).start();
new Thread(consumer).start();
}
// 向输出流写入数据方法,线程延迟500毫秒
public static void produceData(PipedOutputStream pos){
try{
for(int i = 1; i <= 50; i++){
pos.write((byte) i);
pos.flush();
System.out.println("Writing: " + i);
Thread.sleep(500);
}
pos.close();
} catch(Exception e){
e.printStackTrace();
}
}
// 读取输入流数据方法
public static void consumeData(PipedInputStream pis){
try{
int num = -1;
while((num = pis.read()) != -1){
System.out.println("Reading: " + num);
}
pis.close();
} catch (Exception e){
e.printStackTrace();
}
}
}
对象序列化
ObjectOutputStream类的一个对象用于序列化一个对象。
ObjectInputStream类的一个对象用于反序列化一个对象。
ObjectOutputStream继承自OutputStream。 ObjectInputStream继承自InputStream。
类必须实现Serializable或Externalizable接口以便序列化或反序列化。
Serializable接口是一个标记接口。
Java负责处理从/向流读取/写入Serializable对象的细节。我们只需要将对象写入/读取流到流类中的一个方法。
实现Externalizable接口使我们能够更好地控制从流中读取和写入对象。