03 IO流
IO的API方法少且较为固定,有一定的规律,需要熟悉掌握并学会使用特定情况下所使用的代码。
详情参考JDK最新版本的API官方文档,此处只做简单介绍。
概念
IO流即输出流和输入流
将外设的数据读取到内存中:输入
将内存的数据读取到外设中:输出
字符流与字节流
字节流是由字节组成的,不仅可以操作字符,还可以操作其他媒体文件,处理的最小单位是byte.
字符流是由字符组成的,只能操作字符数据,处理的最小单位是char.
字符流的由来:字节流读取字节数据后,查找指定的编码表获得对应的文字,再对该文字进行操作。字符流是由Java虚拟机将字节转化为2个字节的Unicode字符为单位的字符而成的。简单来说,字符流=字节流+编码表
字节流的两个顶层抽象父类InputStreamReader和OutputStreamWriter
字符流的两个顶层抽象类Reader和Writer
类的介绍
字符流顶层父类Reader ###
常用方法与说明
abstract void close():关闭该流并释放与之关联的所有资源。
int read():读取单个字符,如果已到达流的末尾,则返回 -1。
int read(char[] cbuf):将字符读入数组,返回读入数据的长度。
abstract int read(char[] cbuf, int off, int len): 将字符读入数组的某一部分,返回读入数据的长度。
字符流顶层父类Writer
常用方法与说明
Writer append(char c):将指定字符添加到此 writer。
Writer append(CharSequence csq):将指定字符序列添加到此 writer。
Writer append(CharSequence csq, int start, int end):将指定字符序列的子序列添加到此 writer.Appendable。
void write(int c):写入单个字符。
void write(String str):写入字符串。
void write(String str, int off, int len):写入字符串的某一部分。
abstract void close():关闭此流,会调用flush方法刷新它。
abstract void flush(): 刷新该流的缓冲。
void write(char[] cbuf):写入字符数组。
abstract void write(char[] cbuf, int off, int len):写入字符数组的某一部分。
FileReader
构造方法及常用方法
FileReader(File file):根据给定File对象创建FileReader对象
FileReader(String fileName):根据给定文件名创建FileReader对象
使用示例
FileReaderDemo1.java
public class FileReaderDemo1{
public static void main( String[] args ) throws IOException{
// 单个字符读取文件流
FileReader fReader = new FileReader( "input.txt" );//IOException需要处理或者抛出
int ch;
// 如果已到达流的末尾,则返回 -1
while ( (ch = fReader.read()) != -1 )
{
System.out.print( (char)ch );
ch = fReader.read();
}
fReader.close();// 关闭文件输出流,释放资源
}
}
FileReaderDemo2.java
public class FileReaderDemo2{
public static void main( String[] args ) throws IOException{
// 使用字符数组读取文件流
FileReader fReader = new FileReader( "input.txt" );
char[] ch = new char[1024];
int count = 0;
while ( (count = fReader.read( ch )) != -1 )//IOException需要处理或者抛出
{
System.out.println( count + new String( ch, 0, count ) );
}
fReader.close();
}
}
FileWriter
构造方法及常用方法
FileWriter(File file):根据给定的 File 对象创建 FileWriter 对象。
FileWriter(File file, boolean append):根据给定的 File 对象构造一个 FileWriter 对象,如果 append为true,那么对该文件进行续写。
FileWriter(String fileName):根据给定的文件名创建FileWriter对象。
FileWriter(String fileName, boolean append):根据给定的文件名创建FileWriter对象。
使用示例
FileWriterDemo1.java
public class FileWriterDemo1{
public static void main( String[] args ) throws IOException{
/*
* 创建一个文件字符输出流对象
* 构造函数FileWriter(String fileName)
* 若文件不存在,则自动创建
* 若文件存在,则覆盖原文件
*/
FileWriter fWriter = new FileWriter( "output.txt" );//IOException需要处理或者抛出
// 调用write写入数据到临时存储缓冲区
fWriter.write( "Hello World" + LINE_SEPARATOR + "hiahia" + LINE_SEPARATOR );//IOException需要处理或者抛出
// 每次写入都进行flush刷新流,保证数据不丢失
fWriter.flush();
// 关闭文件流。关闭前会调用flush刷新缓冲
fWriter.close();
}
}
FileWriterDemo2.java
public class FileWriterDemo2{
public static void main( String[] args ) throws IOException{
// 使用字符串进行write操作,也可以使用字符数组(略)
FileWriter fWriter = new FileWriter( "output.txt" );
String s = "Hello World";
fWriter.write( s );
fWriter.close();
}
}
程序实现:拷贝text文件,使用数组作为缓冲区,并做异常处理
CopyFileByCharArrays.java
public class CopyFileByCharArrays{
public static void main( String[] args ) throws IOException{
String source, destination;
source = "input.txt";
destination = "output.txt";
FileReader fReader = null;
FileWriter fWriter = null;
try{
fReader = new FileReader( source );
fWriter = new FileWriter( destination );
char[] arr = new char[1024];// 创建临时容器,用于缓存读取到的字符,容器大小一般为1024的整数倍
int len = 0;// 定义一个变量记录读取到的字符数
while( (len = fReader.read( arr )) != -1 ){
fWriter.write( arr, 0, len );
}
} catch( Exception e ){
throw new RuntimeException( "读写失败" );
} finally{
if( fReader != null )//健壮性判断
try{
fReader.close();
} catch( IOException e1 ){
e1.printStackTrace();
}
if( fWriter != null )
try{
fWriter.close();
} catch( IOException e ){
e.printStackTrace();
}
}
}
}
BufferedReader
作用:从字符输入流中读取文本,缓冲各个字符,从而实现字符、数组和行的高效读取。
使用目的:提高读取效率。
readLine():读取文本行。实现原理:使用读取缓冲区的read方法,将读取到的字符进行缓冲并判断换行标记,将标记前的数据变成字符串返回
构造方法
BufferedReader(Reader in):创建一个使用默认大小输入缓冲区的缓冲字符输入流。
BufferedReader(Reader in, int size):创建一个使用指定大小输入缓冲区的缓冲字符输入流。
常用方法
String readLine():读取一个文本行。
*其余方法参考Reader
使用示例
BufferedReader.java
public class CopyFileByCharArrays{
public static void main( String[] args ){
FileReader fReader = new FileReader( "input.txt" );
// 为提高读取效率,使用字符流读取的缓冲区
// 创建一个和被缓冲的读取流对象相关联的字符读取流的缓冲区对象BufferedReader
BufferedReader bReader = new BufferedReader( fReader );
String line = null;
while ( (line = bReader.readLine()) != null )
{
// 读取文本行,不包含换行符
System.out.println( line );
}
// 关闭缓冲区,其实就是关闭了被缓冲的对象,同时也调用了flush方法
bReader.close();// 等同于 fWriter.close();
}
}
MyBufferedReader
模拟BufferedReader,自定义读取缓冲区(装饰设计模式)
MyBufferedReader.java
/**
* 实现原理:使用读取缓冲区的read方法,将读取到的字符进行缓冲并判断换行标记,将标记前的数据变成字符串返回
* @classname MyBufferedReader
* @author LiShengc
*/
public class MyBufferedReader extends Reader
{
private final int BUFFER_SIZE = 1024;
private Reader reader;
char[] buffer;
int index, len;
public MyBufferedReader( Reader reader )
{
this.reader = reader;
buffer = new char[BUFFER_SIZE];
index = 0;
len = 0;
}
public String myReadLine() throws IOException
{
StringBuilder sb = new StringBuilder();
int ch;
while( (ch = read()) != -1 )
{
// 判断换行符
if( ch == '\r' )
continue;
if( ch == '\n' )
return sb.toString();
sb.append( (char)ch );
}
// 健壮性判定,判断当前行是否最后一行
if( sb.length() > 0 )
return sb.toString();
return null;
}
@Override
public int read( char[] cbuf, int off, int len ) throws IOException
{
if( index == len )
{
len = reader.read( buffer );
index = 0;
}
if( len == -1 )
return -1;
return buffer[index++];
}
@Override
public void close() throws IOException
{
reader.close();
}
}
BufferedWriter
构造方法
*参考BufferedReader
常用方法
newLine():写入一个行分隔符。分隔符字符串由系统属性 line.separator定义,可使用 private final static String LINE_SEPARATOR = System.getProperty( "line.separator" );
语句定义一个静态常量并获取当前系统下的换行符。
*其余方法参考Writer
使用示例
BufferedWriterDemo.java
public class BufferedWriterDemo{
public static void main( String[] args ) throws IOException{
FileWriter fWriter = new FileWriter( "output.txt" );
// 为提高写入效率,使用字符流写入的缓冲区
// 创建一个和被缓冲的写入流对象相关联的字符写入流的缓冲区对象BufferedWriter
BufferedWriter bWriter = new BufferedWriter( fWriter );
bWriter.write( "abcd" );
// 写入换行符
bWriter.newLine();
// 刷新缓冲区
bWriter.flush();
// 关闭缓冲区,其实就是关闭了被缓冲的对象,同时也调用了flush方法
bWriter.close();// 等同于 fWriter.close();
}
}
*装饰设计模式
对一组对象的功能进行增强时,使用该模式进行问题的解决。
装饰设计模式和继承都能实现一样的特点——进行某种功能的扩展。
继承方法实现的缺点:
1. 为体系的每个类实现一个功能扩展的子类会导致该继承体系臃肿,且当体系进行扩展时,问题更加突出。
2. 使用不够灵活。
例子:BufferedRead,BufferedWriter类
装饰设计模式:将所需要增强的功能进行单独封装,并将该功能和具体对象相结合。在构造函数中只需要传入该体系的顶层父类,在体系扩展时无需改动,更为灵活。
特点:装饰类和被装饰类都必须同属于一个接口或者父类
LineNumberReader
构造方法
LineNumberReader(Reader in):使用默认输入缓冲区的大小创建LineNumberReader对象。
LineNumberReader(Reader in, int size):使用指定的输入缓冲区的大小创建LineNumberReader对象。
常用方法
int getLineNumber():获得当前行号。
void setLineNumber(int lineNumber)设置当前行号。默认为0,每获取一行+1。
*其余方法及构造方法参考父类Reader
使用示例
LineNumberReaderDemo.java
public class LineNumberReaderDemo
{
public static void main( String[] args ) throws IOException
{
FileReader fReader = new FileReader( "IO流.txt" );
LineNumberReader lnReader = new LineNumberReader( fReader );
String s = null;
// 可设置起始行号,默认为0
// lnReader.setLineNumber( 100 );
while ( (s = lnReader.readLine()) != null )
{
System.out.println( lnReader.getLineNumber() + ":" + s );
}
lnReader.close();
}
}
字节流顶层父类OutputStream
常用方法
void close()
void write(byte[] b)
void write(byte[] b, int off, int len)
abstract void write(int b)
字节流顶层父类InputStream
常用方法
void close()
void mark(int readlimit)
abstract int read()
int read(byte[] b)
int read(byte[] b, int off, int len)
int available():返回此输入流下一个方法调用可以不受阻塞地从此输入流读取(或跳过)的估计字节数。读取大文件时慎用,内存可能溢出。
FileInputStream
构造方法
FileInputStream(File file):创建一个向指定 File 对象表示的文件中读取数据的FileInputStream对象。
FileInputStream(String name):创建一个向具有指定名称的文件中写入数据的FileInputStream对象。
常用方法
*参考父类InputStream
FileOutputStream
构造方法
FileOutputStream(File file)
FileOutputStream(File file, boolean append)
FileOutputStream(String name)
FileOutputStream(String name, boolean append)
常用方法
*参考父类OutputStream
使用示例:读取键盘录入
使用标准输入对象 System.in
进行读取键盘输入。
ReadKeyToUpperCase1.java
/*
* 需求;获取用户输入的数据,并将小写字母变成大写显示在控制台上。
* 如果输入的是“over”,结束键盘输入
*
* 思路:
* 1.需要将输入的每行数据拼接成字符串
* 2.使用容器StringBuilder
* 3.在用户回车之前将录入的数据变成字符串即可
*/
import java.io.IOException;
import java.io.InputStream;
public class ReadKeyToUpperCase1
{
public static void main( String[] args ) throws IOException
{
//readKey();
readWords();
}
public static void readWords() throws IOException
{
StringBuilder sb = new StringBuilder();
InputStream in = System.in;
int ch = 0;
while( (ch = in.read()) != -1 )
{
// 回车换行不进行存储输出
if( ch == '\r' )
continue;
if( ch == '\n' )
{
String temp = sb.toString();
if( "over".equals( temp ) )
break;
System.out.println( temp.toUpperCase() );
sb.delete( 0, sb.length() );// 清空sb数据
} else
sb.append( (char)ch );
}
}
public static void readKey() throws IOException
{
InputStream in = System.in;//获取System.in对象,即标准输入对象
int ch = in.read();//阻塞式方法
System.out.println( ch );
//windows下回车换行符占用两个字节
ch = in.read();
System.out.println( ch );
ch = in.read();
System.out.println( ch );
//无需关闭in,关闭后此程序将无法再次使用和创建
}
}
转换流InputStreamReader
它是字节流通向字符流的桥梁(解码):它使用指定的 charset 读取字节并将其解码为字符,所使用的字符集可以由名称指定或显式给定,否则接受平台默认的字符集。
为了达到最高效率,可以考虑在BufferedReader内包装InputStreamReader。
构造方法
InputStreamReader(InputStream in):创建一个使用默认字符集的 InputStreamReader。
InputStreamReader(InputStream in, Charset cs):创建使用给定字符集的 InputStreamReader。
InputStreamReader(InputStream in, String charsetName):创建使用指定字符集的 InputStreamReader。
常用方法
*参考父类Reader
使用示例
上述一题的第二种做法:
ReadKeyToUpperCase2.java
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
public class ReadKeyToUpperCase2
{
public static void main( String[] args ) throws IOException
{
InputStream in = System.in;
//将字节流转成字符流
InputStreamReader inReader = new InputStreamReader( in );
BufferedReader biStream = new BufferedReader( inReader );
String lnString = null;
while( (lnString = biStream.readLine()) != null )
{
if( "over".equals( lnString ) )
break;
System.out.println( lnString.toUpperCase() );
}
}
}
转换流:OutputStreamWriter
它是字符流通向字节流的桥梁(编码):可使用指定的 charset 将要写入流中的字符编码成字节。它使用的字符集可以由名称指定或显式给定,否则将接受平台默认的字符集。
构造方法
OutputStreamWriter(OutputStream out)
OutputStreamWriter(OutputStream out, Charset cs)
OutputStreamWriter(OutputStream out, String charsetName)
常用方法
*参考父类Writer
使用示例
使用OutputStreamWriter实现基于上一题的需求,代码如下:
TransToByteStream.java
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
public class TransToByteStream
{
public static void main( String[] args ) throws IOException
{
BufferedReader biStream = new BufferedReader(
new InputStreamReader( System.in ) );
// 完整形式
// OutputStream out = System.out;
// OutputStreamWriter outWriter = new OutputStreamWriter( out );
// BufferedWriter boWriter = new BufferedWriter( outWriter );
BufferedWriter bWriter = new BufferedWriter( new OutputStreamWriter( System.out ) );
String lnString = null;
while( (lnString = biStream.readLine()) != null )
{
if( "over".equals( lnString ) )
break;
boWriter.write( lnString.toUpperCase() );
boWriter.newLine();
boWriter.flush();
}
}
}
使用情景
- 源或目的设备是字节流,但是操作的是文本数据,可以使用转换流将字节流转换为字符流,提高对文本操作的便捷。
- 一旦操作文本涉及到具体的指定字符集时,必须使用转换流。
流的操作规律总结
四个明确
- 明确源和目的
- 源:InputStream Reader
- 目的:OutputStream Writer
-
明确数据是否是纯文本数据
- 是纯文本
- 源:Reader
- 目的:InputStream
- 非纯文本
- 源:InputStream
- 目的:Writer
到此处就可以明确需求中具体要使用哪个体系
- 是纯文本
-
明确具体设备
- 源设备:
- 硬盘:File输入流
- 键盘:System.in(标准输入)
- 内存:数组
- 网络:Socket流
- 目的设备:
- 硬盘:File输出流
- 控制台:System.out(标准输出)
- 内存:数组
- 网络:Socket流
- 是否需要额外功能
- 需要高效读写,使用buffer:BufferedReader和BufferedWriter
- 转换流: InputStreamReader 和 OutputStreamWriter
File类
将文件或者文件夹封装成对象,方便对文件与文件夹的操作
构造方法
File(String pathname):通过将给定路径名字符串转换为抽象路径名来创建一个新 File 实例。
File(String parent, String child):根据 parent 路径名字符串和 child 路径名字符串创建一个新 File 实例。
File(File parent, String child):根据 parent 抽象路径名和 child 路径名字符串创建一个新 File 实例。
File(URI uri):通过将给定的 URI 转换为一个抽象路径名来创建一个新的 File 实例。
具体实现:
File f1=new File( "c:\\test.txt" );
File f2=new File( "c:\\","test.txt" );
File f3=new File( new File( "c:\\" ),"test.txt" );
字段摘要 ###
static String pathSeparator:包含与系统有关的路径分隔符字符的字符串。在 UNIX 系统上,此字段为 ‘:’;在 Microsoft Windows 系统上,它为 ‘;’。与System.getProperty("path.separator")
功能相同。
static char pathSeparatorChar
static String separator:包含与系统有关的默认名称分隔符字符的字符串。。在 UNIX 系统上,此字段的值为 ‘/’;在 Microsoft Windows 系统上,它为 ‘\’。与System.getProperty("file.separator")
功能相同。
static char separatorChar
常用方法
- 获取
- 文件名:String getName()
- 文件大小:long length()
- 最后修改时间:long lastModified(),返回毫秒值
- 文件路径名(不包含文件名):String getParent()
- 绝对路径名:String getAbsolutePath(), String getCanonicalPath()
- 指定路径名下的分区未分配的字节数:long getFreeSpace()
- 当前目录下的文件名以及目录名(包含隐藏文件):String[] list()
**调用list方法的File对象中封装的必须是目录,否则将传回null,访问会发生NullPointerException。
如果File对象中封装的是系统级目录或者不存在的目录,调用list方法也将返回null。
如果目录存在但为空,会返回一个长度为0的空字符串数组** - long getTotalSpace():返回此抽象路径名下的分区大小。
- long getFreeSpace():未分配的字节数。
- long getUsableSpace(): 可用于此虚拟机的字节数。
- File getAbsoluteFile():返回此抽象路径名的绝对路径名表示的File对象。
- File getCanonicalFile():同上。
- File getParentFile():返回此抽象路径名父目录的抽象路径名表示的File对象。
- static File[] listRoots():列出可用的文件系统根(盘符)。
- String[] list(FilenameFilter filter)
- ……
- boolean createNewFile():当且仅当不存在具有此抽象路径名指定名称的文件时,不可分地创建一个新的空文件。如果文件不存在,则创建;如果存在,则不创建。
- boolean mkdir():创建此抽象路径名指定的目录。
- boolean mkdirs():创建多级目录。
- static File createTempFile(String prefix, String suffix):在默认临时文件目录中创建一个空文件,使用给定前缀和后缀生成其名称。
- static File createTempFile(String prefix, String suffix, File directory):在指定目录中创建一个新的空文件,使用给定的前缀和后缀字符串生成其名称。
- boolean delete():删除此抽象路径名表示的文件或目录。
- void deleteOnExit():在虚拟机终止时,请求删除此抽象路径名表示的文件或目录。
- boolean exists():判断此抽象路径名表示的文件或目录是否存在。
- boolean isAbsolute():测试是否为绝对路径名。
- boolean isDirectory():测试是否目录。
- boolean isFile():测试是否标准文件。
- boolean isHidden():测试是否隐藏文件。
- ……
- boolean renameTo(File dest):重新命名此文件。当源路径和目的路径不一致时,该操作为移动。
过滤器
接口FilenameFilter的实现
过滤器FilenameFilter及list方法的使用:ListDemo.javaimport java.io.File;
import java.io.FilenameFilter;
class FilenameFilterSuffixByPDF implements FilenameFilter // 接口FilenameFilter的实现
{
@Override
public boolean accept( File dir, String name )
{
return name.endsWith( ".pdf" );
}
}
public class ListDemo
{
public static void main( String[] args )
{
File file = new File( "d:\\" );
String[] fileList = null;
// 显示d盘下所有文件和目录名称
fileList = file.list();
for( String string : fileList )
{
System.out.println( string );
}
// 输出d盘下所有以".pdf"为后缀名的文件
fileList = file.list( new FilenameFilterSuffixByPDF() );// 使用过滤器筛选结果
for( String string : fileList )
{
System.out.println( string );
}
}
}
接口FileFilter的实现
过滤器FileFilter及listFiles的使用:ListFilesDemo.javaimport java.io.File;
import java.io.FileFilter;
class FilterByHindden implements FileFilter // 接口FileFilter的实现
{
@Override
public boolean accept( File pathname )
{
return pathname.isHidden();
}
}
public class ListFilesDemo
{
public static void main( String[] args )
{
// 获取c:\下所有具有隐藏属性的文件的File对象
File f = new File( "c:\\" );
File[] files = f.listFiles( new FilterByHindden() );
for( File file : files )
{
System.out.println( file );
}
// 输出d:\目录下所有以".pdf"为后缀名的文件
f = new File( "d:\\" );
files = f.listFiles( new FilenameFilterSuffixByPDF() );// 使用过滤器筛选结果
for( File file : files )
{
System.out.println( file );
}
}
}
小程序:深度遍历文件夹
ListAll.javaimport java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import javax.swing.filechooser.FileSystemView;
public class ListAll
{
public static void main( String[] args ) throws IOException
{
// 获取当前电脑的桌面目录
String desktopPath = FileSystemView.getFileSystemView()
.getHomeDirectory().getAbsolutePath();
BufferedWriter bWriter = new BufferedWriter(
new FileWriter( desktopPath + "\\AllFiles.txt" ) );
// 获取各个盘符路径
File[] roots = File.listRoots();
for( File root : roots )
{
// 遍历盘符
listAll( root, bWriter, 0 );
}
bWriter.close();
}
/**
* 获取当前目录下的所有文件夹和文件对象,并输出
*
* @param file
* @param bWriter
* @param count层数计数器,用于带有层次感的缩进输出
* @throws IOException
* @return void
* @author LiShengc
*/
public static void listAll( File file, BufferedWriter bWriter, int count )
throws IOException
{
// 判断是否为盘符目录,是则输出分割行
if( count == 0 )
{
for( int i = 0; i < 80; i++ )
bWriter.write( "*" );
bWriter.newLine();
bWriter.newLine();
}
tab( bWriter, count );
count++;
bWriter.write( file.getAbsolutePath() );// 输出目录路径
bWriter.newLine();
// 获取当前目录下的所有文件夹和文件对象
File[] files = file.listFiles();
if( files != null )
for( int i = 0; i < files.length; i++ )
{
if( files[i].isDirectory() )
{
// 递归
listAll( files[i], bWriter, count );
} else
{
tab( bWriter, count );
try
{
// 输出文件绝对路径
bWriter.write( files[i].getAbsolutePath() );
bWriter.newLine();
} catch( IOException e )
{
throw new RuntimeException(
"写入" + bWriter.toString() + "失败" );
}
}
}
}
/**
* 用于层级缩进
*/
public static void tab( BufferedWriter bWriter, int count )
throws IOException
{
for( int i = 0; i < count; i++ )
{
bWriter.write( " | " );
}
bWriter.write( " |--" );
}
}
小程序:删除非空文件夹
import java.io.File;
public class RemoveDir
{
public static void main( String[] args )
{
String path = "path";
File dir = new File( path );
removeDir( dir );
}
public static void removeDir( File file )
{
File[] files = file.listFiles();
for( File f : files )
{
if( f.isDirectory() )
removeDir( f );
else
System.out.println( f + ":删除" + (f.delete() ? "成功" : "失败") );
}
System.out.println( file + ":删除" + (file.delete() ? "成功" : "失败") );
}
}
Properties集合
集合与IO相结合,通常该集合用于操作以键值对形式存在的配置文件Map特点
- 该集合中的键和值都是字符串类型
- 集合中的数据可以保存到流中,或者从流中获取
使用示例
propertiesDemo1.java
Properties对象数据的存储、修改和获取。
import java.util.Properties;
import java.util.Set;
public class propertiesDemo1
{
public static void main( String[] args )
{
Properties prop = new Properties();
// 存储元素
prop.setProperty( "zhangsan", "30" );
prop.setProperty( "lisi", "24" );
prop.setProperty( "wangwu", "35" );
prop.setProperty( "zhaoliu", "29" );
// 修改元素
prop.setProperty( "wangwu", "15" );// 键相同,值覆盖
// 取出所有元素
Set<String> names = prop.stringPropertyNames();
for( String name : names )
{
String age = prop.getProperty( name );
System.out.println( name + ":" + age );
}
}
}
propertiesDemo2.java
通过Properties对象获取本机系统信息,并输出到标准输出流上。
import java.util.Properties;
public class propertiesDemo2
{
public static void main( String[] args )
{
/*
* 获取系统信息
*/
Properties prop = new Properties();
prop = System.getProperties();
prop.list( System.out );
}
}
store方法
可将Properties对象中保存的字符串信息持久化,即存储到文件中。
方法概要:
void store(OutputStream out, String comments):以适合使用 load(InputStream) 方法加载到 Properties 表中的格式,将此 Properties 表中的属性列表(键和元素对)写入输出流。comments为属性列表的描述。
void store(Writer writer, String comments)
PropertiesDemo3.java
将集合中的数据输出到propertiesInfo.txt文件中。
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Properties;
public class PropertiesDemo3
{
public static void main( String[] args ) throws IOException
{
Properties prop = new Properties();
prop.setProperty( "zhangsan", "30" );
prop.setProperty( "lisi", "24" );
prop.setProperty( "wangwu", "35" );
prop.setProperty( "zhaoliu", "29" );
// 关联输出流
FileOutputStream foStream = new FileOutputStream(
"propertiesInfo.txt" );
// 将数据存储到文件中
prop.store( foStream, "name-age" );
foStream.close();
}
}
PropertiesDemo4.java
读取已保存在文件的数据,并输出。
PropertiesDemo4.java
import java.io.FileInputStream;
import java.io.IOException;
import java.util.Properties;
import java.util.Set;
public class PropertiesDemo4
{
public static void main( String[] args ) throws IOException
{
Properties prop = new Properties();
// 将数据文件读入集合中,必须要保证该文件中的数据是键值对
// 关联文件输入流
FileInputStream fiStream = new FileInputStream( "propertiesInfo.txt" );
// 读取文件输入流
prop.load( fiStream );
Set<String> names = prop.stringPropertyNames();
for( String name : names )
{
String age = prop.getProperty( name );
System.out.println( name + ":" + age );
}
fiStream.close();
}
}
PropertiesDemo5.java
对已有的配置文件中的信息进行修改。
PropertiesDemo5.java
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Properties;
public class PropertiesDemo5
{
public static void main( String[] args ) throws IOException
{
// 判断文件是否存在,不存在则创建,确保读取成功
File file = new File( "propertiesInfo.txt" );
if( !file.exists() )
{
file.createNewFile();
}
FileReader fReader = new FileReader( file );
Properties prop = new Properties();
prop.load( fReader );
prop.setProperty( "wangwu", "21" );
// 创建FileWriter对象会把file中的内容清空
FileWriter fWriter = new FileWriter( file );
prop.store( fWriter, "name-age" );
fReader.close();
fWriter.close();
}
}
PropertiesDemo6.java
综合练习:
需求:记录程序的使用次数,如果运行次数超过5次,则输出提示信息,并结束程序。
package properties;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Properties;
public class PropertiesDemo6
{
public static void main( String[] args ) throws IOException
{
getAppCounts();
}
public static void getAppCounts() throws IOException
{
File config = new File( "count.properties" );
if( !config.exists() )
config.createNewFile();
FileInputStream fiStream = new FileInputStream( config );
Properties prop = new Properties();
prop.load( fiStream );
String value = prop.getProperty( "times" );
int count = 0;
// 判断是否不是第一次使用
if( value != null )
{
count = Integer.parseInt( value );
// 判断使用次数是否大于等于5次
if( count >= 5 )
{
// 抛出异常,结束程序的运行
throw new RuntimeException( "使用次数已使用完毕,请开通会员,给钱!" );
}
}
count++;
System.out.println( "已经使用" + count + "次。尚余使用次数:" + (5 - count) + "次." );
prop.setProperty( "times", count + "" );
FileOutputStream foStream = new FileOutputStream( config );
prop.store( foStream, "" );
fiStream.close();
foStream.close();
}
}