InputStreamReader
public InputStreamReader(InputStream in):用默认的编码读取数据字节流转换为字符输入流
OutputStreamWriter
public OutputStreamWriter(OutputStream out):根据默认编码把字节流的数据转换为字符流
import java.io.*;
//将字节输入流转换为字符读取流
public class InputStreamReaderTest {
public static void main2(String[] args) throws Exception {
// 将字节输出流转换为字符输出流
File file = new File("F://test/test.txt");
FileOutputStream fos = new FileOutputStream(file, true);
BufferedOutputStream bos = new BufferedOutputStream(fos);
//OutputStreamWriter osw=new OutputStreamWriter(bos);//默认编码
OutputStreamWriter osw=new OutputStreamWriter(bos, "GB2312");
BufferedWriter bw=new BufferedWriter(osw);
// bos.write("你好".getBytes());
// bos.flush();
// bos.close();
bw.newLine();
bw.write("你好3");
bw.flush();
bw.close();
}
public static void main(String[] args) throws Exception {
File file = new File("F://test/test.txt");
FileInputStream fis = new FileInputStream(file);
BufferedInputStream bis = new BufferedInputStream(fis);
// 将字节流转换为字符流
// InputStreamReader isr=new InputStreamReader(bis);//使用默认编码进行操作
InputStreamReader isr = new InputStreamReader(bis, "GB2312");
// 注意:编码为文件编码 为了正确的将文件数据为字节转换字符
BufferedReader br = new BufferedReader(isr);
// int len = 0;
// byte[] b = new byte[1024];
// len = bis.read(b);
// System.out.println(new String(b, 0, len));
// bis.close();
System.out.println(br.readLine());
System.out.println(br.readLine());
System.out.println(br.readLine());
System.out.println(br.readLine());
System.out.println(br.readLine());
br.close();
}
}
字符集
字符(Character)是各种文字和符号的总称,包括各国家文字、标点符号、图形符号、数字等。字符集(Character set)是多个字符的集合,字符集种类较多,每个字符集包含的字符个数不同,常见字符集名称:ASCII字符集、GB2312字符集、BIG5字符集、 GB18030字符集、Unicode字符集等。计算机要准确的处理各种字符集文字,需要进行字符编码,以便计算机能够识别和存储各种文字。中文文字数目大,而且还分为简体中文和繁体中文两种不同书写规则的文字,而计算机最初是按英语单字节字符设计的,因此,对中文字符进行编码,是中文信息交流的技术基础。
打印流
只有输出的流,无论是否成功,无论是否出现异常都会正常执行
特点:
只有输出目的地
不会出现io异常
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintStream;
import java.io.PrintWriter;
//打印流
public class PrintTest {
// 只会将指定内容输出至目的地
public static void main(String[] args) throws IOException {
// 字符打印流
// PrintWriter pw=new PrintWriter(file)
// PrintWriter pw=new PrintWriter(fileName)
// PrintWriter pw=new PrintWriter(out);//使用指定字符输出流输出文件作为输出
// PrintWriter pw = new PrintWriter(out, autoFlush);//自动刷新输出后自动刷新缓存区
File f = new File("F://test/test1.txt");
FileWriter fw = new FileWriter(f, true);
PrintWriter pw = new PrintWriter(fw);
pw.append("数据1");
pw.println("数据2");// 打印并换行
pw.write("数据3");
pw.flush();
pw.close();
}
public static void main1(String[] args) throws Exception {
// 字节打印流
// 以字节的形式进行内容的输出
// PrintStream ps=new PrintStream(file);//使用指定文件对象作为输出
// PrintStream ps=new PrintStream(fileName);//使用指定文件路径创建对象作为输出
// PrintStream ps=new PrintStream(out);//使用指定字节输出流输出文件作为输出
// PrintStream ps = new PrintStream(out, autoFlush);//自动刷新输出后自动刷新缓存区
File f = new File("F://test/test.txt");
FileOutputStream fos = new FileOutputStream(f, true);
PrintStream ps = new PrintStream(fos);
// ps.print("打印数据不换行");
// ps.println("打印数据并换行");
ps.append("追加打印");// 在当前打印的基础上继续打印与print功能相似
ps.write("数据".getBytes());// 将字节数组写入
ps.flush();
ps.close();
}
}
对象序列化
对象序列化的目标是将对象保存到磁盘中,或允许在网络中直接传输对象。对象序列化机制允许把内存中的Java对象转换成平台无关的二进制流,从而允许把这种二进制流持久地保存在磁盘上,通过网络将这种二进制流传输到另一个网络节点。其他程序一旦获得了这种二进制流,都可以将这种二进制流恢复成原来的Java对象。
对象序列化机制(object serialization)是Java语言内建的一种对象持久化方式,通过对象序列化,可以把对象保存为字节数组,这些字节数组可以保存在磁盘上,或通过网络传输。在有需要的时候将这个字节数组通过反序列化的方式再转换成对象。对象序列化可以很容易的在JVM中的活动对象和字节数组(流)之间进行转换。
在Java中,对象的序列化与反序列化被广泛应用到RMI(远程方法调用)及网络传输中。通常建议:程序创建的每个javabeen都实现Serializable接口
对象序列化
构造方法
ObjectOutputStream(out)
使用字节输出流输出序列化数据
常用方法
void writeObject(obj)
将对象转换为二进制数字并输出至指定位置
ObjectInputStream
对象反序列化
构造方法
new ObjectInputStream(in)
使用字节输入流创建反序列化对象读取指定文件
常用方法
Object readObject()
读取指定文件将文件中二进制流转换为对象(需要强制转换后才能使用原对象方法)
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.ArrayList;
import java.util.Collections;
//对象序列化与反序列化
public class SerializableTest {
public static void m1(String[] args) throws IOException {
// 序列化
// 将对象转换为二进制流的形式进行存储与网络传输
// 1准备创建一个要进行序列化的对象(必须实现Serializable序列化接口)
ArrayList<String> arr = new ArrayList<>();
Collections.addAll(arr, "a", "b", "c", "d");
// 2创建对象序列化对象
FileOutputStream fos = new FileOutputStream("F://test/object.txt");
ObjectOutputStream oos = new ObjectOutputStream(fos);
// 3将对象以流的形式输出
oos.writeObject(arr);
oos.flush();
oos.close();
}
public static void main(String[] args) throws Exception {
// 反序列化
// 1准备获取对象二进制流的输入流
FileInputStream fis = new FileInputStream("F://test/object.txt");
// 创建反序列化对象
ObjectInputStream ois = new ObjectInputStream(fis);
// 将读取数据以流的形式返回
ArrayList<String> readObject = (ArrayList<String>) ois.readObject();
System.out.println(readObject);
}
}
reader方法只能读取一个对象,切返回Object类型,在序列化时不要将多个对象存储至相同文件
被序列化的对象必须实现序列化接口
properties配置文件
Properties文件是java中很常用的一种配置文件,文件后缀为“.properties”,属文本文件,文件的内容格式是“键=值”的格式,可以用“#”作为注释,java编程中用到的地方很多,运用配置文件,可以便于java深层次的解耦。例如java应用通过JDBC连接数据库时,进行log4j的使用时.
#properties配置文件是一种文本文件不要出现中文字符
#默认编码iso-8859-1
#使用#进行单行注释(只有单行注释)
#配置存储数据形式 key=value
#注意:value后不要书写空格(否则空格可能被当做数据获取)
username=password
zhangsan=123456
lisi=123456
properties数据获取
1、使用类加载器classload、properties类进行读取
类加载器:在程序运行时用于加载类进行类初始化加载的工具,在项目运行时对类进行预加载(不会调用静态代码块) 将我们书写的class文件放到jvm中
// 使用类加载器、properties类进行properties配置文件的读取
//使用当前类获取类加载器
ClassLoader classLoader = PropertiesTest.class.getClassLoader();
//使用类加载器将指定properties配置文件解析为输入流
InputStream is = classLoader.getResourceAsStream("com/yunhe/day1102/my.properties");
//创建properties配置类
Properties p=new Properties();
//使用properties配置类加载输入流
p.load(is);
//当加载完相应输入流后,会自动进行解析
//使用getProperty方法获取指定key对应value
//String property = p.getProperty("zhangsan");
String property = p.getProperty("zhangsan","默认值");//当没有指定key时返回默认值
System.out.println(property);
优点:
类加载器可以直接加载当前项目根目录下的配置文件,如果配置文件存放在包下则包之间使用/进行分割,使用包名/包名/文件名.后缀进行读取
// 使用输入流inputStream、properties类进行读取
FileInputStream fis = new FileInputStream("F://teacher/javacore/JavaLogic/src/my.properties");
// 创建properties配置类
Properties p = new Properties();
// 使用properties配置类加载输入流
p.load(fis);
// 当加载完相应输入流后,会自动进行解析
// 使用getProperty方法获取指定key对应value
// String property = p.getProperty("zhangsan");
String property = p.getProperty("zhangsan1", "默认值");// 当没有指定key时返回默认值
System.out.println(property);
优点:
可以加载任意位置的配置文件
// ResourceBundle抽象类静态方法进行读取
ResourceBundle bundle = ResourceBundle.getBundle("com/yunhe/day1102/my");
//默认读取src下properties配置文件可以省略后缀
String string = bundle.getString("zhangsan");//properties配置文件数据就是字符串
System.out.println(string);
优点:
内置方法进行配置文件的读取,省略了配置文件后缀的书写
// 使用类加载器classload、ResourceBundle子类PropertyResourceBundle进行读取
// 使用当前类获取类加载器
ClassLoader classLoader = PropertiesTest.class.getClassLoader();
// 使用类加载器将指定properties配置文件解析为输入流
InputStream is = classLoader.getResourceAsStream("my.properties");
// 使用相应配置文件的输入流创建PropertyResourceBundle对象
PropertyResourceBundle prb = new PropertyResourceBundle(is);
String string = prb.getString("zhangsan");
System.out.println(string);
这种形式不建议使用,与使用properties类进行读取差别不大,而且没有使用ResourceBundle直接读取方便
// 使用输入流inputStream、ResourceBundle子类PropertyResourceBundle进行读取
//使用文件字符输入流读取配置文件
FileInputStream fis=new FileInputStream(new File("F://teacher/javacore/JavaLogic/src/my.properties"));
//创建propertyResourceBundle对象进行读取
PropertyResourceBundle prb=new PropertyResourceBundle(fis);
System.out.println(prb.getString("lisi"));
根据配置文件位置,以及读取方式不同分为以下几类
配置文件在类路径下:classload类加载器
配置文件在类路径外:inputStream输入流
properties类进行load方法进行读取
ResourceBundle抽象类静态方法bundle方法进行读取
ResourceBundle子类PropertyResourceBundle构造方法进行读取
注意:
1、无论配置文件在哪里都可以使用输入流进行获取,无论使用哪种方法进行获取properties类与PropertyResourceBundle类都是使用流进行读取(需要获取输入流),ResourceBundle可以直接通过方法获取配置文件数据
2、使用类加载器获取类路径下配置文件可以直接使用配置文件全名(my.properties),如果使用ResourceBundle进行读取,省略后缀,如果配置文件在相应包中则使用/进行分割指定包下的配置文件
练习
创建累实现序列化接口,进行序列化存储至文件,书写方法获取指定对象并修改内容继续存储
扩展
搜索字符集编码unicode、utf-8、gbk、ascii字符分别所占字节数
使用序列化持久保持登录注册信息
思考log4j的书写格式(使用IO、properties简单模拟log4j的书写)
读取properties配置文件,使用hashmap进行存储后序列化保持至文件中
//获取所有key的列表对象
Enumeration<String> keys = prb.getKeys();
//是否存在key元素
while(keys.hasMoreElements()){
//获取下一个key元素对象
System.out.println(keys.nextElement());
}
注意:本文归作者所有,未经作者允许,不得转载