1. 国际化程序实现
对于国际化程序,主要是能够在各个国家使用,功能基本上不会变化,变化的是语言,就是语言要国际化。
一般配置多个资源文件,资源文件用来配置语言的内容,一般配置文件都用.properties文件。
读取资源文件的信息使用java.util.ResourceBundle类,这是一个抽象类,但是这个类的内部提供一个Static方法,用来取得本对象.
根据当前语言环境取出:public static final ResourceBundle getBundle(String baseName);
设置指定语言:public static final ResourceBundle getBundle(String baseName,Locale locale);
代码如下:
public class NativeClassTest {
public static void main(String[] args) throws Exception {
ResourceBundle sb = ResourceBundle.getBundle("messages");
System.out.println(sb.getString("gys"));
String str = new String(sb.getString("info").getBytes("ISO-8859-1"),"GBK");
System.out.println(MessageFormat.format(str,"gys",new SimpleDateFormat("yyyy-MM-dd").format(new Date())));
}
}
对应的messages.properties中的内容如下:
gys=kljdlkjfkldjklfjdkl
info=你好啊{0},今天日期是:{1}
1.1 Locale类使用
Locale类是用来设置语言类,通过获取当前的语言环境来设置语言类,主要方法有:
- 构造方法:public Locale(String language,String country);
- 取得当前语言环境 :public static Locale getDefault();
2. 文件操作类的概念及使用
对于文件操作,在JAVA编程中相对较难的一部分,主要涉及以下内容:
- 五个核心类:File、InputStream、OutputStream、Reader、 Writer;
- 一个核心接口:Serializable;
其中File类是操作文件的类,是对文件本身进行操作。
如果想要使用File类,那么首先就需要通过它提供的构造方法定义一个要操作文件的类,主要方法有- 设置完整路径:public File(String pathName);大部分情况下使用此类操作
- 设置父路径与子文件路径:public File(File parent,String child);这个在Android上使用较多
2.1 文件操作类
- 创建文件:public boolean createNewFile() throws IOException;
- 删除文件:public boolean delete();
- 判断文件是否存在:public boolean exists();
注意:在文件分隔符,在Windows下使用"",而Linux下使用的是“/”,做为路径分隔符。
在FIle类里面提供有一个分隔符常量:public static final String separator;
如下代码:
public class FileTestClass {
public static void main(String[] args) throws Exception {
File file = new File("d:" + File.separator +"test.txt");
if (file.exists()){
file.delete();
}else{
System.out.println(file.createNewFile());
}
}
}
在JAVA的IO操作时,会出现延迟情况,因为现在的问题是JAVA间接调用 JVM,调用操作系统处理文件的方法,所以中间会出现延迟。
- 找到父路径:public File getParentFile();
- 创建目录:public boolean mkdirs();
代码如下:
public class FileTestClass {
public static void main(String[] args) throws Exception {
File file = new File("d:" + File.separator +"demo"+File.separator+"tset"+File.separator+"gysh"+File.separator+"test.txt");
if ( !file.getParentFile().exists() ){
file.getParentFile().mkdirs();
}
if(file.exists()) {
file.delete();
}else
{
System.out.println(file.createNewFile());
}
}
}
在File类里面还提供有一系列的取得文件信息内容的操作功能:
- 取得文件大小:public long length(); 按照字节返回
- 判断是否是文件:public boolean isFile();
- 判断是否是目录 :public boolean isDirectory();
- 最近一次修改日期:public long lastModified(); 返回的是long型的日期,需要通过Date构造方法的来设置。
以上所有操作是围绕文件进行的,但是在整个磁盘上除了文件之后,还有我们使用的目录,对于目录而言,最常用的功能是列出目录组成: - 列出目录下的信息:public String[] list();只列出目录或者文件名称
- 列出所有的信息,以File类进行包装:public File[] listFile(); 这个列出目录下面的所有文件的信息,都是绝对路径。
代码如下
public class DirectoryTestClass {
public static void main(String[] args) throws Exception{
File file = new File("D:"+File.separator+"03EBook");
print(file);
}
//通过递归的方式,展示给定目录下所有文件的信息(绝对路径)
public static void print(File file){
if (file.isDirectory()){
File result[] = file.listFiles();
if(result!=null){
for (int i = 0; i < result.length; i++) {
print(result[i]);
}
}
}
System.out.println(file);
}
}
总结:
- File类只是对文件进行操作,而不对内容进行操作。
- 目录分割符一定要用File.separator
2.2 内容操作(字节流、字符流)
如果要进行输入、输出操作一般都会按照如下步骤进行(以文件操作为例):
- 通过File类定义一个要操作文件的路径
- 通过字节流或字符流的子类对象为父类对象实例化
- 进行数据的读、写操作
- 数据流属于资源操作,资源操作必须关闭
对于JAVA.iO包中定义两种流: - 字节流:InputStream、OutputStream
- 字符流:Reader、Writer
2.2.1 字节输出流:OutputStream
OutputStream是一个专门进行字节数据输出的一个类,这个类定义如下:
public abstract class OutputStream extends Object implements Closeable,Flushable;
从上面代码中它实现了两个接口:Closeable、Flushable。
其中Closeable接口:
public interface Closeable extends AutoCloseable{
public void close() throws IOException;
}
从上面可以看出:接口可以继承接口;
public interface Flushable{
public void flush() throws IOException;
}
在OutputStream类中提供了三个输出方法:
- 输出单个字节:public abstract void write(int b) throws IOException;
- 输出全部字节:public abstract void write(byte[] b) throws IOException;
- 输出部分字节:public abstract void write(byte[] b ,int off,int len) throws
IOExcetion;
OutputStream是一个抽象类,需要通过子类进行实例化操作,一般情况下使用较多的是FileOutputStream对象; - 创建或覆盖已有文件:public FileOutputStream(File file) throws FileNotFoundException;
- 文件内容追加:public FileOutputStream(File file,boolean append) throws FileNotFoundException;
代码如下:
public class OutputStreamTestClass {
public static void main(String[] args) throws Exception{
File file = new File("d:"+File.separator+"test.txt");
if (!file.getParentFile().exists()){
file.getParentFile().mkdirs();
}
FileOutputStream fileOutput = new FileOutputStream(file);
String str = "你好啊,整个世界!";
byte[] bStr = str.getBytes();
//采用字节数组进行输出
//fileOutput.write(bStr);;
//采用单个字节进行输出
for (int i = 0; i < bStr.length; i++) {
fileOutput.write(bStr[i]);
}
//采用部分数据输出
//fileOutput.write(bStr,6,6);//一个汉字占用两个字节
fileOutput.close();
}
}
2.2.2 字节输入流:InputStream
如果程序需要进行读取操作,可以利用InputStream类实现此功能,
public abstract class InputStream extends Object implements Closeable;
这个不与OutputStream一样,不需要考虑Closeable这个接口的存在,还是需要手动去操作关闭。
InputStream主要的方法如下:
- 读取单个字节:public abstract int read() throws IOException;
- 将读取的数据保存在字节中:public int read(byte[] b) throws IOException;
- 将读取的数据保存在部分字节数组里:public int read(byte[] b,int off,int len) throws IOException;
Inputstream是一个抽象类,需要使用它对应的子类来实例化,对于文件读取,我们经常使用FileInputStream子类,代码如下:
public class InputStreamTestClass {
public static void main(String[] args) throws IOException {
File file = new File("d:"+File.separator+"test.txt");
FileInputStream fileInput = null;
if(file.exists()){
fileInput = new FileInputStream(file);
}
byte[] b = new byte[1024];
int len = fileInput.read(b);
fileInput.close();
System.out.println("["+new String(b,0,len)+"]");
}
}
2.2.3 字符输出和输入流(Reader、Writer)
Writer类:
public abstract class Writer extends Object implements Appendable,Closeable,Flushable;
Writer也是一个抽象类,需要有子类进行实例化,一般情况下使用FileWriter子类,它比OutputStream类多实现了一个接口,这个接口主要的方法有:
public interface Appendable{
public Appendable append(char c) throws IOException;
public Appendable append(CharSequence csq) throws IOException;
public Appendable append(CharSequence csq,int start,int end) throws IOException;
}
Appendable主要是追加字符或者字符串。
对于Writer类来说,主要功能如下:
- 输出全部字符数组:public void write(char[] cbuf) throws IOException;
- 输出字符串:public void write(String str) throws IOException;
对于Reader与InputStream基本一样,不在详细说明。
2.2.4 字节流与字符流的区别
- 字节流是直接与终端进行交互,而字符流需要经过缓冲区处理之后才能与终端交流
- 在使用OutputStream输出数据时,即使最后没有关闭输出流,那么内容也可以正常输出,如果使用的字符输出流,如果没有关闭,表示在缓冲区中处理的内容不会被强制性清空,不能正常输出,但是有一种特殊情况,不关闭输出流的情况,可以使用flush()方法可以强制清空缓冲区。
- 对于字节数据处理的比较多,例如:图片、音乐、视频、文字等,可以处理中文数据。
- 在处理中文相关的数据时,建议优先考虑使用字节流。
2.2.5 字节流与字符流之间转换
在java.io包里面提供有两个类:InputStreamReader、OutputStreamWriter两个转换类。
public class OutputStreamTestClass {
public static void main(String[] args) throws Exception{
File file = new File("d:"+File.separator+"test.txt");
if (!file.getParentFile().exists()){
file.getParentFile().mkdirs();
}
OutputStream fileOutput = new FileOutputStream(file);
Writer out = new OutputStreamWriter(fileOutput);
out.write("习主席万岁!!!");
out.flush();
out.close();
/* String str = "你好啊,整个世界!";
byte[] bStr = str.getBytes();
//采用字节数组进行输出
//fileOutput.write(bStr);;
//采用单个字节进行输出
for (int i = 0; i < bStr.length; i++) {
fileOutput.write(bStr[i]);
}
//采用部分数据输出
//fileOutput.write(bStr,6,6);//一个汉字占用两个字节*/
fileOutput.close();
}
}
3 字符编码
计算机中所有的信息组成都是二进制数据,那么如果需要描述出中文字符的需要进行编码处理,所有的语言都要通过使用编码来进行描述,那么在计算机语言中常见的编码如下
- GBK、GB2312:中文的国标编码,其中GBK包含有简体和繁体中文,GB2312只包含简体。
- ISO8859-1:是国际编码,可以描述任何的文字信息
- UNICODE:是十六进制编码,造成传输时,无用数据过多,占用较大带宽
- UTF编码(UTF-8):融合了ISO8859-1和UNICODE编码的特点
在以后 的软件开发过程中,使用的都是UTF-8编码。
所谓的乱码最本质的方式就是编码与解码的字符集不统一。
4 内存流
我们可以使用内存流实现IO操作。在字节、字符输入与输出流中讲解了对文件数据的输入与输出的操作,如果我们只是对数据操作,又不想产生文件,我们就可以利用内存流实现输入与输出的操作。
针对内存流,JAVA中提供了两组操作:
- ByteArrayInputStream
- ByteArrayOutputStream
- CharArrayWriter
- CharArrayReader
下面主要讲解ByteArrayInputStream与ByteArrayOutputStream
什么是输出与输入:
以文件操作为例:是把文件当做终端 - 输出(OutputStream):程序-》OutputStream-》文件
- 输入(InputStream):程序《-InputStream《-文件
以内存操作为例:是把程序当做终端 - 输出(InputStream):程序-》InputStream-》内存
- 输入(OutputStream):程序《-OutputStream《-内存
代码如下:
public class MemoryStreamClass {
public static void main(String[] args) throws Exception{
String str = "Hello,World!!";
InputStream input = new ByteArrayInputStream(str.getBytes());
OutputStream output = new ByteArrayOutputStream();
int temp =0;
while ((temp = input.read()) != -1){
output.write(Character.toUpperCase(temp));
}
System.out.println(output);
input.close();
output.close();
}
}
对于ByteArrayOutputStream类中有一个方法能把内存中的数据转变成字节数组:
public byte[] toByteArray();
代码如下:
public class ToByteArrayTest {
public static void main(String[] args) throws Exception {
File fileA = new File("D:"+File.separator+"test.txt");
File fileB = new File("D:"+File.separator+"testB.txt");
InputStream fileinputA = new FileInputStream(fileA);
InputStream fileInputB = new FileInputStream(fileB);
ByteArrayOutputStream out = new ByteArrayOutputStream();
int temp = 0;
while((temp = fileinputA.read()) != -1){
out.write(temp);
}
while((temp = fileInputB.read())!= -1){
out.write(temp);
}
//通过下面的能够把两个文件的内容进行合并,并输出
byte b[] = out.toByteArray();
System.out.println(new String(b));
fileinputA.close();
fileInputB.close();
out.close();;
}
}
5 打印流
主要讲解打印流的实现原理以及打印流的操作类的使用,打印流在JAVA开发中是非常重要的一部分。
为了解决输出数据,能够输出各中格式,JAVA中提供了一个专门用来输出数据的类,分别是PrintStream、PrintWriter
- PrintStream是用来打印字节流;
- PrintWriter是用来打印字符流:
PrintStream是基于OutputStream类设计而成的,通过对OutputStream进行包装(装饰模式)来完成的。
代码如下:
public class PrintStreamClass
{
public static void main(String[] args) throws Exception{
File file = new File("d:"+File.separator+"test.txt");
PrintStream ps = new PrintStream(new FileOutputStream(file));
ps.print(false);
ps.println();;
ps.println(23);
ps.println(23.45);
ps.println("你好!");
}
}
在以后开发过程中,如果有程序输出模式,都会采用 打印流的模式,一定要知道打印流也是基于OutputStream的类完成实现功能。
打印流是在JDK1.5之后,进行设计 ,被称为格式化输出:public PrintStream printf(String format,Object … args);
6 System类对IO的支持
在System类里面为了支持IO操作专门提供有三个常量:
- 错误输出:public static final PrintStream err;
- 输出到标准输出设备(显示器):public static final PrintStream out;
- 从标准输入设备读取数据:public static final InputStream in;
其中:
System.err这个不经常使用,它和System.out中的功能是一样的。
System.in
public class SystemInClass {
public static void main(String[] args) throws Exception {
InputStream input = System.in;
byte[] b = new byte[1024];
System.out.print("请输入数据:");
int len = input.read(b);
System.out.println("输入的数据是:"+new String(b,0,len));
}
}
7 缓冲流
如果要进行中文数据处理,首先我们会使用字符流,并且要完整的处理数据,需要利用缓冲区的操作,在JAVA中对缓冲区操作有两种流:
- 字符缓冲区流:BufferedReader、BufferedWriter
- 字节缓冲区流:BufferedInputStream、BufferedOutputStream
其中在BufferedReader类是非常重要,是因为它提供了一个重要的方法:public String readLine() throws IOException;
代码如下:
public class BufferedReaderTest {
public static void main(String[] args) throws IOException {
//通过转换流把字节流转换到字符流
BufferedReader buffer = new BufferedReader(new InputStreamReader(System.in));
System.out.print("请输入数据:");
String str = buffer.readLine();
System.out.println("数据输入的内容是:"+str);
}
}
结合正则表达式来判断输入数据是否为年龄数字,代码如下:
public class RegexStreamTest {
public static void main(String[] args) throws IOException {
BufferedReader buffer = new BufferedReader(new InputStreamReader(System.in));
boolean flag = true;
while (flag){
System.out.println("请输入年龄数据:");
String str = buffer.readLine();
if(str.matches("\\d{1,3}")){
System.out.println("年龄是:"+Integer.parseInt(str));
flag =false;
}else
{
System.out.println("输入的年龄数据是错误的!");
}
}
}
}
利用BufferReader也可以对文件进行读取,一行一行的读取。
读取数据不再直接使用InputStream,就好比不使用OutputStream一样。
8 扫描流
主要讲解Scanner类的主要特点以及操作形式,利用Scanner来解决数据输入流的操作。
对于改进输出流的不足提供了打印流,对于文件内容行读取,又提供了BufferedReader类,解决了读取大文件的问题。
那么如何解决输入的功能不足:主要由Scanner提供,这个类在java.util包中,真正解决所有的输入流的一个工具。
Scanner类的构造方法:public Scanner(InputStream source);接收一个InputStream输入流。
JAVA在Scanner类中定义了两组方法:
- 判断是否有指定数据:public boolean hasNextXxx();
- 取出数据:public String nextXxx();
代码如下:
public class ScannerTest {
public static void main(String[] args) {
Scanner s = new Scanner(System.in);
while (s.hasNext()){
System.out.println(s.next());
}
s.close();
}
}
Scanner类结合正则表达式,能够判断输入数据的格式 ,代码如下:
public class ScannerTest {
public static void main(String[] args) {
Scanner s = new Scanner(System.in);
/* while (s.hasNext()){
System.out.println(s.next());
}*/
System.out.print("请输入生日:");
if(s.hasNext("\\d{4}-\\d{2}-\\d{2}")){
String str = s.next("\\d{4}-\\d{2}-\\d{2}");
System.out.println("输入内容:"+str);
}else{
System.out.println("输入的不是数字,错误!!");
}
s.close();
}
}
总结
- InputStream类的功能不足,已经被Scanner类解决了
- Reader类的功能不足被BufferReader解决
- OutputStream类的功能不足被PrintStream解决了
- Writer类的功能不足被PrintWriter解决了
对于JAVA高级语言有关JDBC、集合、网络编程,请看续集:JAVA高级语言重要概念以及重要的类之三(网络编程、对象序列化、集合、JDBC等)