java IO的学习记录

    技术2022-05-19  20

     

    1  File

    IO包中唯一代表磁盘文件本身信息的类,而不是文件的内容

    File类定义了一些与平台无关的方法来操纵文件(创建,删除,重命名文件)

    Java目录被当做一种特殊的文件使用,list方法可以返回目录中所有的子目录和文件名

    import java.io.File;

    import java.io.IOException;

    import java.util.Date;

    public class FileTest {

    public static void main(String args[]){

    File f = new File("C://Users//姜康 //Desktop//java//2.txt");

    if(f.exists()){

    f.delete();

    }

    else{

    try {

    f.createNewFile();

    } catch (IOException e) {

    e.printStackTrace();

    }

    }

    System.out.println("name:"+f.getName());

    System.out.println("parent name:"+f.getParent());

    System.out.println("path:"+f.getPath());

    System.out.println("");

    Date dt;

    dt = new Date(f.lastModified());

    System.out.println(dt);

    }

    }

    2 . RandomAccessFile

    支持随机访问方式

    支持众多的文件访问方法

    在随机读写等长记录格式的文件时有很大的优势

    仅限于操作文件,不能访问其他的IO设备

    New RandomAccessFile(f,"rw");

    New RandwomAccessFile(f,"r");

    读写共享文件指示器

    import java.io.RandomAccessFile;

    public class TestRandomFile {

    public static void main(String args[])throws Exception{

    Employee e1 = new Employee("zhangsan",25);

    Employee e2 = new Employee("lisi",15);

    Employee e3 = new Employee("wangwu",20);

    RandomAccessFile ra = null;

    ra = new RandomAccessFile

    ( "C://Users//姜康//Desktop//java//2.txt","rw");

    ra.write(e1.name.getBytes());

    //ra.write(e1.age);只读取一个字节

    ra.writeInt(e1.age);

    ra.write(e2.name.getBytes());

    ra.writeInt(e2.age);

    ra.write(e3.name.getBytes());

    ra.writeInt(e3.age);

    ra.close();

    RandomAccessFile raf = null;

    raf = new RandomAccessFile("C://Users//姜康    //Desktop//java//2.txt","r");

    //byte[] buf = new byte[8];

    raf.skipBytes(12);//跳过第一个员工的信息

    System.out.println("第二个员工的信息是:");

    int len = 8;

    String str = "";

    for(int i=0;i<len;i++){

    str = str + (char)raf.readByte();

    }

    System.out.println("name:"+str);

    System.out.println("age:"+raf.readInt());

    raf.seek(0);

    str = "";

    System.out.println("第 一个员工的信息是:");

    for(int i=0;i<len;i++){

    str = str+(char)raf.readByte();

    }

    System.out.println("name:"+str);

    System.out.println("age:"+raf.readInt());

    raf.skipBytes(12);

    System.out.println("第 三个员工的信息是:");

    str = "";

    for(int i=0;i<len;i++){

    str = str+(char)raf.readByte();

    }

    System.out.println("name:"+str);

    System.out.println("age:"+raf.readInt());

    raf.close();

    }

    }

     

    class Employee{

    public final static int LEN = 8;

    String name = null;

    int age = 0;

    Employee(String name,int age){

    if(name.length() > LEN){

    name = name.substring(0, 8);

    }

    else{

    ///u0000表示空字符

    while(name.length() < LEN){

    name += "/u0000";

    }

    }

    this.name = name;

    this.age = age;

    }

    }

    处理中文使用Unicode编码:

    import java.io.RandomAccessFile;

    public class TestRandomFile {

    public static void main(String args[])throws Exception{

    Employee e1 = new Employee("张三",25);

    Employee e2 = new Employee("李四",15);

    Employee e3 = new Employee("王五",20);

    RandomAccessFile ra = null;

    ra = new RandomAccessFile( "C://Users//姜康   //Desktop//java//2.txt","rw");

    ra.writeChars(e1.name);

    //ra.write(e1.age);只读取一个字节

    ra.writeInt(e1.age);

    ra.writeChars(e2.name);

    ra.writeInt(e2.age);

    ra.writeChars(e3.name);

    ra.writeInt(e3.age);

    ra.close();

    RandomAccessFile raf = null;

    raf = new RandomAccessFile("C://Users//姜康      //Desktop//java//2.txt","r");

    //byte[] buf = new byte[8];

    System.out.println("第二个员工的信息是:");

    int len = 8;

    String str = "";

    raf.skipBytes(len*2+4);//跳过第一个员工的信息

    for(int i=0;i<len;i++){

    str = str + (char)raf.readChar();

    }

    //注意Unicode编码,每次占用两个字节

    System.out.println("name:"+str);

    System.out.println("age:"+raf.readInt());

    raf.seek(0);

    str = "";

    System.out.println("第 一个员工的信息是:");

    for(int i=0;i<len;i++){

    str = str+(char)raf.readChar();

    }

    //System.out.println("changdu:"+str.length());

    System.out.println("name:"+str);

    System.out.println("age:"+raf.readInt());

    System.out.println("第 三个员工的信息是:");

    str = "";

    raf.skipBytes(len*2+4);

    for(int i=0;i<len;i++){

    str = str+(char)raf.readChar();

    }

    System.out.println("name:"+str);

    System.out.println("age:"+raf.readInt());

    raf.close();

    }

    }

     

    class Employee{

    public final static int LEN = 8;

    String name = null;

    int age = 0;

    Employee(String name,int age){

    if(name.length() > LEN){

    name = name.substring(0, 8);

    }

    else{

    ///u0000表示空字符

    while(name.length() < LEN){

    name += "/u0000";

    }

    }

    this.name = name;

    this.age = age;

    }

    }

    3. 节点流

    流是字节序列的抽象概念(数据传输)

    文件时数据的静态存储形式,而流是知识传输时的形态

    流分为:节点流类和过滤流类

    InputStreamOutputStream

    InputStream可以连续输入字节

    有了垃圾回收期为什么还会有close方法?

    除了对象外还有各种资源,比如流,close

    FileInputStreamFileOutputStream

    分别用来创建磁盘文件的输入输出流对象,通过他们构造函数来制定文件路径名和文件 名,创建FileOutStream实例对象时,如果制定文件存在,将会覆盖源文件。

    FileInputStream inOne = new FileInputStream("hello.test");

    File f = new File("test.test");

    FileInputStream inTwo = new FileInputStream(f);

    import java.io.FileInputStream;

    import java.io.FileOutputStream;

     

    public class TestFileIO {

    public static void main(String args[]) throws Exception{

    FileInputStream in = new FileInputStream("C://Users// 姜康 //Desktop//java//1.txt");

    FileOutputStream out = new            FileOutputStream("C://Users//姜康//Desktop//java//1.txt");

    //会把源文件覆盖掉

    out.write("www.baidu.com".getBytes());

    out.close();

    byte [] buf = new byte[1024];

    int len = in.read(buf);

    System.out.println(new String(buf,0,len));

    in.close();

    }

    }

    ReaderWrite

    ReaderWriter简化对字符串的输入输出编程,即用于读写文本数据

    二进制文本和文本文件的区别

    文件系统中每个文件都是二进制文件

    import java.io.FileReader;

    import java.io.FileWriter;

    import java.io.IOException;

     

    public class FileStream1 {

    public static void main(String args[]) throws IOException{

    FileWriter out = new FileWriter("C://Users//姜康 //Desktop//java//1.txt");

    out.write("www.google.com");

    out.flush();

    out.close();

    //一定要关闭或者是刷新缓冲区

    //否则最后一行数据不会输入到文件中

    FileReader in = new FileReader("C://Users//姜康 //Desktop//java//1.txt");

    char [] buf = new char[1024];

    int len = in.read(buf);

    System.out.println(new String(buf,0,len));

    }

    }

    PipedInputStreamPipedOutputStream

    他们应用在应用程序中的创建管道通信(线程通信)

    import java.io.IOException;

    import java.io.PipedInputStream;

    import java.io.PipedOutputStream;

     

    public class PipedStreamTest {

    public static void main(String args[]){

    Sender t1 = new Sender();

    Riceiver t2 = new Riceiver();

    PipedOutputStream out1 = t1.getOutputStream();

    PipedInputStream in1 = t2.getInputStream();

    try {

    out1.connect(in1);

    } catch (IOException e) {

    e.printStackTrace();

    }

    t1.start();

    t2.start();

    }

    }

     

     

     

    import java.io.IOException;

    import java.io.PipedOutputStream;

     

    public class Sender extends Thread{

    private PipedOutputStream out = new PipedOutputStream();

    public PipedOutputStream getOutputStream(){

    return out;

    }

    public void run(){

    String strInfo = new String("hello,receiver!");

    try {

    out.write(strInfo.getBytes());

    out.close();

    } catch (IOException e) {

    e.printStackTrace();

    }

    }

    }

     

     

    import java.io.IOException;

    import java.io.PipedInputStream;

    public class Riceiver extends Thread{

    private PipedInputStream in = new PipedInputStream();

    public PipedInputStream getInputStream(){

    return in;

    }

    public void run(){

    byte buf[] = new byte[1024];

    try {

    int len = in.read(buf);

    System.out.println("the following comes from  sender:/n"+new String(buf,0,len));

    in.close();

    } catch (IOException e) {

    e.printStackTrace();

    }

    }

    }

    PipedWriter和PipedReader类

    使用管道流类,可以实现各个程序模块之间的松耦合通信

    ByteArrayInputStreamByteArrayOutputStream

    用于以IO流的方式来完成对字节数组内容的读写

    支持类似内存虚拟文件或者内存映像文件的功能

    public class ByteArrayTest {

    public static void main(String[] args) {

    String tmp = "abcdefghijkmlnopqrstuvwxyz";

    byte [] src = tmp.getBytes();

    ByteArrayInputStream input = new ByteArrayInputStream(src);

    ByteArrayOutputStream output = new ByteArrayOutputStream();

    try {

    transform(input,output);

    } catch (IOException e) {

    e.printStackTrace();

    }

    byte [] result = output.toByteArray();

    System.out.println(new String(result));

    }

    public static void transform(InputStream in,OutputStream out) throws IOException{

    int ch;

    while((ch = in.read()) != -1){

    int upperCh = (int)Character.toUpperCase((char)ch);

    out.write(upperCh);

    }

    }

    }

     

    重视IO程序代码的复用

    System.in连接连接到键盘,InputStream类型的实例对象,System,outPrintStream 实例对象,连接到显示器

    无论各种底层物理设备用什么样的方式实现数据的终止点,InputStream总是返回-1 示输入流的结束

    transform(System.in,System.out);

    字符编码

    中国每个字符都用连个字节的数字来表示,GB2312 后来扩展了繁体称为GBK

    ISO制定了Unicode编码标准

    Java中的字符使用的都是Unicode编码

    UTF-8编码中ASCii码只占用一个字节,其他国家的字符,使用两个或三个字节表示

    UTF-16 big-Endianlittle-Endian0xFE 0xFF开头表明是big-Endian,反过来为 little-Endian

    动手体验字符编码:

    public class CharCode {

    public static void main(String args[]){

    System.setProperty("find-encoding","GBK");

    System.getProperties().list(System.out);

    String strChina = "中国";

    for(int i=0;i<strChina.length();i++){

    System.out.println(Integer.toHexString

    ((int)strChina.charAt(i)));

    }

    byte []buf = null;

    buf = strChina.getBytes();

    for(int i=0;i<buf.length;i++){

    System.out.println(Integer.toHexString(buf[i]));

    }

    for(int i=0;i<buf.length;i++){

    System.out.write(buf[i]);

    }

    System.out.println();

    //PrintStream会自动把字符集转换为机器中装入的字符集(GB2312)

    }

    }

    6  过滤流与包装类

    InputOutStream处理的是字节,需要先把数据转换到字节数组中再做处理

    DateOutputStream类提供了往各种输入流对象中写入各种类型的数据的方法,现在只需要传递一个FileOutputStream输入流对象给DateOutputStream实例对象和调用实例对象

    一定要指定到任何具体的流设备

    DateOutputStream包装类

    Public DateOutputStreamOutputStream out

    包装流类通过节点流类传送数据给目标

    BufferedInputStreamBufferedOutputStream

    缓冲流增加了内存缓冲区:

    允许java程序一次不止操作一个字节(提高了程序的性能)

    有了缓冲区,skipmarkreset方法可以使用了

    不管地磁是否使用了缓冲区,这两个类在自己的实例对象中创建缓冲区

    它有两个构造函数:

    BufferedInputStream(InputStream in)//一次创建32个字节的缓冲区

    BufferedInputStream(InputStream in,int size)//可以指定大小

    Mark方法是建立在缓冲区内部的(同样有BufferedOutputStream

    BufferedReaderBufferedWriter

    BufferedReader有一个readLine方法可以一次读取一行文本

    BufferedWriter 可以写入不同操作系统下的换行符

    DateInputSteam类和DateOutputStream

    public final void writeByte(String s)//每次只是将字符串中的低字节写入到目标设备

    public final void writeChars(String s)//每次写入两个字节

    Public final void writeUTF(String str)//按照UTF格式写入,前两个是编码后的长度

    UTF规则:

    如果字符c范围在/u0001/u007f之间,则占一个字节,内容为(byte)c

    如果在/u0080或其范围在/u07ffh之间则两个字节

    如果在/u0800/uffff之间,则占三个字节

    如果关闭流栈中最上层的流对象,底层的流对象将全会被关闭

    import java.io.BufferedInputStream;

    import java.io.BufferedOutputStream;

    import java.io.DataInputStream;

    import java.io.DataOutputStream;

    import java.io.FileInputStream;

    import java.io.FileOutputStream;

    import java.io.IOException;

     

    public class DateStreamTest {

    public static void main(String[] args) throws IOException {

    FileOutputStream fos = new FileOutputStream("C://Users//姜康//Desktop//java//xx.txt");

    BufferedOutputStream bos = new BufferedOutputStream(fos);

    DataOutputStream dos = new DataOutputStream(bos);

    dos.writeUTF("ab中国");

    dos.writeBytes("ab中国");

    dos.writeChars("ab中国");

    dos.close();

    FileInputStream fis = new FileInputStream("C://Users//姜康//Desktop//java//xx.txt");

    BufferedInputStream bis = new BufferedInputStream(fis);

    DataInputStream dis = new DataInputStream(bis);

    System.out.println(dis.readUTF());

    /*byte buf[] = new byte[1024];

    int len = dis.read(buf);

    System.out.println(new String(buf,0,len));*/

    //用writechars和writebytes写入文件后读出来就不容易了

    //所以java提供了一些专用类来处理字符串

    }

    }

    7 PrintStream

    PrintStream提供了一系列的printprintln方法,可以将基本数据类型的数据格式 化成字符串输出(println可以自动调用flush方法来刷新缓冲区)

    格式化输出就是将数据用字符串的形式输出

    三个构造函数:

    PrintStream(OutputStream out)

    PrintStream(OutputStream out, boolean autoflush)//设置是否自动清空缓冲区

    PrintStream(OutputStream out boolean autoflush,String encoding)

    //可以指定字符编码

    PrintWriter类,计时遇到了文本换行标识符(/n)也不会自动清空缓冲区

    println()windows生成的文本换行标识符为:"/r/n"Linux下为:"/n"

    8 ObjectInputStreamObjectOutputStream

    可以完成保存和读取对象成员变量取值的过程

    所读取的对象必须实现了Serializable接口,对象中的transient(表示变量是临时的, 不能被用作对象的表示)和static类型的成员 变量不会被读取和写入

    序列化可以屏蔽操作系统的差异

    import java.io.*;

     

    @SuppressWarnings("serial")

    class Student implements Serializable {

    int id;

    String name;

    int age;

    String department;

    public Student(int id,String name,int age,String department){

    this.id = id;

    this.name = name;

    this.age = age;

    this.department = department;

    }

    }

    class Serialization {

    public static void main(String args[]) throws IOException, ClassNotFoundException{

    Student stu1 = new Student(19,"zhangsan",25,"jsj");

    Student stu2 = new Student(20,"lisi",18,"yingyu");

    FileOutputStream out = new FileOutputStream("C://Users//姜康//Desktop//java//student.txt");

    ObjectOutputStream os = new ObjectOutputStream(out);

    os.writeObject(stu1);

    os.writeObject(stu2);

    os.close();

    FileInputStream in = new FileInputStream("C://Users//姜康//Desktop//java//student.txt");

    ObjectInputStream is = new ObjectInputStream(in);

    stu1= (Student) is.readObject();

    stu2= (Student) is.readObject();

    is.close();

    System.out.println("id:"+stu1.id);

    System.out.println("name:"+stu1.name);

    System.out.println("age:"+stu1.age);

    System.out.println("department:"+stu1.department);

    System.out.println();

    System.out.println("id:"+stu2.id);

    System.out.println("name:"+stu2.name);

    System.out.println("age:"+stu2.age);

    System.out.println("department:"+stu2.department);

    }

    }

    9  字节流与字符流的转换

    BufferedReader类的两个构造方法:

    BufferedReader(Reader in)    创建一个使用默认大小输入缓冲区的缓冲字符输入流。 

    BufferedReader(Reader in, int sz)    创建一个使用指定大小输入缓冲区的缓冲字符输入流。

    需要用包装类来转换输入的数据

    InputStreamReader(Reader类的子类)OutputStreamWriter两个类分别来把字节流 转换成字符流后读取和把字符编码为字节后写入到一个字节流中

    InputStreamReader构造函数:

    InputStreamReader(InputStream in)          创建一个使用默认字符集的 InputStreamReader

    InputStreamReader(InputStream in, Charset cs)          创建使用给定字符集的 InputStreamReader

    InputStreamReader(InputStream in, CharsetDecoder dec)          创建使用给定字符集解码器的 InputStreamReader

    InputStreamReader(InputStream in, String charsetName)          创建使用指定字符集的 InputStreamReader

     

     

     

     

     

    OutputStreamRead构造函数:

    OutputStreamWriter(OutputStream out)          创建使用默认字符编码的 OutputStreamWriter

    OutputStreamWriter(OutputStream out, Charset cs)          创建使用给定字符集的 OutputStreamWriter

    OutputStreamWriter(OutputStream out, CharsetEncoder enc)          创建使用给定字符集编码器的 OutputStreamWriter

    OutputStreamWriter(OutputStream out, String charsetName)          创建使用指定字符集的 OutputStreamWriter

     

     

     

     

    10  java虚拟机读写其他进程的数据

    我们在java虚拟机中可以产生其他应用程序的进程,在java程序中启动的进程成 为子进程,子进程的标准输入输出不再连接到键盘和显示器,而是以管道流的形式 连接到父进程的一个输入流和输出流对象上

    调用Process类的getOutputStreamgetInputStream方法可以获得连接到子进程的 输出流和输入流对象

    import java.io.*;

    public class TestInout implements Runnable{

    Process p = null;

    public TestInout() throws IOException{

    p = Runtime.getRuntime().exec("java MyTest");

    new Thread(this).start();

    //用this表示send和run方法调用的是一个对象

    }

    public static void main(String[] args) throws IOException {

    TestInout t = new TestInout();

    t.send();

    }

    public void send() throws IOException{//向子进程发送数据

    OutputStream ops = p.getOutputStream();

    while(true){

    ops.write("help/r/n".getBytes());

    }

    }

    public void run(){//接收数据

    InputStream ips = p.getInputStream();

    BufferedReader bfr = new BufferedReader(

    new InputStreamReader(ips));

    String strLine = "";

    try {

    strLine = bfr.readLine();

    while(true){

    System.out.println(strLine);

    }

    } catch (IOException e) {

    e.printStackTrace();

    }

    }

    }

     

    import java.io.*;

    public class MyTest {

    public static void main(String args[]) throws IOException{

    String strLine = "";

    BufferedReader bft = new BufferedReader(

    new InputStreamReader(System.in));

    while(true){

    strLine = bft.readLine();

    if(strLine != null){

    System.out.println("hi"+strLine);

    }

    else{

    return;

    }

    }

    }

    }

    要用destroy方法结束Process子进程的运行

    11  字节输入流类

    字节输出流类

    字符输入流类

    字符输出流类

     

    12  Decorator设计模式

    在程序中用一个对象(the Decorator) 包装另外一个对象

    如果设计字节的IO包装类,这个类需要继承FilterXXX命名的类

    import java.io.*;

     

    public class TestPrintWriter {

    public static void main(String args[]){

    try{

    throw new Exception("test");

    }catch(Exception e){

    StringWriter sw = new StringWriter();

    PrintWriter pw = new PrintWriter(sw);

    e.printStackTrace(pw);

    System.out.println(sw.toString());

    }

    }

    }

     


    最新回复(0)