java的IO复习

复习一下 TIJ 做一下IO的笔记 把以前的笔记转到Blog上

在core java上就把IO分成了 流和文件 这两个最最基本和最根源的类型

流就是对字节的操作 文件就是对文件和目录的操作

也就是说 File是在文件系统里 在不打开文件的情况下的操作 流是对文件的内容的操作

基础  & File类

tips

'     File可以是任何文件或者是文件夹

'     java 是用 "/“ 来做结合字母做转义字符 因此路径要用 "//" 来分隔 File f=new File("e://**//******")

'     File类有常量 separator来表示分隔符 在linux下为 "/" 在win下为"/"  这个separator是string类型的

          还有一个 separatorChar是char类型的

'     File.separator 表示了当前的根目录

'      File(File parent, String child)
          根据 parent 抽象路径名和 child 路径名字符串创建一个新 File 实例。

    File dir = new  File(File.separator);
    Stirng str
= " one " + File.separator + " two.txt " ;
    File f
= new  File(dir, str);
    f.createNewFile();

'    删除方法 delete() deleteOnExit()是在程序终止的时候删除文件

'    createTempFile 是在缺省的temp目录下创建 临时文件 并赋值 构造的时候可指定前缀名和后缀名

'    list() 返回目录内的文件和文件夹名称的 String[]

'    FileNameFilter() 文件名过滤器接口 里面有accept方法 File的list()有能力来callback 它

    String的  indexOf(string s)方法 返回此字符串的索引 如果没有返回 -1

    因此 过滤文件名的时候可以这么写

        File fdir  =   new  File(File.separator);
        String s 
=   " lessons "   +  File.separator  +   " ssdf "   +  File.separator  +   " 09 " ;
        File f 
=   new  File(fdir,s);
        String[] names 
