-------android培训、java培训、期待与您交流! ----------
字节流转化成字符流
OutputStreamWriter:把字节输出流对象转成字符输出流对象
InputStreamReader:把字节输入流对象转成字符输入流对象
FileWriter和FileReader分别是OutputStreamWriter和InputStreamReader的直接子类,而不是Writer和Reader的直接子类
例子:
//构建字节输出流对象
OutputStream out = new FileOutputStream("");
//把字节输出流转成字符输出流
Writer w = new OutputStreamWriter(out);
//构建一个字节输入流对象
InputStream is = new FileInputStream("");
//把字节输入流转成字符输入流
Reader r = new InputStreamReader(is);
内存操作流
之前的文件操作流是以文件的输入输出为主的,当输出的位置变成了内存,那么就称为内存操作流。此时要使用内存流完成内存的输入和输出操作。
如果程序运行过程中要产生一些临时文件,可采用虚拟文件方式实现;
ByteArrayInputStream的构造方法:
public ByteArrayInputStream(byte[] buf):全部内容
public ByteArrayInputStream(byte[] buf,int offset,int length):指定范围的内容
ByteArrayOutputStream的构造方法:
public ByteArrayOutputStream()
例子:
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
public class ByteArrayDemo7 {
public static void main(String[] args) throws IOException {
String s = "hello heima";
ByteArrayOutputStream bos = new ByteArrayOutputStream();//输出流
bos.write(s.getBytes());
// 已经把信息写到了内存中
byte[] bys = bos.toByteArray();// 得到数据
ByteArrayInputStream bis = new ByteArrayInputStream(bys);//输入流,需要源。
byte[] b = new byte[1024];
int len;
while ((len = bis.read(b)) != -1) {
String data = new String(b, 0, len);
System.out.println(data);
}
}
}
package june6D;
import java.io.CharArrayReader;
import java.io.CharArrayWriter;
public class CharArrayDemo8 {
public static void main(String[] args) throws Exception {
// 用内存字符流先把数据保存到内存中,然后从内存中取出数据
String s = "hello workd";
CharArrayWriter cw = new CharArrayWriter();
cw.write(s);// 数据写到了内存中
char[] ch = cw.toCharArray();
CharArrayReader cr = new CharArrayReader(ch);
char[] b = new char[1024];
int len;
while ((len = cr.read(b)) != -1) {
String data = new String(b, 0, len);
System.out.println(data);
}
}
}
对象序列化
操作的对象为:ObjectInputStream与ObjectOutputStream
import java.io.*;
class ObjectStreamDemo {
public static void main(String[] args) {
}
public static void writeObj() {
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("obj.txt"));
}
}
RandomAccessFIle类
RandomAccessFile的唯一父类是Object,与其他流父类不同。是用来访问那些保存数据记录的文件的,这样你就可以用seek( )方法来访问记录,并进行读写了。这些记录的大
小不必相同;但是其大小和位置必须是可知的。
RandomAccessFile是不属于InputStream和OutputStream类系的。实际上,除了实现DataInput和DataOutput接口之外(DataInputStream和DataOutputStream也实现了这两个接
口),它和这两个类系毫不相干,甚至都没有用InputStream和OutputStream已经准备好的功能;它是一个完全独立的类,所有方法(绝大多数都只属于它自己)都是从零开始写
的。这可能是因为RandomAccessFile能在文件里面前后移动,所以它的行为与其它的I/O类有些根本性的不同。总而言之,它是一个直接继承Object的,独立的类。
例子:
import java.io.*;
class RandomAccessFileDemo {
public static void main(String[] args)throws IOException
{
//writeFile();
//readFile();
writeFile_2()
}
public static void readFile() throws IOException {
RandomAccessFile raf = new RandomAccessFile("ran.txt", "r");
// 调整对象指针
raf.seek(8);
// 跳过指定的字节数
raf.skipBytes(8);// 只能往前跳 不能往后跳
byte[] buf = new byte[4];
raf.read(buf);
String name = new String(buf);
int age = raf.readInt();
System.out.println("name=" + name);
System.out.println("age=" + age);
raf.close();
}
public static void writeFile_2() throws IOException {
RandomAccessFile raf = new RandomAccessFile("ran.txt", "rw");
raf.seek(8 * 3);
// raf.seek(8*0);//会对数据进行覆写
raf.write("周期".getBytes());
raf.writeInt(103);
raf.close();
}
public static void writeFile() throws IOException {
RandomAccessFile raf = new RandomAccessFile("ran.txt", "rw");
raf.write("李四".getBytes());
// raf.write(258);//write只写出最低八位,超出八位的话会数据丢失
raf.writeInt(97);// writeInt(int v) 按四个字节将 int 写入该文件,先写高字节
raf.write("王五".getBytes());
raf.writeInt(99);
raf.close();
}
}
打印流:PrintWriter和PrintStream
打印流有非常好的打印功能,可以打印任何的数据类型。如,整数,小数,字符串等
PrintStream类的构造:
public PrintStream(File file) throws FileNotFoundException
public PrintStream(OutputStream out)
实例化的时候依然需要传入一个OutputStream的对象。
PrintWriter和PrintStream都属于输出流,分别针对字符和字节。
PrintWriter和PrintStream重载的print()和println()用于多种数据类型的输出。
print()里的参数不能为空;println()可以
PrintWriter和PrintStream输出操作不抛出异常
PrintStream调用println方法有自动flush功能;
例子:
import java.io.FileWriter;
import java.io.PrintStream;
import java.io.PrintWriter;
public class PrintDemo9 {
public static void main(String[] args) throws Exception {
PrintStream ps = new PrintStream("out.txt");
// ps.write(12);
ps.println(10086);
ps.println(false);
ps.println();// 此时就可以
ps = System.out;
ps.println("hello!");// 控制台操作,注意上一句
// 字符打印流
PrintWriter pr = new PrintWriter("out2.txt");
// PrintWriter(OutputStream out, boolean autoFlush) 通过现有的 OutputStream,创建新的 PrintWriter。(构造方法)
pr = new PrintWriter(new FileWriter("out2.txt"), true);// 自动刷新,否则的话需要关闭资源!
// 与PrintStream不同,若PrintWriter使用了自动刷新方法,那么必须调用println,print,format这些方法的其中一个才可以实现操作
pr.println("hello world");
pr.println(false);
pr = new PrintWriter(System.out, true);// 打印在控制台上
pr.println(false);
pr.println("nihaoya");
pr.println(374822);
// pr.close();//因为使用了自动刷新。
}
}
缓冲流
缓冲流要“套接”在相应的节点流之上,对读写的数据提供了缓冲的功能,提高了读写效率,同时增加了一些新的方法。
四种缓冲流
BufferedReader(Reader in)
BufferedReader(Reader in,int sz)//sz表示自定义缓冲区大小
BufferedWriter(Writer out)
BufferedWriter(Writer out,int sz)
BufferedInputStream(InputStream in)
BufferedInputStream(InputStream in,int sz)
BufferedOutputStream(OutputStream out)
BufferedOutputStream(OutputStream out,int sz)
BufferedReader提供readLine方法用于读取一行字符串。
BufferedWriter提供了newLine方法用于写入一个行分隔符。等价于//.writer("\r\n");
对于输出的缓冲流,写出的数据会先在内存中缓冲,使用flush方法将会使内存中的数据立刻写出。
例子:
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
//用缓冲流,性能相对高些
public class BufferedInputStreamDemo22 {
public static void main(String[] args) throws IOException {
/*
* BufferedInputStream bis = new BufferedInputStream(new
* FileInputStream("68.txt")); BufferedOutputStream bos = new
* BufferedOutputStream(new FileOutputStream("buffer.txt"));
*
* int len = 0;
* while((len = bis.read()) != -1){
* bos.write(len);
* }
* bos.close();
* bis.close();
*/
try (
BufferedReader br = new BufferedReader(new FileReader("68.txt"));
BufferedWriter bw = new BufferedWriter(new FileWriter(
"bufferWriter.txt")))
{//java7新特性,自动关闭资源
String Line = null;
while ((Line = br.readLine()) != null) {
bw.write(Line);
bw.newLine();//此时必须加上换行操作,注意这是个新用法(方法)
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
合并流:SequenceInputStream
将两个文件的内容合并成一个文件
该类提供的方法:
SequenceInputStream(InputStream s1, InputStream s2) :根据两个字节输入流对象来创建合并流对象。
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.SequenceInputStream;
//和并两个文件的合并流
public class SequenceInputStreamDemo24 {
public static void main(String[] args) throws IOException {
SequenceInputStream si = new SequenceInputStream(
new FileInputStream("hello"),
new FileInputStream("world!"));
OutputStream ost = new FileOutputStream("sequence.txt");
int len;
byte []b = new byte[1024];
while((len = si.read(b)) != -1){
ost.write(b, 0, len);
}
}
}
切割文件
import java.io.*;
import java.util.*;
class SplitFile {
public static void main(String[] args) {
// splitFile();
merge();
}
public static void merge()
{
ArrayList<FileInputStream> al = new ArrayList<FileInputStream>();
for(int x=1;x<=5;x++)
{
al.add(new FileInputStream("e:\\Java练习\\"+(x++)+".part"))
}
Iterator it = al.iterator();
Enumeration<FileInputStream> en = new Enumeration<FileInputStream>()
{
public boolean hasMoreElements()
{
return it.hasNext();
}
public FileInputStream nextElement()
{
return it.next();
}
};
SequenceInputStream sis = new SequenceInputStream(en);
FileOutputStream fos = new FileOutputStream("e:\\Java练习\\1.mp3");
byte[] buf = new byte[1024];
int len = 0;
while((len=sis.read())!=-1)
{
fos.write(buf,0,len)
}
fos.close();
sis.close();
}
public static void splitFile()
{
FileInputStream fis = new FileInputStream("e:\\Java练习\\0.mp3");
FileOutputStream fos = null;
byte[] buf = new byte[1024*1024];
int len = 0;
int x = 1;
while((len=fis.read(buf))!=-1)
{
fos = new FileOutputStream("e:\\Java练习\\"+(x++)+".part")
fos.write(buf,0,len);
fos.close();
}
fis.close();
}
}
“联通问题”
class EncodeDemo2 {
public static void main(String[] args) {
String s = "联通";
byte[] by = s.getBytes("gbk");
for (byte b : by) {
System.out.println(Integer.toBinaryString(b & 255));
}
}
}
编码
字符流的出现为了方便操作字符,本质上就是对字节流进行了编解码的操作
主要通过下面子类转换流来完成:InputStreamReader 和OutputStreamWriter
在两个对象进行构造的时候可以加入字符集
计算机只能识别二进制数据,为了方便应用计算机,让它可以识别各个国家的文字,就将各个国家的文字用数字来表示,并一一对应,形成一张表,这就是编码表
常见的编码表
ASCII:美国标准信息交换码。 用一个字节的7位可以表示
ISO08859-1:拉丁码表。欧洲码表
GBK/GB2312:中文国际编码,专门用来表示汉字
Unicode:java中使用此编码方式,是最标准的一种编码
UTF-8:最多用三个字节来表示一个字符
例子:
import java.io.*;
class EncodeStream {
public static void main(String[] args) throws IOException {
writeText();
}
public static void readText() throws IOException {
InputStreamReader isr = new InputStreamReade(new FileInputStream("gbk.txt"), "gbk");
char[] buf = new char[10];
int len = isr.read(buf);
String str = new String(buf, 0, len);
System.out.println(str);
isr.close();
}
public static void writeText() throws IOException {
OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("gbk.txt"), "gbk");
OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("utf.txt"), "UTF-8");
osw.write("你好");
osw.close();
}
}