IO
打印流-----输出流
- PrintStream(字节流) . PrintWriter(字符流)
- 特点:打印,不抛异常
- 打印目的:file对象,字符串路径,字节输出流
- 保证数值的表现形式不变,写的是什么样子,目的就是就是什么样子
//printStream演示
public static void printStream() throws IOException {
PrintStream ps= new PrintStream("E:\\a.txt");
ps.write(97);
ps.print(97);
ps.close();
}
//读取键盘录入,将数据转成大写显示在控制台
public static void printWriter() throws IOException {
//键盘录入
BufferedReader bfr=new BufferedReader(new InputStreamReader(System.in));
//输出目的
PrintWriter pw=new PrintWriter(System.out,true);//加上true可以自动刷新
// BufferedWriter bfw=new BufferedWriter(new OutputStreamWriter(System.out));
String line=null;
//读一行写一行,定义键盘录入结束标记
while ((line=bfr.readLine())!=null){
if (line.equals("over")){
break;
}
pw.println(line.toUpperCase());
}
bfr.close();//后面如果不使用就close
pw.close();
}
序列流(多个源合并一个目的)
- 流对象有序排列
- 解决问题 : 将多个输入流合并成一个输入流, 将多个源合并成一个源
- 功能: 特殊之处在构造函数上, 一初始化就合并了多个流进来
- 使用场景之一:对多个文件的数据进行合并,多个源对应一个目的
public static void sequence() throws IOException {
//将创建的输入流对象存入到集合中
List<InputStream> al=new ArrayList<>();
for (int i=1;i<=3;i++){
al.add(new FileInputStream("E:\\"+i+".txt"));
}
//使用Collctions 工具类 获取Enumeration
Enumeration<InputStream> en= Collections.enumeration(al);
//创建序列流对象,
SequenceInputStream sis=new SequenceInputStream(en);
//创建存储目的,输出流对象
FileOutputStream fos=new FileOutputStream("E:\\gg.txt");
//创建缓冲区对象
BufferedInputStream bis=new BufferedInputStream(sis);
BufferedOutputStream bos=new BufferedOutputStream(fos);
byte[] bytes=new byte[1024];
int num =0;
while ((num=bis.read(bytes))!=-1){
bos.write(bytes,0,num);
bos.flush();
}
bis.close();
bos.close();
}
对象功能流 ObjectOutputStream/ObjectInputStream
- 特点:用于操作对象
- 功能: readObject(); . writerObject();
- 关键字,瞬态,transient
/*
* Person类的对象如果需要序列化,就需要实现Serializable接口
* 该接口给序列的类,提供了一个序列版本号 :serialVersionUID
* 版本号的目的在于验证序列化对象和对应类是否版本匹配
* */
class Person implements Serializable {
private String name;
private transient int age; //瞬态关键字,不写入该变量
private static final long serialVersionUID = 123L;
Person(String name, int age) {
this.name = name;
this.age = age;
}
public String toString() {
return name + age;
}
}
public static void outObject() throws IOException {
//明确储存对象文件
FileOutputStream fos = new FileOutputStream("E:\\a.object");
//给输出流加入写入对象功能
ObjectOutputStream oos = new ObjectOutputStream(fos);
oos.writeObject(new Person("张三", 20));
oos.close();
}
public static void readObject() throws IOException, ClassNotFoundException {
FileInputStream fis = new FileInputStream("E:\\a.object");
ObjectInputStream ois = new ObjectInputStream(fis);
Person p = (Person) ois.readObject();
System.out.println(p.toString());
ois.close();
}
RandomAccessFile
- 特点:只能操作文件
既能读又能写
内部维护了一个byte数组,定义了字节流的读写
通过对指针的操作可以实现对文件内部任意位置的读取和写入
public static void rafread() throws IOException {
RandomAccessFile raf = new RandomAccessFile("E:\\e.txt", "r");
raf.seek(10);
byte[] bytes = new byte[1024];
raf.read(bytes);
System.out.println(new String(bytes));
raf.close();
}
public static void rafWriter() throws IOException {
//创建一个随机访问文件的对象
RandomAccessFile raf = new RandomAccessFile("E:\\e.txt", "rw");
//写入名字年龄;
// raf.write("张三".getBytes());
// raf.writeInt(97);
// raf.write("李四".getBytes());
// raf.writeInt(98);
System.out.println(raf.getFilePointer());
raf.seek(10); //设置指针位置,从此位置开始改写数据
raf.write("王五".getBytes());
raf.writeInt(99);
System.out.println(raf.getFilePointer());
raf.close();
}
管道流 PipedInputStream/ PipedOutputStream
public class Main {
public static void main(String[] args) throws IOException, ClassNotFoundException {
//创建管道流对象
PipedInputStream pis = new PipedInputStream();
PipedOutputStream pos=new PipedOutputStream();
pis.connect(pos); //将两个流连接
Thread t1=new Thread(new Input(pis)); //此线程执行管道输入流
Thread t2=new Thread(new Output(pos)); //此线程执行管道输出流
t1.start();
t2.start();
}
}
//定义输入任务一条线程专门执行输入
class Input implements Runnable{
private PipedInputStream pis;
public Input(PipedInputStream pis) {
this.pis = pis;
}
public void run() {
byte[] bytes=new byte[1024];
int num=0;
try{
while ((num=pis.read(bytes))!=-1){ //从管道流读取数据
System.out.println(new String (bytes,0,num));
}
pis.close();
}catch (IOException e){
e.printStackTrace();
}
}
}
//定义输出任务,一条线程专门执行输出
class Output implements Runnable{
private PipedOutputStream pos;
public Output(PipedOutputStream pos) {
this.pos = pos;
}
public void run() {
try {
pos.write("管道刘来了!~~~".getBytes()); //往管道流写入数据
pos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
操作基本类型的流
DataInputStream/DataOutputStream
private static void readDate() throws IOException {
FileInputStream fis = new FileInputStream("E:\\a.txt");
DataInputStream dis = new DataInputStream(fis);
System.out.println(dis.readBoolean());
System.out.println(dis.readInt());
dis.close();
}
public static void writeDate() throws IOException {
FileOutputStream fos = new FileOutputStream("E:\\a.txt");
DataOutputStream dos = new DataOutputStream(fos);
dos.writeBoolean(true);
dos.writeInt(353);
dos.close();
}
ByteArrayInputStream/ByteArrayOutputStream
//操作字节数组ByteArrayInputStream/ByteArrayOutputStream
private static void byteArray() throws IOException {
//用IO读写思想操作数组
ByteArrayInputStream bis = new ByteArrayInputStream("你好".getBytes());
ByteArrayOutputStream bos = new ByteArrayOutputStream(); //内置一个可变长度byte数组
int num = 0;
byte[] bytes = new byte[1024];
while ((num = bis.read(bytes)) != -1) {
bos.write(bytes, 0, num);
}
System.out.println(bos.toString());
}
文件切割
public static void main(String[] args) throws IOException {
File file = new File("E:\\0.mp3"); //文件源
File file2 =new File("E:\\music"); //文件目的
fileSplit(file,file2);
}
public static void fileSplit(File infile, File outfile) throws IOException {
if (!infile.exists()){
throw new RuntimeException("源文件不存在");
}
if (!outfile.exists()){
outfile.mkdirs(); //如果不存在就创建文件夹
};
FileInputStream fis = new FileInputStream(infile); //读取源文件
FileOutputStream fos = null;// 创建目的引用;
byte[] bytes = new byte[1024 * 1024]; //创建一个1 M的缓冲区;
int count = 1;
int num = 0;
while ((num = fis.read(bytes)) != -1) { //将1M的数据读到数组中
System.out.println(num);
File fileout=new File(outfile,(--count)+".mp3");
fos = new FileOutputStream(fileout);
count++;
fos.write(bytes, 0, num);
fos.close();
}
//使用Properties 生成配置文件记录,文件个数,和源文件名字
Properties ppt = new Properties();
ppt.setProperty("文件个数", String.valueOf(--count));
ppt.setProperty("源文件名字", infile.getName());
//定义配置文件输出流
FileWriter fw = new FileWriter("E:\\music\\config.properties");
ppt.store(fw, "config"); //将集合写出此流
fw.close();
fis.close();
}
按字节截取字符串
public static void main(String[] args) throws IOException {
String s = "abc你好";
byte[] bytes = s.getBytes("GBK");
for (int i = 0; i < bytes.length; i++) {
String temp = cutString(s, (i + 1));
System.out.println((i + 1) + "个字节截取到的 : " + temp);
}
}
private static String cutString(String str, int len) throws UnsupportedEncodingException {
//将字符串转成字节数组,因为要截取的是字节,GBK编码
byte[] bytes = str.getBytes("GBK");
//定义一个计数器,记录住负数的个数
int count = 0;
//对字节数组进行遍历,应该从截取长度len的最后一个字节开始往回判断
for (int i = len - 1; i >= 0; i--) {
if (bytes[i] < 0) {
count++;
} else {
break;
}
}
//如果计数器的值为奇数.就舍弃最后一个字节,如果偶数不舍弃
if (count % 2 == 0) {
return new String(bytes, 0, len, "GBK");
} else {
return new String(bytes, 0, len - 1, "GBK");
}
}