Java_I/O流
Posted 小企鹅推雪球!
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java_I/O流相关的知识,希望对你有一定的参考价值。
文章目录
Java_文件(File)
java.io.File类
:文件和文件目录路径的抽象表示形式,与平台无关File对象 能新建、删除、重命名文件和目录,但 File 不能访问文件内容本身
。如果需要访问文件内容本身,则需要使用输入/输出流。- 想要在Java程序中表示一个真实存在的文件或目录,那么必须有一个File对象,但是Java程序中的一个File对象,可能没有一个真实存在的文件或目录。
File对象
可以作为参数传递给流的构造器
Java_创建文件
public File(String pathname)
表示以pathname
为路径创建File
对象,可以是绝对路径或者相对路径,如果pathname
是相对路径,则默认的当前路径在系统属性user.dir
中存储。
扩展绝对路径:是一个固定的路径,从盘符开始: 相对路径:是相对于某个位置开始
public File(String parent,String child);
以parent
为父路径,child为子路径创建File对象。
public File(File parent,String child)
;根据一个父File
对象和子文件路径创建File
对象
File(String pathname)
File(File parent, String child)
File(String parent, String child)
- 文件路径名字符串test.txt,我们可以创建一个抽象路径名
File dummyFile = new File("test.txt");
File dummyFile = new File("test.txt");
名为test.txt的文件不必存在,以使用此语句创建File
对象。dummyFile对象表示抽象路径名
,它可能指向或可能不指向文件系统中的真实文件。String workingDir = System.getProperty("user.dir");
:通过读取user.dir系统属性
来获取JVM
的当前工作目录System.setProperty("user.dir", "C:\\\\myDir");
:使用System.setProperty()
方法更改当前工作目录。
Java_File判断文件存在
- 使用
File类的exists()
方法检查File对象的抽象路径名是否存在;boolean fileExists = dummyFile.exists();
import java.io.File;
public class Main {
public static void main(String[] argv) {
// Create a File object
File dummyFile = new File("dummy.txt");
// Check for the file"s existence
boolean fileExists = dummyFile.exists();
if (fileExists) {
System.out.println("The dummy.txt file exists.");
} else {
System.out.println("The dummy.txt file does not exist."); // 输出结果The dummy.txt file does not exist
}
}
}
Java_路径
- 绝对路径在文件系统上唯一标识文件。规范路径是唯一标识文件系统上文件的最简单路径
- 使用
getAbsolutePath()
分别获得由File对象
表示的绝对路径 - 使用
getCanonicalPath()
方法来获取File对象
表示的规范路径。
import java.io.File;
import java.io.IOException;
public class Main {
public static void main(String[] args) {
printFilePath("dummy.txt");
printFilePath(".." + File.separator + "notes.txt");
}
public static void printFilePath(String pathname) {
File f = new File(pathname);
System.out.println("File Name: " + f.getName());
System.out.println("File exists: " + f.exists());
System.out.println("Absolute Path: " + f.getAbsolutePath());
try {
System.out.println("Canonical Path: " + f.getCanonicalPath());
}
catch (IOException e) {
e.printStackTrace();
}
}
}
Java_文件操作
- 使用
File类的createNewFile()
方法创建一个新文件:File dummyFile = new File("test.txt");boolean fileCreated = dummyFile.createNewFile();
如果文件已成功创建,则返回true;否则,返回false。如果发生I/O错误,该方法将抛出IOException。
createNewFile()
方法创建一个新的空文件,如果有指定名称的文件不存在。
创建文件夹:
- 使用
mkdir()或mkdirs()
方法创建一个新目录。 - 可以在默认的临时文件目录或目录中创建一个临时文件,使用
File类的createTempFile()
静态方法,该方法接受前缀和后缀以生成临时文件名。File tempFile = File.createTempFile("abc", ".txt");
File newDir = new File("C:\\\\users\\\\home")
;仅当路径名中指定的父目录已存在时,mkdir()
方法才创建目录。只有当C:\\users
目录已经存在时,newDir.mkdir()
方法才会创建主目录。
删除文件:
- 使用
File类的delete()
方法来删除文件/目录。 - 目录必须为空,我们才能删除它。
- 如果文件/目录被删除,
File类的delete()
方法返回true; 否则,返回false。 - 可以延迟删除文件,直到JVM通过使用
deleteOnExit()
方法终止。 - 在程序中创建临时文件,当程序退出时要删除,这将非常有用。
立即删除dummy.txt文件
File dummyFile = new File("dummy.txt");
dummyFile.delete();
在JVM终止时删除dummy.txt文件
File dummyFile = new File("dummy.txt");
dummyFile.deleteOnExit();
文件重命名:
-
要重命名文件,可以使用
renameTo()
方法,renameTo()
使用一个File对象来表示新文件:
boolean fileRenamed = oldFile.renameTo(newFile);
-
下例中的文件命名已经存在了,所以,
renameTo()
方法返回false。
import java.io.File;
public class Main {
public static void main(String[] argv) {
// Rename old-dummy.txt to new_dummy.txt
File oldFile = new File("old_dummy.txt");
File newFile = new File("new_dummy.txt");
boolean fileRenamed = oldFile.renameTo(newFile);
if (fileRenamed) {
System.out.println(oldFile + " renamed to " + newFile);
} else {
System.out.println("Renaming " + oldFile + " to " + newFile
+ " failed."); // 输出结果
}
}
}
文件属性:
- File类包含让我们获取/设置文件和目录的属性的方法。
- 可以设置分别使用
setReadOnly(),setReadable(),setWritable()和setExecutable()
方法将文件设置为只读,可读,可写和可执行。
- 使用
lastModified()和setLastModified()
方法来获取和设置文件的最后修改日期和时间。 - 使用
isHidden()
方法检查文件是否被隐藏。
文件大小:
- 使用File类的length()方法获取文件的大小(以字节为单位)。
File myFile = new File("myfile.txt");
long fileLength = myFile.length();
- 如果File对象表示不存在的文件,则
length()
方法返回零。 length()
方法的返回类型是long,而不是int。
查看文件和目录:
- 使用File类的listRoots()静态方法获取文件系统中可用根目录的列表。 它返回一个File对象数组
File[] roots = File.listRoots();
- 使用
File类的list()或listFiles()
方法列出目录中的所有文件和目录。list()方法返回一个String
数组,而listFiles()方法返回一个File
数组。
文件过滤器
- 要从列表中排除扩展名为.SYS的所有文件,可以使用由功能接口FileFilter的实例表示的文件过滤器来实现。它包含一个
accept()
方法,它将File
作为参数列出,如果应该列出文件,则返回true。
返回false
不会列出文件。
创建一个文件过滤器,将过滤扩展名为.SYS的文件。
FileFilter filter = file -> {
if (file.isFile()) {
String fileName = file.getName().toLowerCase();
if (fileName.endsWith(".sys")) {
return false;
}
}
return true;
};
Java_输入流
- 抽象基本组件是
InputStream
类并且有FileInputStream,ByteArrayInputStream和PipedInputStream,FilterInputStream
的具体类。 InputStream
包含从输入流读取数据的基本方法,所有具体类都支持这些方法。
方法:
read()
读取一个字节并将读取的字节作为int
返回。当到达输入流的结尾时,它返回-1
。read(byte[] buffer)
读取最大值直到指定缓冲区的长度。它返回在缓冲区中读取的字节数。如果到达输入流的结尾,则返回-1
。read(byte [] buffer,int offset,int length)
读取最大值到指定长度字节。数据从偏移索引开始写入缓冲区。它返回读取的字节数或-1
,如果到达输入流的结束。close()
关闭输入流available()
返回可以从此输入流读取但不阻塞的估计字节数。
Java_I/O流原理
- I/O是Input/Output的缩写, I/O技术是非常实用的技术,用于处理设备之间的数据传输。如读/写文件,网络通讯等。
- Java程序中,对于数据的输入/输出操作以“流(stream)” 的方式进行。
- java.io包下提供了各种“流”类和接口,用以获取不同种类的数据,并通过标准的方法输入或输出数据。
- 输入input:读取外部数据(磁盘、光盘等存储设备的数据)到程序(内存)中。
- 输出output:将程序(内存)数据输出到磁盘、光盘等存储设备中。
流的分类:
- 按操作数据单位不同分为:字节流(8 bit),字符流(16 bit)
- 按数据流的流向不同分为:输入流,输出流
- 按流的角色的不同分为:节点流,处理流
节点流和处理流:
- 节点流:直接从数据源或目的地读写数据
- 处理流:不直接连接到数据源或目的地,而是“连接”在已存在的流(节点流或处理流)之上,通过对数据的处理为程序提供更为强大的读写功能。
Java_InpitStream 和 Reader
InputStream 和 Reader
是所有输入流的基类。InputStream(典型实现:FileInputStream)
常见方法:int read()
,int read(byte[] b)
,int read(byte[] b, int off, int len)
Reader(典型实现:FileReader)
:常用方法:int read(),int read(char [] c),int read(char [] c, int off, int len)
- 程序中打开的文件 IO 资源不属于内存里的资源,垃圾回收机制无法回收该资源,所以应该显式关闭文件
IO 资源。
FileInputStream
从文件系统中的某个文件中获得输入字节。FileInputStream
用于读取非文本数据之类的原始字节流。要读取字符流,需要使用FileReader
InputStream类:
int read()
:从输入流中读取数据的下一个字节。返回0 到 255
范围内的int
字节值。如果因
为已经到达流末尾而没有可用的字节,则返回值-1
。int read(byte[] b)
从此输入流中将最多 b.length 个字节的数据读入一个byte
数组中。如果因为已经到达流末尾而没有可用的字节,则返回值 -1。否则以整数形式返回实际读取的字节数。int read(byte[] b, int off,int len)
将输入流中最多 len 个数据字节读入 byte 数组。尝试读取 len 个字节,但读取的字节也可能小于该值。以整数形式返回实际读取的字节数。如果因为流位于文件末尾而没有可用的字节,则返回值 -1。- `public void close() throws IOException:``:关闭此输入流并释放与该流关联的所有系统资源。
Reader类:
int read()
读取单个字符。作为整数读取的字符,如果已到达流的末尾,则返回 -1int read(char[] cbuf)
将字符读入数组。如果已到达流的末尾,则返回 -1。否则返回本次读取的字符数。int read(char[] cbuf,int off,int len)
将字符读入数组的某一部分。存到数组cbuf中,从off处开始存储,最多读len
个字符。如果已到达流的末尾,则返回 -1。否则返回本次读取的字符数。public void close() throws IOException
关闭此输入流并释放与该流关联的所有系统资源。
Java_OutputStream 和 Writer 输出流
OutputStream:
void write(int b)
:将指定的字节写入此输出流。void write(byte[] b)
:将 b.length 个字节从指定的 byte 数组写入此输出流。void write(byte[] b,int off,int len)
将指定 byte 数组中从偏移量 off 开始的 len 个字节写入此输出流。public void flush()throws IOException
:刷新此输出流并强制写出所有缓冲的输出字节,调用此方法指示应将这些字节立即写入它们预期的目标。public void close() throws IOException
:关闭此输出流并释放与该流关联的所有系统资源。
Writer:
-
void write(int c)
:写入单个字符。 -
void write(char[] cbuf)
写入字符数组。 -
void write(char[] cbuf,int off,int len)
:写入字符数组的某一部分。从off开始,写入len个字符 -
void write(String str)
:写入字符串。 -
void write(String str,int off,int len)
:写入字符串的某一部分。 -
void flush()
刷新该流的缓冲,则立即将它们写入预期目标。 -
public void close() throws IOException
关闭此输出流并释放与该流关联的所有系统资源。
Java_节点流(或文件流)
读取文件
- 建立一个流对象,将已存在的一个文件加载进流。
FileReader fr = new FileReader(new File(“Test.txt”));
- 创建一个临时存放数据的数组。
char[] ch = new char[1024];
- 调用流对象的读取方法将流中的数据读入到数组中。
fr.read(ch)
- 关闭资源。
fr.close();
FileReader fr = null;
try {
fr = new FileReader(new File("c:\\\\test.txt"));
char[] buf = new char[1024];
int len;
while ((len = fr.read(buf)) != -1) {
System.out.print(new String(buf, 0, len));
}
} catch (IOException e) {
System.out.println("read-Exception :" + e.getMessage());
} finally {
if (fr != null) {
try {
fr.close();
} catch (IOException e) {
System.out.println("close-Exception :" + e.getMessage());
}
}
}
写入文件
- 创建流对象,建立数据存放文件
FileWriter fw = new FileWriter(new File(“Test.txt”));
- 调用流对象的写入方法,将数据写入流:
fw.write(“atguigu-songhongkang”);
- 关闭流资源,并将流中的数据清空到文件中。
fw.close();
FileWriter fw = null;
try {
fw = new FileWriter(new File("Test.txt"));
fw.write("atguigu-songhongkang");
} catch (IOException e) {
e.printStackTrace();
} finally {
if (fw != null)
try {
fw.close();
} catch (IOException e) {
e.printStackTrace();
}
}
Java_对象流
ObjectInputStream和OjbectOutputSteam
用于存储和读取基本数据类型数据或对象的处理流。它的强大之处就是可以把Java中的对象写入到数据源中,也能把对象从数据源中还原回来。- 序列化:用
ObjectOutputStream
类保存基本类型数据或对象的机制 - 反序列化:用
ObjectInputStream
类读取基本类型数据或对象的机制 ObjectOutputStream和ObjectInputStream
不能序列化static和transient
修饰的成员变量
Java_对象序列化
- 对象序列化机制允许把内存中的Java对象转换成平台无关的二进制流,从而允许把这种二进制流持久地保存在磁盘上,或通过网络将这种二进制流传输到另一个网络节点。//当其它程序获取了这种二进制流,就可以恢复成原来的Java对象
- 序列化的好处在于可将任何实现了Serializable接口的对象转化为字节数据,使其在保存和传输时可被还原
- 序列化是
RMI(Remote Method Invoke – 远程方法调用)
过程的参数和返回值都必须实现的机制,而RMI 是 JavaEE
的基础。因此序列化机制是JavaEE 平台的基础 - 如果需要让某个对象支持序列化机制,则必须让对象所属的类及其属性是可序列化的,为了让某个类是可序列化的,该类必须实现如下两个接口之一。否则,会抛出
NotSerializableException
异常:1.Serializable
2.Externalizable
- 凡是实现
Serializable
接口的类都有一个表示序列化版本标识符的静态变量:private static final long serialVersionUID;``serialVersionUID
用来表明类的不同版本间的兼容性,如果类没有显示定义这个静态常量,它的值是Java运行时环境根据类的内部细节自动生成的。 - 若类的实例变量做了修改,
serialVersionUID
可能发生变化。所以显式声明。
对象序列化重点
- Java的序列化机制是通过在运行时判断类的
serialVersionUID
来验证版本一致性的。 - 在进行反序列化时,
JVM
会把传来的字节流中的serialVersionUID
与本地相应实体类的serialVersionUID
进行比较,如果相同就认为是一致的,可以进行反序列化,否则就会出现序列化版本不一致的异常。(InvalidCastException)
使用对象流序列化对象;
- 若某个类实现了 Serializable 接口,该类的对象就是可序列化的:
- 创建一个
ObjectOutputStream
- 调用
ObjectOutputStream 对象的 writeObject(对象)
方法输出可序列化对象 - 注意写出一次,操作
flush()
一次
反序列化
- 创建一个
ObjectInputStream
- 调用
readObject()
方法读取流中的对象 - 强调:如果某个类的属性不是基本数据类型或
String
类型,而是另一个引用类型,那么这个引用类型必须是可序列化的,否则拥有该类型的Field
的类也不能序列化
//序列化:将对象写入到磁盘或者进行网络传输。
//要求对象必须实现序列化
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(“data.txt"));
Person p = new Person("韩梅梅", 18, "中华大街", new Pet());
oos.writeObject(p);
oos.flush();
oos.close();
//反序列化:将磁盘中的对象数据源读出。
ObjectInputStream ois = new ObjectInputStream(new FileInputStream(“data.txt"));
Person p1 = (Person)ois.readObject();
System.out.println(p1.toString());
ois.close();
Java_Java NIO 概述
- Java NIO (New IO,Non-Blocking IO)是一套新的
IO API
,可以替代标准的Java IO API
。NIO
与原来的IO
有同样的作用和目的,但是使用的方式完全不同,NIO
支持面向缓冲区的(IO是面向流的)、基于通道的IO操作。NIO将以更加高效的方式进行文件的读写操作。 - Java API中提供了两套
NIO
,一套是针对标准输入输出NIO
,另一套就是网络编程NIO
Java_NIO.2中Path、Paths、Files类的使用
- 早期的Java只提供了一个File类来访问文件系统,但File类的功能比较有限,所提供的方法性能也不高。而且,大多数方法在出错时仅返回失败,并不会提供异常信息。
- NIO. 2为了弥补这种不足,引入了Path接口,代表一个平台无关的平台路径,描述了目录结构中文件的位置。
Path可以看成是File类的升级版本
,实际引用的资源也可以不存在。
在以前IO操作都是这样写的:
import java.io.File;
File file = new File("index.html");
但在Java7 中,我们可以这样写:
import java.nio.file.Path;
import java.nio.file.Paths;
Path path = Paths.get("index.html");
- NIO.2在java.nio.file包下还提供了
Files、Paths
工具类,Files
包含了大量静态的工具方法来操作文件;Paths则包含了两个返回Path
的静态工厂方法。 - Paths 类提供的静态
get()
方法用来获取Path
对象: static Path get(String first, String … more)
: 用于将多个字符串串连成路径static Path get(URI uri)
: 返回指定uri对应的Path路径
Java_NIO.2中Path常用方法
String toString()
: 返回调用 Path 对象的字符串表示形式boolean startsWith(String path)
: 判断是否以 path 路径开始boolean endsWith(String path)
: 判断是否以 path 路径结束boolean isAbsolute()
: 判断是否是绝对路径Path getParent()
:返回Path对象包含整个路径,不包含 Path 对象指定的文件路径Path getRoot()
:返回调用 Path 对象的根路径Path getFileName()
: 返回与调用 Path 对象关联的文件名int getNameCount()
: 返回Path 根目录后面元素的数量Path getName(int idx)
: 返回指定索引位置 idx 的路径名称Path toAbsolutePath()
: 作为绝对路径返回调用 Path 对象Path resolve(Path p)
:合并两个路径,返回合并后的路径对应的Path对象File toFile()
: 将Path转化为File类的对象
Java_NIO.2中Files 类
java.nio.file.Files
用于操作文件或目录的工具类。
Files常用方法:
Path copy(Path src, Path dest, CopyOption … how)
: 文件的复制Path createDirectory(Path path, FileAttribute<?> … attr)
: 创建一个目录Path createFile(Path path, FileAttribute<?> … arr)
: 创建一个文件void delete(Path path)
: 删除一个文件/目录,如果不存在,执行报错void deleteIfExists(Path path)
: Path对应的文件/目录如果存在,执行删除Path move(Path src, Path dest, CopyOption…how)
: 将 src 移动到 dest 位置long size(Path path)
: 返回 path 指定文件的大小
Files常用方法:用于判断
boolean exists(Path path, LinkOption … opts)
: 判断文件是否存在boolean isDirectory(Path path, LinkOption … opts)
: 判断是否是目录boolean isRegularFile(Path path, LinkOption … opts)
: 判断是否是文件boolean isHidden(Path path
) : 判断是否是隐藏文件boolean isReadable(Path path)
: 判断文件是否可读boolean isWritable(Path path
) : 判断文件是否可写boolean notExists(Path path, LinkOption … opts)
: 判断文件是否不存在
Files常用方法:用于操作内容
SeekableByteChannel newByteChannel(Path path, OpenOption…how)
: 获取与指定文件的连接,how 指定打开方式。DirectoryStream<Path> newDirectoryStream(Path path)
: 打开 path 指定的目录InputStream newInputStream(Path path, OpenOption…how)
:获取 InputStream 对象OutputStream newOutputStream(Path path, OpenOption…how)
: 获取 OutputStream 对象
以上是关于Java_I/O流的主要内容,如果未能解决你的问题,请参考以下文章
Java_I/O输入输出_实现当用户输入姓名和密码时,将每一个姓名和密码加在文件中,如果用户输入done,就结束程序。
java内存流:java.io.ByteArrayInputStreamjava.io.ByteArrayOutputStreamjava.io.CharArrayReaderjava.io(代码片段
java缓冲字符字节输入输出流:java.io.BufferedReaderjava.io.BufferedWriterjava.io.BufferedInputStreamjava.io.(代码片段