文件的内容类型
Files.probeContentType(Path path)
方法探测文件的内容类型。该方法以多用途互联网邮件扩展(MIME)内容类型的值的字符串形式返回内容类型。如果无法确定文件的内容类型,则返回null
。
以下代码显示如何探测文件的内容类型。
import java.nio.file.Files
import java.nio.file.Path
import java.nio.file.Paths
import java.io.IOException
public class Main {
public static void main(String[] args) {
Path p = Paths.get("C:\\Java_Dev\\test1.txt")
try {
String contentType = Files.probeContentType(p)
System.out.format("Content type of %s is %s%n", p, contentType)
} catch (IOException e) {
e.printStackTrace()
}
}
}
上面的代码生成以下结果。
Content type of C:\Java_Dev\test1.txt is text/plain
读取文件的内容
Files
类包含以下方法来读取文件的内容作为字节和文本行:
- static byte[] readAllBytes(Path path) - reads all bytes from a file.
- static List readAllLines(Path path) - reads the entire contents of a file lines of text.
- static List readAllLines(Path path, Charset cs)
Files
类可以从Path
对象获取InputStream
和BufferedReader
对象。newInputStream(Path path,OpenOption ... options)
方法返回指定路径的InputStream
对象。它假定文件的内容是UTF-8
字符集。
newBufferedReader(Path path)
和newBufferedReader(Path path,Charset cs)
方法返回一个BufferedReader
。我们可以指定字符集。Files
类提供了使用其newByteChannel(Path path,OpenOption ... options)
方法从Path
对象中获取SeekableByteChannel
对象的方法。
OpenOption
类型配置正在打开的文件。下表列出了OpenOption
类型的值及其描述。OpenOption
是java.nio.file
包中的一个接口。java.nio.file
包中的StandardOpenOption
枚举实现了OpenOption
接口。
标准打开选项 | 描述 |
---|---|
APPEND | 将写入的数据附加到现有文件,如果文件被打开写入。 |
CREATE | 创建一个新文件,如果它不存在。 |
CREATE_NEW | 如果文件不存在,则创建一个新文件。 如果文件已存在,则操作失败。 |
DELETE_ON_CLOSE | 关闭流时删除文件。在与临时文件一起使用时非常有用。 |
DSYNC | 保持文件的内容与底层存储同步。 |
READ | 打开具有读访问权限的文件。 |
SPARSE | 如果它与CREATE_NEW 选项一起使用,它对文件系统提示新文件应该是稀疏文件。 |
SYNC | 保持文件的内容和元数据与底层存储同步。 |
TRUNCATE_EXISTING | 如果打开文件以进行写访问,则将现有文件的长度截断为零。 |
WRITE | 打开文件以进行写访问。 |
以下代码实现在默认目录中为test2.txt
文件获取一个SeekableByteChannel
对象。它打开文件以进行读取和写入访问。它使用CREATE
选项,因此如果文件不存在,则创建该文件。
import static java.nio.file.StandardOpenOption.CREATE
import static java.nio.file.StandardOpenOption.READ
import static java.nio.file.StandardOpenOption.WRITE
import java.nio.channels.SeekableByteChannel
import java.nio.file.Files
import java.nio.file.Path
import java.nio.file.Paths
public class Main {
public static void main(String[] args) throws Exception {
Path src = Paths.get("test2.txt")
SeekableByteChannel sbc = Files.newByteChannel(src, READ, WRITE, CREATE)
}
}
以下代码演示了如何读取和显示默认目录中test1.txt
文件的内容。 如果文件不存在,程序将显示一条错误消息。
import java.io.IOException
import java.nio.charset.Charset
import java.nio.file.Files
import java.nio.file.NoSuchFileException
import java.nio.file.Path
import java.nio.file.Paths
import java.util.List
public class Main {
public static void main(String[] args) throws Exception{
Charset cs = Charset.forName("US-ASCII")
Path source = Paths.get("test1.txt")
List<String> lines = Files.readAllLines(source, cs)
for (String line : lines) {
System.out.println(line)
}
}
}
写入文件
使用Files
类的以下write()
方法将内容写入文件。
static Path write(Path path, byte[] bytes, OpenOption... options)
static Path write(Path path, Iterable lines, OpenOption... options)
static Path write(Path path, Iterable lines, Charset cs, OpenOption... options)
write()
方法打开文件,将传递的内容写入文件,并关闭它。如果没有打开选项,它将使用CREATE
,TRUNCATE_EXISTING
和WRITE
选项打开文件。
如果正在向文件写入文本,它会写一个平台相关的行分隔符。如果在写入文本行时未指定字符集,则默认使用UTF-8
字符集。
以下代码演示了如何使用write()
方法将文本行写入文件。
import static java.nio.file.StandardOpenOption.CREATE
import static java.nio.file.StandardOpenOption.WRITE
import java.io.IOException
import java.nio.charset.Charset
import java.nio.file.Files
import java.nio.file.Path
import java.nio.file.Paths
import java.util.ArrayList
import java.util.List
public class Main {
public static void main(String[] args) {
List<String> texts = new ArrayList<>()
texts.add("test line - 1")
texts.add("test line - 2")
Path dest = Paths.get("C:\\Java_Dev\\twinkle.txt")
Charset cs = Charset.forName("US-ASCII")
try {
Path p = Files.write(dest, texts, cs, WRITE, CREATE)
System.out.println("Text was written to " + p.toAbsolutePath())
} catch (IOException e) {
e.printStackTrace()
}
}
}
Files.newOutputStream(Path path,OpenOption ... options)
返回指定路径的OutputStream
。Files.newBufferedWriter(Path path, Charset cs, OpenOption... options)
方法为指定的路径返回BufferedWriter
。
执行上面代码,得到以下结果 -
Text was written to C:\Java_Dev\twinkle.txt
随机访问文件
SeekableByteChannel
对象提供对文件的随机访问。使用Files
类的newByteChannel()
方法为Path
获取一个SeekableByteChannel
对象,如下所示:
Path src = Paths.get("test.txt")
SeekableByteChannel seekableChannel = Files.newByteChannel(src, READ, WRITE, CREATE, TRUNCATE_EXISTING)
使用size()
方法以字节为单位获取SeekableByteChannel
实体的大小。由于数据被截断或写入通道,因此更新了大小。
import static java.nio.file.StandardOpenOption.CREATE
import static java.nio.file.StandardOpenOption.READ
import static java.nio.file.StandardOpenOption.TRUNCATE_EXISTING
import static java.nio.file.StandardOpenOption.WRITE
import java.io.IOException
import java.nio.ByteBuffer
import java.nio.CharBuffer
import java.nio.channels.SeekableByteChannel
import java.nio.charset.Charset
import java.nio.file.Files
import java.nio.file.Path
import java.nio.file.Paths
public class Main {
public static void main(String[] args) {
Path src = Paths.get("test.txt")
String encoding = System.getProperty("file.encoding")
Charset cs = Charset.forName(encoding)
try (SeekableByteChannel seekableChannel = Files.newByteChannel(src, READ, WRITE, CREATE, TRUNCATE_EXISTING)) {
printDetails(seekableChannel, "Before writing data")
writeData(seekableChannel, cs)
printDetails(seekableChannel, "After writing data")
seekableChannel.position(0)
printDetails(seekableChannel, "After resetting position to 0")
readData(seekableChannel, cs)
printDetails(seekableChannel, "After reading data")
} catch (IOException e) {
e.printStackTrace()
}
}
public static void writeData(SeekableByteChannel seekableChannel, Charset cs) throws IOException {
String separator = System.getProperty("line.separator")
StringBuilder sb = new StringBuilder()
sb.append("test")
sb.append(separator)
sb.append("test2")
sb.append(separator)
CharBuffer charBuffer = CharBuffer.wrap(sb)
ByteBuffer byteBuffer = cs.encode(charBuffer)
seekableChannel.write(byteBuffer)
}
public static void readData(SeekableByteChannel seekableChannel, Charset cs) throws IOException {
ByteBuffer byteBuffer = ByteBuffer.allocate(128)
String encoding = System.getProperty("file.encoding")
while (seekableChannel.read(byteBuffer) > 0) {
byteBuffer.rewind()
CharBuffer charBuffer = cs.decode(byteBuffer)
System.out.print(charBuffer)
byteBuffer.flip()
}
}
public static void printDetails(SeekableByteChannel seekableChannel, String msg) {
try {
System.out.println(
msg + ": Size = " + seekableChannel.size() + ", Position = " + seekableChannel.position())
} catch (IOException e) {
e.printStackTrace()
}
}
}
上面的代码生成以下结果。
Before writing data: Size = 0, Position = 0
After writing data: Size = 13, Position = 13
After resetting position to 0: Size = 13, Position = 0
test
test2