java I/O系统的概念和分类
概念
- I/O系统:输入/输出系统。java I/O系统使我们能够通过控制台、文件、内存块,甚至英特网进行读写。
- 流:输入/输出对象。代表任何有能力产出数据的数据源对象或者是有能力接收数据的接收端对象。
分类
- I/O四个基类。
流向/数据类型 | 字节流 | 字符流 |
---|---|---|
输入流 | InputStream | Reader |
输出流 | OutputStream | Writer |
InputStream():字节输入流基类
AudioInputStream:音频输入流
ByteArrayInputStream(byte[]):内部缓冲区
FileInputStream(File/String):读取诸如图像数据的原始字节流
FilterInputStream(InputStream):转换数据/提供附加功能(装饰类)
InputStream():CDR元数据流读取IDL
ObjectInputStream(/InputStream):反序列化
PipedInputStream(PipedOutputStream):管道输入流
SequenceInputStream(InputStream s1, InputStream s2):表示其他输入流的逻辑级联
FilterInputStream(InputStream):过滤输入流基类
BufferedInputStream(InputStream):mark和reset方法,标记,重置位置
CheckedInputStream(InputStream, Checksum 校验和):验证输入数据的完整性
CipherInputStream(InputStream):解密
DataInputStream(InputStream):读取原始Java数据类型
DeflaterInputStream(InputStream):压缩“放气”压缩格式的数据
DigestInputStream(InputStream, MessageDigest 消息摘要):消息摘要计算
InflaterInputStream(InputStream):解压缩数据
ProgressMonitorInputStream(Component 被监视操作的组件, Object 描述性文本, InputStream):监视读取输入流的进度
PushbackInputStream(InputStream):“推回”或“未读”一个字节
OutputStream(OutputStream):字节输出流基类
ByteArrayOutputStream():写入字节数组
FileOutputStream(File/String):写入诸如图像数据的原始字节流
FilterOutputStream(OutputStream):转换数据/提供附加功能(装饰类)
ObjectOutputStream():原始数据类型和图形写入
OutputStream():将IDL类型写入CDR元数据流
PipedOutputStream(/PipedInputStream):连接到管道输入流以创建通信管道
FilterOutputStream():过滤输出流基类
BufferedOutputStream(OutputStream):缓冲输出流
CheckedOutputStream(OutputStream, Checksum 校验和):验证输出数据的完整性
CipherOutputStream(OutputStream):加密
DataOutputStream(OutputStream):写入原始Java数据类型
DeflaterOutputStream(OutputStream):压缩输出流过滤器
GZIPOutputStream(OutputStream):以GZIP文件格式写入压缩数据
ZipOutputStream(OutputStream):以ZIP文件格式写入文件
DigestOutputStream(OutputStream, MessageDigest 消息摘要):消息摘要计算
InflaterOutputStream(OutputStream):解压
PrintStream(File/String/OutputStream):打印各种数据值
Reader():读取字符流的抽象类
BufferedReader(Reader):缓冲字符,高效读取
LineNumberReader(Reader):缓冲字符输入流,跟踪行号
CharArrayReader(char[]):字符缓冲区
FilterReader(Reader):过滤后的字符流的抽象类
PushbackReader(Reader):字符推回到流中
InputStreamReader(InputStream):字节转换为字符
FileReader(File/String):阅读字符文件
PipedReader(PipedWriter):字符输入流
StringReader(String):字符流,其源是一个字符串
Writer():写入字符流的抽象类
BufferedWriter(Writer):缓冲字符,高效读取
CharArrayWriter():字符缓冲区
FilterWriter(Writer):过滤后的字符流的抽象类
OutputStreamWriter(OutputStream):字节转换为字符
FileWriter(File/String):写字符文件
PipedWriter():字符输出流
PrintWriter(File/String/Writer):打印到文本输出流
StringWriter():构造字符串
- 按功能
- 节点流:可以从一个特定的节点(地方)读写数据。
- 文件
- 字符串
- 数组
- 管道
- 处理流:对一个已存在流的连接和封装,通过被封装流实现数据读写。
- 缓冲流
- 转换流
- 数据流
- 合并流
- 打印流
- 对象流
- 压缩流
- 回退流
- 节点流:可以从一个特定的节点(地方)读写数据。
java I/O类库及应用
File类
File类是一个实用类库工具,可以帮助我们处理文件目录问题。它既能代表一个特定文件的名称,又能代表一个目录下一组文件的名称。
// 构造器
import java.io.*;
class FileConstructor{
public static void printAbPath( File file ){
System.out.println( file.getAbsolutePath() );
}
public static void main( String[] args ){
File file = new File( "E:/java" );
printAbPath( file );
File file1 = new File( file, "201906" );
printAbPath( file1);
File file2 = new File( "E:/java", "201906" );
printAbPath( file2 );
}
}
public class Test0613{
public static void main( String[] args ){
FileConstructor.main( args );
}
}
------------------------
E:\java>java Test0613
E:\java
E:\java\201906
E:\java\201906
// 获取文件属性
import java.io.*;
class FileAttribute{
public static void main( String[] args )throws IOException{
File file = new File( "E:/java", "Test0613.java" );
System.out.println( "父目录字符串: " + file.getParent() );
System.out.println( "父目录文件: " + file.getParentFile() );
System.out.println( "绝对形式: " + file.getAbsoluteFile() );
System.out.println( "绝对路径: " + file.getAbsolutePath() );
System.out.println( "规范形式: " + file.getCanonicalFile() );
System.out.println( "规范路径: " + file.getCanonicalPath() );
System.out.println( "路径: " + file.getPath() );
System.out.println( "路径字符串: " + file.toString() );
System.out.println( "文件名称: " + file.getName() );
System.out.println( "文件长度: " + file.length() );
System.out.println( "修改时间: " + file.lastModified() );
System.out.println( "是否绝对: " + ( file.isAbsolute() ? "绝对的" : "不绝对的" ) );
System.out.println( "是否目录: " + ( file.isDirectory() ? "目录" : "不是目录" ) );
System.out.println( "是否文件: " + ( file.isFile() ? "文件" : " 不是文件" ) );
System.out.println( "是否隐藏: " + ( file.isHidden() ? "隐藏" : "不是隐藏" ) );
System.out.println( "是否可执行文件: " + ( file.canExecute() ? "可执行" : "不可执行" ) );
System.out.println( "是否可读: " + ( file.canRead() ? "可读" : "不可读" ) );
System.out.println( "是否可写: " + ( file.canWrite() ? "可写" : "不可写" ) );
System.out.println( "是否存在: " + ( file.exists() ? "存在" : "不存在" ) );
}
}
public class Test0613{
public static void main( String[] args )throws IOException{
FileAttribute.main( args );
}
}
------------------------------------
E:\java>java Test0613
父目录字符串: E:\java
父目录文件: E:\java
绝对形式: E:\java\Test0613.java
绝对路径: E:\java\Test0613.java
规范形式: E:\java\Test0613.java
规范路径: E:\java\Test0613.java
路径: E:\java\Test0613.java
路径字符串: E:\java\Test0613.java
文件名称: Test0613.java
文件长度: 7195
修改时间: 1560446490428
是否绝对: 绝对的
是否目录: 不是目录
是否文件: 文件
是否隐藏: 不是隐藏
是否可执行文件: 可执行
是否可读: 可读
是否可写: 可写
是否存在: 存在
// 创建新文件
import java.io.*;
class CreateFile{
public static void createFile( File file )throws IOException{
if( ! file.exists() ) file.mkdirs();
if( file.getName().contains( "." ) ){
file.delete();
file.createNewFile();
}
else{
file.delete();
file.mkdir();
}
}
public static void main( String[] args )throws IOException{
File file =new File( "E:/java/202002" );
File file1 = new File( file, "Test0000.java" );
File file2 = new File( file, "202001" );
createFile( file1 );
createFile( file2 );
}
}
public class Test0613{
public static void main( String[] args )throws IOException{
CreateFile.main( args );
}
}
// 遍历目录所有文件列表
import java.io.*;
class TraversalDirectory{
public static void traversalDirectory( String fileName ){
traversalDirectory( new File( fileName ) );
}
public static void traversalDirectory( File file ){
if( ! file.exists() ) return;
if( file.isFile() ){
System.out.println( file.getAbsolutePath() );
return;
}
String[] fileNames = file.list();
if( fileNames != null ){
for( String s : fileNames ) {
File f = new File( file, s );
System.out.println( f.getAbsolutePath() );
if( f.isDirectory() ){
traversalDirectory( f );
}
}
}
}
public static void main( String[] args ){
traversalDirectory( "." );
}
}
public class Test0613{
public static void main( String[] args ){
TraversalDirectory.main( args );
}
}
// 简单的输出目录,不知道下面的例子为何有那么多步骤?
import java.io.*;
public class Test0606{
public static void main( String[] args ){
File path = new File( "." ); // 创建File实例,表示抽象路径名。
String[] str = path.list(); // list():返回表示抽象路径名的字符串组。
for( String s : str ) System.out.println( s ); // 遍历路径名。
}
}
---------------------
E:\java>java Test0606
201904
201905
201906
Test0606.class
Test0606.java
util
资源
import java.util.regex.*;
import java.io.*;
import java.util.*;
class DirList{ // 目录列表
public static void main( String[] args ){
File path = new File( "." );
String[] list;
// 默认args.length = 0; // args是在命令行进行赋值传入参数。比如:java Test0608 one two three
// 传入的参数是args[0] = "one", args[1] = "two", args[2] = "three"。
if( args.length == 0 ) list = path.list();
else list = path.list( new DirFilter( args[ 0 ] ) );
Arrays.sort( list, String.CASE_INSENSITIVE_ORDER );
for( String dirItem : list ) System.out.println( dirItem );
}
}
class DirFilter implements FilenameFilter{
private Pattern pattern;
public DirFilter( String regex ){
pattern = Pattern.compile( regex ); // 创建regex正则表达式的Pattern(模式)实例
}
public boolean accept( File dir, String name ){
// mathcer():创建匹配器。// matches():与模式进行匹配。
return pattern.matcher( name ).matches();
}
}
public class Test0529{
public static void main( String[] args ){
DirList.main( args );
}
}
---------------------
E:\java>java Test0529
201904
201905
DirFilter.class
DirList.class
Test0529.class
Test0529.java
util
资源
import java.util.regex.*;
import java.util.*;
import java.io.*;
class DirList{
public static FilenameFilter filter( final String regex ){
return new FilenameFilter(){
private Pattern pattern = Pattern.compile( regex );
public boolean accept( File dir, String name ){
return pattern.matcher( name ).matches();
}
};
}
public static void main( String[] args ){
File path = new File( "." );
String[] list;
if( args.length == 0 ) list = path.list();
else list = path.list( filter( args[0] ));
Arrays.sort( list, String.CASE_INSENSITIVE_ORDER );
for( String dirItem : list ) System.out.println( dirItem );
}
}
public class Test0529{
public static void main( String[] args ){
DirList.main( args );
}
}
---------------------
E:\java>java Test0529
201904
201905
DirFilter.class
DirList$1.class
DirList.class
Test0529.class
Test0529.java
util
资源
import java.util.regex.*;
import java.util.*;
import java.io.*;
class DirList{
public static void main( final String[] args ){
File path = new File( "." );
String[] list;
if( args.length == 0 ) list = path.list();
else list = path.list( new FilenameFilter(){
private Pattern pattern = Pattern.compile( args[0] );
public boolean accept( File dir, String name ){
return pattern.matcher( name ).matches();
}
});
Arrays.sort( list, String.CASE_INSENSITIVE_ORDER );
for( String dirItem : list ) System.out.println( dirItem );
}
}
public class Test0529{
public static void main( String[] args ){
DirList.main( args );
}
}
---------------------
E:\java>java Test0529
201904
201905
DirFilter.class
DirList$1.class
DirList.class
Test0529.class
Test0529.java
util
资源
标准I/O
- 标准I/O:程序所使用的单一信息流。程序的所有输入都可以来自于标准输入,所有输出都可以发送到标准输出,所有的错误信息都可以发送到标准错误。
- 按照标准I/O模型,java提供了System.in、System.out和System.err。System.out和System.err已经事先被包装成printStream对象,而System.in是未被包装过的InputStream。因此,在读取System.in之前必须对其进行包装。
// 从标准输入中读取
import java.io.*;
class Echo{ // 回显输入的每一行
public static void main( String[] args ) throws IOException{
BufferedReader stdin = new BufferedReader( new InputStreamReader( System.in ) ); // 包装成BufferedReader
String s;
// readLine():读取输入的一行。
while( ( s = stdin.readLine() ) != null && s.length() != 0 ) System.out.println( s );
}
}
public class Test0530{
public static void main( String[] args ) throws IOException{
Echo.main( args );
}
}
---------------------
E:\java>java Test0530
fgjhxxd
fgjhxxd
lhlhjlvvvvvvvvvvvv
lhlhjlvvvvvvvvvvvv
// 将System.out转换成PrintWriter
import java.io.*;
class ChangeSystemOut{
public static void main( String[] args ){
PrintWriter out = new PrintWriter( System.out, true ); // 转换
out.println( "Hello, world" );
}
}
public class Test0530{
public static void main( String[] args ){
ChangeSystemOut.main( args );
}
}
---------------------
E:\java>java Test0530
Hello, world
// 重定向:使用InputStream和OutputStream,操作的是字节流。
import java.io.*;
class Redirecting{
public static void main( String[] args ) throws IOException{
PrintStream console = System.out;
BufferedInputStream in = new BufferedInputStream( new FileInputStream( "Test0530.java" ) );
PrintStream out = new PrintStream( new BufferedOutputStream( new FileOutputStream( "test.out" ) ) );
System.setIn( in );
System.setOut( out );
System.setErr( out );
BufferedReader br = new BufferedReader( new InputStreamReader( System.in ) );
String s;
while( ( s = br.readLine() ) != null ) System.out.println( s );
out.close();
System.setOut( console );
}
}
public class Test0530{
public static void main( String[] args ) throws IOException{
Redirecting.main( args );
}
}
新I/O
I/O应用
// 缓冲输入文件
import java.io.*;
class BufferedInputFile{ // 缓冲输入文件
public static String read( String filename )throws IOException{
BufferedReader in = new BufferedReader( new FileReader( filename ) );
String s;
// StringBuilder比String和StringBuffer更高效,StringBuffer用于线程安全。
StringBuilder sb = new StringBuilder();
while( (s = in.readLine()) != null ){ // readLine():读一行文字。任何情况要使用readLine()首选BufferedReader。
// sb.append( s + "\n" );是书上原语句,但根据书上关于StringBuilder的用法原则,应该改成下面的语句,更高效。
sb.append( s ); sb.append( "\n" );
}
in.close(); // 关闭流,并释放资源。
return sb.toString();
}
public static void main( String[] args )throws IOException{
System.out.print( read( "Test0607.java" ) );
}
}
public class Test0607{
public static void main( String[] args )throws IOException{
BufferedInputFile.main( args );
}
}
--------------------------------------------------------------------------------
E:\java>java Test0607
import java.io.*;
class BufferedInputFile{ // 缓冲输入文件
public static String read( String filename )throws IOException{
BufferedReader in = new BufferedReader( new FileReader( filename
) );
String s;
// StringBuilder比String和StringBuffer更高效,StringBuffer用于线
程安全。
StringBuilder sb = new StringBuilder();
while( (s = in.readLine()) != null ){ // readLine():读一行文字
。
// sb.append( s + "\n" );是书上原语句,但根据书上关于Str
ingBuilder的用法原则,应该改成下面的语句,更高效。
sb.append( s ); sb.append( "\n" );
}
in.close(); // 关闭流,并释放资源。
return sb.toString();
}
public static void main( String[] args )throws IOException{
System.out.print( read( "Test0607.java" ) );
}
}
public class Test0607{
public static void main( String[] args )throws IOException{
BufferedInputFile.main( args );
}
}
import java.io.*;
class MemoryInput{ // 从内存输入
public static void main( String[] args )throws IOException{
StringReader in = new StringReader( BufferedInputFile.read( "Test0607.java" ) );
int c;
while( (c = in.read()) != -1 ) System.out.print( (char) c );
}
}
public class Test0607{
public static void main( String[] args )throws IOException{
MemoryInput.main( args );
}
}
--------------
输出效果同上例
import java.io.*;
class FormattedMemoryInput{ // 格式化的内存输入
public static void main( String[] args )throws IOException{
try{
DataInputStream in = new DataInputStream(
new ByteArrayInputStream( BufferedInputFile.read( "Test0607.java" ).getBytes() ) );
while( true ) System.out.print( (char) in.readByte() );
}catch( IOException e ){
System.err.println( "End of Stream" );
}
}
}
public class Test0607{
public static void main( String[] args )throws IOException{
FormattedMemoryInput.main( args );
}
}
--------------
输出效果同上例
import java.io.*;
class TestEOF{
public static void main( String[] args ) throws IOException{
DataInputStream in = new DataInputStream( new BufferedInputStream( new FileInputStream( "Test0607.java" ) ) );
while( in.available() != 0 ) System.out.print( (char) in.readByte() );
}
}
public class Test0607{
public static void main( String[] args )throws IOException{
TestEOF.main( args );
}
}
--------------
输出效果同上例
import java.io.*;
class BasicFileOutput{ // 基本的文件输出
static String file = "Test0607.java";
public static void main( String[] args )throws IOException{
BufferedReader in = new BufferedReader(
new StringReader( BufferedInputFile.read( "Test0607.java" ) ) );
PrintWriter out = new PrintWriter( new BufferedWriter( new FileWriter( file ) ) );
int lineCount = 1;
String s;
while( (s = in.readLine()) != null ) out.println( lineCount ++ + ": " + s );
out.close();
System.out.println( BufferedInputFile.read( file ) );
}
}
public class Test0607{
public static void main( String[] args )throws IOException{
BasicFileOutput.main( args );
}
}
--------------------------------------------------------------------------------
// 前面的/* 1 - 91 */已省略
92: import java.io.*;
93: class BasicFileOutput{
94: static String file = "Test0607.java";
95: public static void main( String[] args )throws IOException{
96: BufferedReader in = new BufferedReader(
97: new StringReader( BufferedInputFile.read( "Test0607.java
" ) ) );
98: PrintWriter out = new PrintWriter( new BufferedWriter( new FileW
riter( file ) ) );
99: int lineCount = 1;
100: String s;
101: while( (s = in.readLine()) != null ) out.println( lineCount ++
+ ": " + s );
102: out.close();
103: System.out.println( BufferedInputFile.read( file ) );
104: }
105: }
106: public class Test0607{
107: public static void main( String[] args )throws IOException{
108: BasicFileOutput.main( args );
109: }
110: }
import java.io.*;
class FileOutputShortcut{ // 文本文件输出的快捷方式
static String file = "Test0607.out";
public static void main( String[] args )throws IOException{
BufferedReader in = new BufferedReader(
new StringReader( BufferedInputFile.read( "Test0607.java" ) ) );
PrintWriter out = new PrintWriter( new BufferedWriter( new FileWriter( file ) ) );
int lineCount = 1; String s;
while( (s = in.readLine()) != null ) out.println( lineCount ++ + ": " + s );
out.close();
System.out.println( BufferedInputFile.read( file ) );
}
}
public class Test0607{
public static void main( String[] args )throws IOException{
FileOutputShortcut.main( args );
}
}
--------------
输出效果同上例
import java.io.*;
class StoringAndRecoveringData{ // 存储和恢复数据
public static void main( String[] args )throws IOException{
DataOutputStream out = new DataOutputStream(
new BufferedOutputStream( new FileOutputStream( "Data.txt" ) ) );
out.writeDouble( 3.14159 );
out.writeUTF( "That was pi" );
out.writeDouble( 1.141413 );
out.writeUTF( "Square root of 2" );
out.close();
DataInputStream in = new DataInputStream(
new BufferedInputStream( new FileInputStream( "Data.txt" ) ) );
System.out.println( in.readDouble() );
System.out.println( in.readUTF() );
System.out.println( in.readDouble() );
System.out.println( in.readUTF() );
}
}
public class Test0607{
public static void main( String[] args )throws IOException{
StoringAndRecoveringData.main( args );
}
}
// 另外会创建一个Data.txt文件,写入下面的数据,但数据是乱码的形式。
---------------------
E:\java>java Test0607
3.14159
That was pi
1.141413
Square root of 2
import java.io.*;
class UsingRandomAccessFile{ // 读写随机访问文件
static String file = "rtest.dat";
static void display() throws IOException{
RandomAccessFile rf = new RandomAccessFile( file, "r" );
for( int i = 0; i < 7; i ++ ) System.out.println( "Value" + i + ": " + rf.readDouble() );
System.out.println( rf.readUTF() );
rf.close();
}
public static void main( String[] args )throws IOException{
RandomAccessFile rf = new RandomAccessFile( file, "rw" );
for( int i = 0; i < 7; i ++ ) rf.writeDouble( i * 1.414 );
rf.writeUTF( "The end of the file" );
rf.close();
display();
}
}
public class Test0607{
public static void main( String[] args )throws IOException{
UsingRandomAccessFile.main( args );
}
}
-------------------------
E:\java>java Test0607
Value0: 0.0
Value1: 1.414
Value2: 2.828
Value3: 4.242
Value4: 5.656
Value5: 7.069999999999999
Value6: 8.484
The end of the file
import java.io.*;
import java.util.*;
class TextFile extends ArrayList< String >{ // 工具:文件读写
public static String read( String fileName ){
StringBuilder sb = new StringBuilder();
try{
BufferedReader in = new BufferedReader(
new FileReader( new File( fileName ).getAbsoluteFile() ) );
try{
String s;
while( (s = in.readLine()) != null ){
sb.append( s ); sb.append( "\n" );
}
}finally{ in.close(); }
}catch( IOException e ){ throw new RuntimeException( e ); }
return sb.toString();
}
public static void write( String fileName, String text ){
try{
PrintWriter out = new PrintWriter(
new File( fileName ).getAbsoluteFile() );
try{ out.print( text ); }
finally{ out.close(); }
}catch( IOException e ){ throw new RuntimeException( e ); }
}
public TextFile( String fileName, String splitter ){
super( Arrays.asList( read( fileName ).split( splitter ) ) );
if( get( 0 ).equals( "" ) ) remove( 0 );
}
public TextFile( String fileName ){ this( fileName, "\n" ); }
public void write( String fileName ){
try{
PrintWriter out = new PrintWriter(
new File( fileName ).getAbsoluteFile() );
try{ for( String item : this ) out.println( item ); }
finally{ out.close(); }
}catch( IOException e ){ throw new RuntimeException( e ); }
}
public static void main( String[] args ){
String file = read( "Test0608.java" );
write( "test.txt", file );
TextFile text = new TextFile( "test.txt" );
text.write( "test2.txt" );
TreeSet< String > words = new TreeSet< String >( new TextFile( "Test0608.java", "\\W+" ) );
System.out.println( words.headSet( "a" ) );
}
}
public class Test0608{
public static void main( String[] args ){
TextFile.main( args );
}
}
--------------------------------------------------------------------------------
E:\java>java Test0608
[0, ArrayList, Arrays, BufferedReader, File, FileReader, IOException, PrintWrite
r, RuntimeException, String, StringBuilder, System, Test0608, TextFile, TreeSet,
W]
import java.io.*;
class BinaryFile{ // 工具:读取二进制文件
public static byte[] read( File bFile )throws IOException{
BufferedInputStream bf = new BufferedInputStream( new FileInputStream( bFile ) );
try{
byte[] data = new byte[ bf.available() ];
bf.read( data );
return data;
}finally{ bf.close(); }
}
public static byte[] read( String bFile )throws IOException{
return read( new File( bFile ).getAbsoluteFile() );
}
public static void main( String[] args ){
}
}
public class Test0608{
public static void main( String[] args ){
BinaryFile.main( args );
}
}