=  f.list( new  FilenameFilter() {
            
public boolean accept(File dir, String name){
                
return name.indexOf(".java"!= -1;
            }

        }
);
        
for ( int  j  =   0 ; j  <  names.length; j ++ )
            System.out.println(names[j]);

    也可以像TIJ 上那样写的 再写个实现了FilenamFilter的类 作为list()的参数

eg:对文件夹的操作 列出所有文件

FileTest.java

import  java.io. * ;

class  FileTest {
        
public static void main(String[] args) throws Exception
        
{
                
/*
                //File f = new File("1.txt");
                //f.createNewFile();
                //f.mkdir();                         //创建文件夹
                //file的另一种方法,指定路径
                //File f = new File("E:/lessons/sunxin/09/1.txt");    /注意用双反斜杠
                //f.createNewFile();
                File f = new File(File.separator);//创建文件分割符,代表当前的目录所在的盘符
                String s = "lessons" + File.separator + "sunxin" + File.separator + "09" +File.separator+"1.txt";
                //路径的设置  是一个string类型的(中间注意要加上分割符)
                //file的另一个构造方法
                File  f2 = new File(f, s);//在当前目录下创建
                f2.createNewFile();
                //f2.delete();
                f2.deleteOnExit();     //在程序退出的时候删除文件
                Thread.sleep(13000); 
                
*/

                File fdir 
= new File(File.separator);
                String s 
= "test" + File.separator +"lessons" + File.separator + "sunxin" + File.separator + "09";
                File f 
= new File(fdir,s);
        
//利用list方法返回的是string类的数组,但是filenamefilter是一个接口
        
//用匿名类
                String[] names = f.list(new FilenameFilter(){
                        
public boolean accept(File dir, String name){
                                
return name.indexOf(".java"!= -1;
                        }

                }
);
                
for(int j = 0; j < names.length; j++)
                        System.out.println(names[j]); 
        }

}

 

 

流类

流类用不同的分法可以分为不同的类

可分为            输入流输出流

可分为            节点流过滤流 管道流

还可以分为    字节流字符流

最重要和最基础的类和方法

OutputStream  所有输出流&字节流的超类

提供最基本的输出方法write()和刷新输出流的方法flush() 关闭方法close()

InputStream 所有输入流&字节流的超类

提供一些基本的读入方法 read() 重定位reset()等等方法

在lang包里有一个经常用到的System里提供了两个标准的输入和输出流in和out分别是InputStream和PrintStream

一个例子 在cmd里等待输入 并在回车后打印出来

import  java.io. * ;

public   class  Test
{
    
public static void main(String[] args)throws Exception
    
{
        
int h;
        
while((h=System.in.read())!=-1)
        
{
            System.out.write(h);
        }

    }

}

write(int b)

将指定的字节写入此输出流。write 的常规协定是:向输出流写入一个字节。要写入的字节是参数 b 的八个低位。b 的 24 个高位将被忽略。

read()

从输入流读取下一个数据字节。返回 0255 范围内的 int 字节值。如果因已到达流末尾而没有可用的字节,则返回值 -1。在输入数据可用、检测到流的末尾或者抛出异常前,此方法一直阻塞。

这个程序在运行的时候是这样的

在命令行里输入的字符read方法会得到字符的默认编码下的int

比如输入一个w 会得到一个01110111 也就是一个字节的十六进制的77  十进制的119 然后在write的时候将这个int的低8位写入一个字节  因为使用的是PrintStream的write 所以将会使用系统默认的字符集转换并输出字符

再比如输入的是一个 "王" 得到的是 205 245 也就是二进制的 11001101 11110101 然后用字符集转换输出

我机器的系统默认字符集使用的是GBK 所以在输出的时候没有发生乱码

 

 分类中按节点流 过滤流来分比较好 其他的类型都比较好理解

OutputStream中 有很多子类

其中FilterOutputStream及其子类都是是过滤流

其他的FileOutputStream  等是节点流 PipedOutputStream是管道流(用于线程间的通信)

FileOutputStream是对文件的流的写操作

分别举例 创建文本文件并写入数据

import  java.io. * ;

class  StreamTest {
        
public static void main(String[] args) throws Exception{
                FileOutputStream f1 
= new FileOutputStream("1.rmvb"); 
                f1.write(
"http://www.rainytooo.com".getBytes());
                f1.close();
               
                                        
        }

}

用文本编辑器打开可以看到字符串

再看看几个过滤流的作用

import  java.io. * ;

class  StreamTest {
        
public static void main(String[] args) throws Exception{
                FileOutputStream f1 
= new FileOutputStream("1.rmvb"); 
                
                BufferedOutputStream bf 
= new BufferedOutputStream(f1);

                bf.write(
"http://www.rainytooo.com".getBytes());
               
                bf.flush();                                 
                bf.close();

               
                                        
        }

}

BufferOutputStream是过滤流中的一种 用于将字节写到缓冲先 等缓冲区满才会写入到文件中

DataOutputStream将不同的java数据类型写入到流中 都转换成byte 并且从最高位开始写

import  java.io. * ;

class  StreamTest {
        
public static void main(String[] args) throws Exception{
                FileOutputStream f1 
= new FileOutputStream("1.rmvb"); 
                BufferedOutputStream bf 
= new BufferedOutputStream(f1);
                   DataOutputStream df 
= new DataOutputStream(bf);             
                
byte a1 = 1;
                
char a2 = 'a';
                
float a3 = 1.3f;
                
int a4 = 1
                df.writeByte(a1);
                df.writeChar(a2);
                df.writeFloat(a3);
                df.writeInt(a4);
                df.close();
        }


}

这些数据都被换成了相应的字节数据

1     byte 1个字节    对应    01

a    char   2 个字节   对应    00 61

1.3f    float 4个字节   对应     3F A6 66 66

1    int   4个字节    对应    00 00 00 01

这个过滤的作用就很明显了

可以自己根据需要不断重组过滤流类来得到自己想要的功能的过滤流类 只要一个过滤流的构造以另一个过滤流为参数

 

打印流PrintStream

System里的out 就是一个打印流 有各种格式化的输出

 

另一个例子用来说明管道流的作用

import  java.io. * ;

class  Producer  extends  Thread {
        
private PipedOutputStream pos;
        
public Producer(PipedOutputStream pos){
                
this.pos=pos;
        }

        
public void run(){
                
try
                
{
                        pos.write(
"Hello,RainyTooo!".getBytes());
                        pos.close();
                }
catch(Exception e)
                
{
                        e.printStackTrace();
                }

        }

}


class  Consumer  extends  Thread {
        
private PipedInputStream pis;
        
public Consumer(PipedInputStream pis){
                
this.pis=pis;
        }

        
public void run(){
                
try
                
{
                        
byte[] byt = new byte[100];
                        
int len = pis.read(byt);
                        System.out.println(
new String(byt,0,len));
                        pis.close();
                }
catch(Exception e)
                
{
                        e.printStackTrace();
                }

        }

}



public   class  PipedStreamTest {
        
public static void main(String[] args){
                PipedOutputStream pos 
= new PipedOutputStream();   //创建尚未连接到传送输入流的传送输出流
                PipedInputStream pis = new PipedInputStream();
                
try
                
{
                        pos.connect(pis);   
//用管道的输出留连接输入流;
                        new Producer(pos).start();  //启动线程;
                        new Consumer(pis).start();
                }
catch(Exception e)
                
{
                        e.printStackTrace();
                }

        }

}

 

管道流之间谁连接谁都可以的

 

ByteArrayOutputStream是一个把字节数组当作输出流的实现 具有缓冲区 可以在构造额达时候自己设定 其中有方便的方法得到字符串和输出到文件

主要有以下三个方便的方法

byte[]toByteArray()
          创建一个新分配的字节数组。
 StringtoString()
          将缓冲区的内容转换为字符串,根据平台的默认字符编码将字节转换成字符。

toString方法还有重载的

 void   writeTo(OutputStream out)
          将此字节数组输出流的全部内容写入到指定的输出流参数中,这与使用 out.write(buf, 0, count) 调用该输出流的 write 方法效果一样。

一个例子

import  java.io. * ;

public   class  ByteArrayTest
{
    
public static void main(String[] args)throws Exception
    
{
        ByteArrayOutputStream bos
=new ByteArrayOutputStream();
        
        String s
="This is a test";
        
byte[] buf=s.getBytes();
        bos.write(buf);        
        System.out.println(bos.toString());
        
        
byte[] buf2= bos.toByteArray();
        
for (int i=0; i<buf.length; i++)
        
{
            System.out.print((
char) buf2[i]);
        }


        
        FileOutputStream f
=new FileOutputStream("testByteArray.txt");
        bos.writeTo(f);
    }

}

SequenceInputStream(顺序输入流)

SequenceInputStream类允许连接多个InputStream流。SequenceInputStream的构造不同于任何其他的InputStream。SequenceInputStream构造函数要么使用一对InputStream,要么用InputStream的一个Enumeration,显示如下:
SequenceInputStream(InputStream first, InputStream second)
SequenceInputStream(Enumeration streamEnum)
操作上来说,该类满足读取完第一个InputStream后转去读取第二个流的读取要求。使用Enumeration的情况下,它将继续读取所有InputStream流直到最后一个被读完。
 
例子
输出两个文件内容
import  java.io. * ;
import  java.util. * ;
class  InputStreamEnumerator  implements  Enumeration 
{
    
private Enumeration files;
    
public InputStreamEnumerator(Vector files) 
    
{
        
this.files = files.elements();
    }

    
public boolean hasMoreElements() 
    
{
        
return files.hasMoreElements();
    }

    
public Object nextElement() 
    
{
        
try 
        
{
            
return new FileInputStream(files.nextElement().toString());
        }
 catch (Exception e) {
            
return null;
        }

    }

}


class  SequenceInputStreamDemo 
{
    
public static void main(String args[]) throws Exception 
    
{
        
int c;
        Vector files 
= new Vector();
        files.addElement(
"StreamTest.java");
        files.addElement(
"Test.java");
        InputStreamEnumerator e 
= new InputStreamEnumerator(files);
        InputStream input 
= new SequenceInputStream(e);
        
while ((c = input.read()) != -1
        
{
            System.out.print((
char) c);
        }

        input.close();
    }

}

字符流

ReaderWrite

两个抽象类   作用就是方便字符的 输入和输出 子类必须实现read和close方法

Reader的子类

BufferedReader   CharArrayReader FilterReader InputStreamReader PipedReader  StringReader

Writer的子类

BufferedWriter   CharArrayWriter FilterWriter OutputStreamWriter PipedWriter  StringWriter  PrintWriter

其中InputStreamReader 的子类FileReader 和 OutputStreamWriter的 子类 FileWriter提供了对文件的直接操作字符的方式

RandomAccessFile(随机访问文件类)

RandomAccessFile 包装了一个随机访问的文件。它不是派生于InputStream 和OutputStream,而是实现定义了基本输入/输出方法的DataInput和DataOutput接口。 这个类同时具有读和写的方法   还有文件指针可以方便在制定位置读和写操作
提供了文件的随机存取的功能整合
RandomAccessFile
它是一个完全独立的class,拥有大量的原生函数,它和其他的IO有本质上的差异
,允许你在文件内自由的前后移动
seek() 的作用是指针
public RandomAccessFile(File file,
                        String mode)
                 throws FileNotFoundException创建从中读取和向其中写入(可选)的随机存取文件流,该文件由 File 参数指定。将创建一个新的 FileDescriptor 对象来表示此文件的连接。
mode 参数指定用以打开文件的访问模式。允许的值及其含意为:


含意

"r" 以只读方式打开。调用结果对象的任何 write 方法都将导致抛出 IOException。  
"rw" 打开以便读取和写入。如果该文件尚不存在,则尝试创建该文件。  
"rws" 打开以便读取和写入,对于 "rw",还要求对文件的内容或元数据的每个更新都同步写入到基础存储设备。  
"rwd"   打开以便读取和写入,对于 "rw",还要求对文件内容的每个更新都同步写入到基础存储设备。



有3种string的写入方法
writeByte(String s)没有读取的方法
writeChar(String s)
writeUTF(String s)可以记录字节的长度在前面用两个字节表示

在RandomAccessFile中
long getFilePointer()
          返回此文件中的当前偏移量。

例子 :用RandomAccessFile类读写文件
import  java.io. * ;

public   class  RandomAccessFileTest
{
        
public static void main(String[] args)throws Exception
        
{
                Student a1 
= new Student(1,"wang",99.0);
                Student a2 
= new Student(2,"zhang",22.0);
                Student a3 
= new Student(3,"xiang",33.0);
                RandomAccessFile raf 
= new RandomAccessFile("students.txt""rw");
                a1.writeStudents(raf);
                a2.writeStudents(raf);
                a3.writeStudents(raf);        
                        
                Student s 
= new Student();
                raf.seek(
0);                          //将文件指针移到启始位置;
                for(long i =0; i<raf.length();i=raf.getFilePointer()) //返回long型的指针偏移量
                {
                        s.readStudents(raf);
                        System.out.println(s.num
+"" + s.name+"" +s.scores);
                }

                raf.close();
        }

}



class  Student
{
        
int num;
        String name;
        
double scores;
        
public Student(){
        }

        
public Student(int num, String name, double scores){
                
this.num=num;
                
this.name=name;
                
this.scores=scores;
        }

        
public void writeStudents(RandomAccessFile raf)throws IOException
        
{
                raf.writeInt(num);
                raf.writeUTF(name);
                raf.writeDouble(scores);
        }

        
public void readStudents(RandomAccessFile raf)throws IOException
        
{
                num 
= raf.readInt();
                name 
= raf.readUTF();
                scores 
= raf.readDouble();
        }

}

对象的序列化
将一个对象转化为字节流
以便保存和还原一个对象
对象序列化必须实现Serializable或者Externalizable接口

1 当一个对象序列化的时候只保存非静态的成员变量不能保存任何成员方法和静态的成员变量

2 如果一个对象的成员变量是一个对象,那么这个对象的数据也会被保存

3 如果一个可序列化的对象包含一个不可序列化的对象的引用,那么整个序列化的操作就将失败
  声明为transient时可以继续序列化
例子:
import  java.io. * ;

class  ObjectSerialTest
{
        
public static void main(String[] args) throws Exception
        
{
                Employee e1
=new Employee("zhangsan",25,3000.50);
                Employee e2
=new Employee("lisi",24,3200.40);
                Employee e3
=new Employee("wangwu",27,3800.55);
                
                FileOutputStream fos
=new FileOutputStream("employee.txt");
                ObjectOutputStream oos
=new ObjectOutputStream(fos);
                oos.writeObject(e1);
                oos.writeObject(e2);
                oos.writeObject(e3);
                oos.close();
                
                FileInputStream fis
=new FileInputStream("employee.txt");
                ObjectInputStream ois
=new ObjectInputStream(fis);
                Employee e;
                
for(int i=0;i<3;i++)
                
{
                        e
=(Employee)ois.readObject();
                        System.out.println(e.name
+":"+e.age+":"+e.salary);
                }

                ois.close();
        }

}


class  Employee  implements  Serializable
{
        String name;
        
int age;
        
double salary;
        
transient Thread t=new Thread();
        
public Employee(String name,int age,double salary)
        
{
                
this.name=name;
                
this.age=age;
                
this.salary=salary;
        }

        
private void writeObject(java.io.ObjectOutputStream oos) throws IOException
        
{
                oos.writeInt(age);
                oos.writeUTF(name);
                System.out.println(
"Write Object");
        }

        
private void readObject(java.io.ObjectInputStream ois) throws IOException
        
{
                age
=ois.readInt();
                name
=ois.readUTF();
                System.out.println(
"Read Object");
        }


}

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Java 期末复习资料包括以下几个方面: 1. Java基础知识:掌握Java的基本语法、数据类型、运算符、流程控制语句等。 2. 面向对象编程:掌握Java的面向对象编程思想、类与对象、封装、继承、多态、抽象类和接口等。 3. 异常处理:掌握Java中的异常处理机制,包括异常类的层次结构、异常处理语句(try-catch-finally)、throw和throws关键字等。 4. 集合框架:掌握Java中的集合框架,包括List、Set、Map等集合容器,以及它们的特点和使用方法。 5. IO流:掌握Java中的IO流,包括字节流和字符流,文件操作等。 6. 多线程编程:掌握Java中的多线程编程,包括线程的创建和启动、线程同步、线程间通信等。 7. 数据库编程:掌握Java中的数据库编程,包括JDBC API的使用、连接数据库、执行SQL语句等。 以下是一些Java期末复习资料的推荐: 1. 《Head First Java》:这是一本非常适合初学者入门的Java书籍,内容浅显易懂,同时又不失深度,适合用来巩固Java基础知识。 2. 《Java核心技术》:这是一本全面深入的Java教材,可以帮助你系统地学习Java的各种知识点,适合用来提高Java技能水平。 3. 《Java编程思想》:这是一本讲述Java编程思想和技巧的经典书籍,涵盖了Java的基础知识、面向对象编程、异常处理、集合框架、IO流、多线程编程和数据库编程等方面的内容。 4. MOOC网站上的Java课程:例如中国大学MOOC网站上的《Java程序设计》和Coursera网站上的《Java程序设计与软件工程专项课程》,这些课程都提供了免费的在线学习资源和相关练习。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值