File IO(NIO.2):读、写并创建文件
简介
本页讨论读,写,创建和打开文件的细节。有各种各样的文件I / O方法可供选择。为了帮助理解API,下图以复杂性排列文件I / O方法
在图的最左侧是实用程序方法readAllBytes,readAllLines和write方法,为简单的常见情况设计。右边是用于迭代流或文本行的方法,例如newBufferedReader,newBufferedWriter,然后是newInputStream和newOutputStream。这些方法可以与java.io包兼容。右边是处理ByteChannels,SeekableByteChannels和ByteBuffers的方法,比如newByteChannel方法。最后,对于需要文件锁定或内存映射I
/ O的高级应用程序,使用FileChannel的方法是最右边的。
注意:创建新文件的方法可以为文件指定一组可选的初始属性。例如,在支持POSIX标准集(如UNIX)的文件系统上,您可以在创建文件时指定文件所有者,组所有者或文件权限。“管理元数据”页面介绍文件属性,以及如何访问和设置它们
操作参数
本节中的几个方法使用可选的OpenOptions参数。此参数是可选的,API会告诉您,当没有指定时,该方法的默认行为是什么
支持以下StandardOpenOptions枚举:
WRITE - 打开文件以进行写访问。
APPEND - 将新数据附加到文件的末尾。该选项用于WRITE或CREATE选项。
TRUNCATE_EXISTING - 将文件截断为零字节。该选项与WRITE选项一起使用。
CREATE_NEW - 创建一个新文件,如果文件已经存在,则会引发异常。
CREATE - 如果文件存在,打开文件,如果没有,则创建一个新文件。
DELETE_ON_CLOSE - 流关闭时删除文件。此选项对临时文件很有用。
SPARSE - 提示新创建的文件将是稀疏的。这种高级选项在某些文件系统(例如NTFS)中得到尊重,其中具有数据“间隙”的大型文件可以以更有效的方式存储,这些空隙不占用磁盘空间。
SYNC - 保持与底层存储设备同步的文件(内容和元数据)。
DSYNC - 保持与底层存储设备同步的文件内容。
仅用于小文件的方法
读取文件中所有的字节或行:如果您有一个小的文件,并且您想在一次读取其全部内容,则可以使用readAllBytes(Path)或readAllLines(Path,Charset)方法。这些方法可以处理大部分的工作,比如打开和关闭流,但不适合处理大文件。以下代码显示了如何使用readAllBytes方法:
Path file = ...;
byte[] fileArray;
fileArray = Files.readAllBytes(file);
输出文件中所有的字节或行:您可以使用一种写入方式将字节或行写入文件。
write(Path, byte[], OpenOption...)
write(Path, Iterable< extends CharSequence>, Charset, OpenOption...)
以下代码片段显示了如何使用write方法:
Path file = ...;
byte[] buf = ...;
Files.write(file, buf);
对于Text文件的缓冲IO方法
java.nio.file包支持通道I / O,它可以将数据移入到一个缓冲区中,绕过一些IO的瓶颈
使用缓冲流读取文件:newBufferedReader(Path,Charset)方法打开一个文件进行读取,返回一个BufferedReader,可以用来以高效的方式从文件中读取文本。以下代码片段显示了如何使用newBufferedReader方法从文件中读取。该文件以“US-ASCII”编码。
Charset charset = Charset.forName("US-ASCII");
try (BufferedReader reader = Files.newBufferedReader(file, charset)) {
String line = null;
while ((line = reader.readLine()) != null) {
System.out.println(line);
}
} catch (IOException x) {
System.err.format("IOException: %s%n", x);
}
使用缓冲流输出文件:您可以使用newBufferedWriter(Path,Charset,OpenOption ...)方法使用BufferedWriter写入文件。以下代码片段显示如何使用此方法创建以“US-ASCII”编码的文件:
Charset charset = Charset.forName("US-ASCII");
String s = ...;
try (BufferedWriter writer = Files.newBufferedWriter(file, charset)) {
writer.write(s, 0, s.length());
} catch (IOException x) {
System.err.format("IOException: %s%n", x);
}
对于非缓冲流和互操作的java.io API
使用流读取一个文件:要打开文件进行阅读,可以使用newInputStream(Path,OpenOption ...)方法。该方法返回一个无缓冲的输入流,用于从文件读取字节。
Path file = ...;
try (InputStream in = Files.newInputStream(file);
BufferedReader reader =
new BufferedReader(new InputStreamReader(in))) {
String line = null;
while ((line = reader.readLine()) != null) {
System.out.println(line);
}
} catch (IOException x) {
System.err.println(x);
}
使用IO流创建并输出一个文件:您可以使用newOutputStream(Path,OpenOption ...)方法创建文件,附加到文件或写入文件。此方法打开或创建用于写入字节的文件,并返回无缓冲的输出流。该方法采用可选的OpenOption参数。如果没有指定打开的选项,并且该文件不存在,将创建一个新的文件。如果文件存在,则会被截断。此选项相当于使用CREATE和TRUNCATE_EXISTING选项调用该方法。
以下示例打开日志文件。如果文件不存在,则创建它。如果文件存在,它将被打开以进行追加。
import static java.nio.file.StandardOpenOption.*;
import java.nio.file.*;
import java.io.*; public class LogFileTest { public static void main(String[] args) { // Convert the string to a
// byte array.
String s = "Hello World! ";
byte data[] = s.getBytes();
Path p = Paths.get("./logfile.txt"); try (OutputStream out = new BufferedOutputStream(
Files.newOutputStream(p, CREATE, APPEND))) {
out.write(data, 0, data.length);
} catch (IOException x) {
System.err.println(x);
}
}
}
用于通道和字节流的方法
使用通道流读写文件:当流I / O一次读取一个字符时,通道I / O一次读取一个缓冲区。 ByteChannel接口提供基本的读写功能。SeekableByteChannel是一个ByteChannel,它具有维持通道中位置并改变该位置的能力。 SeekableByteChannel还支持截断与通道关联的文件,并查询文件的大小。
移动到文件中的不同点,然后从该位置读取或写入到该位置的能力使得文件的随机访问成为可能
通道I / O读取和写入有两种方法:newByteChannel(Path, OpenOption...) 和 newByteChannel(Path, Set<? extends OpenOption>, FileAttribute<?>...)
注意:newByteChannel方法返回一个SeekableByteChannel的实例。使用默认文件系统,您可以将此可寻找字节通道转换为FileChannel,以提供对更高级功能的访问,从而将文件的一个区域直接映射到内存中,以便更快的访问,锁定文件的一个区域,以便其他进程无法访问该文件,或从绝对位置读取和写入字节,而不影响通道的当前位置。
两个newByteChannel方法都可以指定一个OpenOption选项列表。除了另外一个选项,还支持newOutputStream方法使用的相同的打开选项:READ是必需的,因为SeekableByteChannel支持读写。
指定READ打开通道读取。指定WRITE或APPEND打开通道进行写入。如果没有指定这些选项,则打开通道进行读取。 以下代码片段读取文件并将其打印到标准输出:
// Defaults to READ
try (SeekableByteChannel sbc = Files.newByteChannel(file)) {
ByteBuffer buf = ByteBuffer.allocate(10); // Read the bytes with the proper encoding for this platform. If
// you skip this step, you might see something that looks like
// Chinese characters when you expect Latin-style characters.
String encoding = System.getProperty("file.encoding");
while (sbc.read(buf) > 0) {
buf.rewind();
System.out.print(Charset.forName(encoding).decode(buf));
buf.flip();
}
} catch (IOException x) {
System.out.println("caught exception: " + x);
以下为UNIX和其他POSIX文件系统编写的示例创建具有特定文件权限集的日志文件。此代码创建日志文件或附加到日志文件(如果它已经存在)。创建日志文件,具有对组的所有者和只读权限的读/写权限。
import static java.nio.file.StandardOpenOption.*;
import java.nio.*;
import java.nio.channels.*;
import java.nio.file.*;
import java.nio.file.attribute.*;
import java.io.*;
import java.util.*; public class LogFilePermissionsTest { public static void main(String[] args) { // Create the set of options for appending to the file.
Set<OpenOption> options = new HashSet<OpenOption>();
options.add(APPEND);
options.add(CREATE); // Create the custom permissions attribute.
Set<PosixFilePermission> perms =
PosixFilePermissions.fromString("rw-r-----");
FileAttribute<Set<PosixFilePermission>> attr =
PosixFilePermissions.asFileAttribute(perms); // Convert the string to a ByteBuffer.
String s = "Hello World! ";
byte data[] = s.getBytes();
ByteBuffer bb = ByteBuffer.wrap(data); Path file = Paths.get("./permissions.log"); try (SeekableByteChannel sbc =
Files.newByteChannel(file, options, attr)) {
sbc.write(bb);
} catch (IOException x) {
System.out.println("Exception thrown: " + x);
}
}
}
用于创建一个常规或者临时文件的方法
创建文件:您可以使用createFile(Path,FileAttribute <?>)方法创建一个具有初始属性集的空文件。例如,如果在创建时想要一个文件具有特定的一组文件权限,可以使用createFile方法。如果不指定任何属性,则使用默认属性创建文件。如果文件已经存在,则createFile会引发异常。
在单个原子操作中,createFile方法检查文件的存在,并使用指定的属性创建该文件,这使得进程对恶意代码的安全性更高。 以下代码段创建一个默认属性的文件:
Path file = ...;
try {
// Create the empty file with default permissions, etc.
Files.createFile(file);
} catch (FileAlreadyExistsException x) {
System.err.format("file named %s" +
" already exists%n", file);
} catch (IOException x) {
// Some other sort of failure, such as permissions.
System.err.format("createFile error: %s%n", x);
}
POSIX文件权限有一个使用createFile(Path,FileAttribute <?>)创建具有预设权限的文件的示例。 您还可以使用newOutputStream方法创建新文件,如使用流I / O创建和写入文件中所述。如果您打开一个新的输出流并立即关闭,则会创建一个空文件。
创建临时文件:您可以使用以下createTempFile方法之一创建临时文件:
createTempFile(Path, String, String, FileAttribute<?>)
createTempFile(String, String, FileAttribute<?>)
第一种方法允许代码为临时文件指定目录,第二种方法在默认临时文件目录中创建一个新文件。两种方法都允许您为文件名指定后缀,第一种方法允许您指定前缀。以下代码片段给出了第二种方法的示例:
try {
Path tempFile = Files.createTempFile(null, ".myapp");
System.out.format("The temporary file" +
" has been created: %s%n", tempFile)
;
} catch (IOException x) {
System.err.format("IOException: %s%n", x);
}
运行此文件的结果将如下所示:
The temporary file has been created: /tmp/509668702974537184.myapp
File IO(NIO.2):读、写并创建文件的更多相关文章
- IO侦探:多进程写ceph-fuse单文件性能瓶颈侦查
近期接到ceph用户报案,说是多进程direct写ceph-fuse的单个文件,性能很低,几乎与单进程direct写文件的性能一样.关乎民生,刻不容缓,笔者立即展开侦查工作~ 一.复现案情,寻踪追记 ...
- Android(java)学习笔记167:Java中操作文件的类介绍(File + IO流)
1.File类:对硬盘上的文件和目录进行操作的类. File类是文件和目录路径名抽象表现形式 构造函数: 1) File(String pathname) Creat ...
- Android(java)学习笔记110:Java中操作文件的类介绍(File + IO流)
1.File类:对硬盘上的文件和目录进行操作的类. File类是文件和目录路径名抽象表现形式 构造函数: 1) File(String pathname) Creat ...
- Java 学习(9):java Stream & File & IO
Java 流(Stream).文件(File)和IO Java.io 包几乎包含了所有操作输入.输出需要的类.所有这些流类代表了输入源和输出目标. Java.io 包中的流支持很多种格式,比如:基本类 ...
- Java Stream File & IO
摘录自:http://www.runoob.com/java/java-files-io.html Java 流(Stream).文件(File)和IO Java.io包几乎包含了所有操作输入.输出需 ...
- Haskell语言学习笔记(19)File IO
关于IO Action 类型为IO t. 运算时不执行,因而没有任何效果,只有执行时才会有效果,产生副作用. 一个IO Action只有在其他IO Action中才能被执行. 类型为IO t的IO A ...
- php学习笔记--高级教程--读取文件、创建文件、写入文件
打开文件:fopen:fopen(filename,mode);//fopen("test.txt","r"): 打开模式:r 仅仅读方式打开,将文件指针指向 ...
- Android创建文件夹及文件并写入数据
package elwin.fei.mobileaudio; import java.io.BufferedWriter; import java.io.File; import java.io.Fi ...
- Java 在给定路径上创建文件,所在文件夹不存在时,如何正确创建。
String strPath = "E:\\a\\aa\\aaa.txt"; File file = new File(strPath); if(!file.exists())){ ...
随机推荐
- linux 命令——38 cal (转)
cal命令可以用来显示公历(阳历)日历.公历是现在国际通用的历法,又称格列历,通称阳历.“阳历”又名“太阳历”,系以地球绕行太阳一周为一年,为西方各国所通用,故又名“西历”. 1.命令格式: cal ...
- 初学树套树:线段树套Treap
前言 树套树是一个十分神奇的算法,种类也有很多:像什么树状数组套主席树.树状数组套值域线段树.\(zkw\)线段树套\(vector\)等等. 不过,像我这么弱,当然只会最经典的 线段树套\(Trea ...
- python_68_迭代器
''' 我们已经知道,可以直接作用于for循环的数据类型有以下几种: 一类是集合数据类型,如list.tuple.dict.set.str等: 一类是generator,包括生成器和带yield的ge ...
- cd ..和cd -
cd ..是返回上一层目录, cd -是返回到上一次的工作目录.
- CUDA实现数组倒序
数组倒序,将在主机上初始化的数组传输到设备上,然后用CUDA并行倒序,此时在全局内存上操作,再将结果返回到主机并验证. #include <stdio.h> #include <as ...
- Activiti学习记录(一)
1.工作流的概念 工作流(Workflow),就是“业务过程的部分或整体在计算机应用环境下的自动化”,它主要解决的是“使在多个参与者之间按照某种预定义的规则传递文档.信息或任务的过程自动进行,从而实现 ...
- 自己写一个Promise
参考Promise 的 官方规范 https://promisesaplus.com/ Promise 其实就是一个状态机 它只有两种状态变化 pending => fulfill ...
- vue的属性监听
一.vue的监听 1.监听的例子 如: html:<input type="number" v-model="a" /> js: watch: { ...
- caller、callee的用法及区别
1 :caller 返回一个调用当前函数的引用 如果是由顶层调用的话 则返回null (举个栗子哈 caller给你打电话的人 谁给你打电话了 谁调用了你 很显然是下面a函数的执行 只有在打电话的时 ...
- cf519C. A and B and Team Training(找规律)
题意 $a$个学生,$b$个教练 可以两个学生和一个教练一组,也可以两个教练和一个学生一组,问最多组成多少组 Sol 发题解的目的是为了纪念一下自己的错误思路 刚开始想的是:贪心的选,让少的跟多的分在 ...