JAVA IO流(下)

 流(Stream)是字节的源或目的。

 InputStream 和 OutputStream 是两个 abstact 类,对于字节为导向的 stream 都扩展这两个基类。
 初学的时候,就记住一句话,只要带Reader或者Writer的就是字符流,带Stream就是字节流。
 流的本质是用于文件本地的操作,由于网络需求,现在经常用于网络编程。所以我们还是先来看看文件之间的IO操作吧。
 下面为包含了IO流的常用案例:
  

  public class FileCreate {
   public static void main(String[] args){
    //在不同环境下的\分隔符是不同的,所以推荐使用File的变量
    File file = new File("f:"+File.separator+"newFile.zip");
    File file1 = new File("f:"+File.separator+"wenjianjia");
    //创建一个文件夹 
    //mkdir 必须上级目录存在 才可以完成创建 
    //makdirs  创建所有目录文件夹
    file1.mkdir();
    File file2  = new File("f:"+File.separator+"ai"+File.separator);
    //判断指定目录是否存在
    Boolean  = file2.isDrectory();
    if(!file.exists()){   //如果文件不存在
     try {
      //创建一个该路径下的文件
      file.createNewFile();
     } catch (IOException e) {
      e.printStackTrace();
     } 
    }else{
     //第一次运行创建  第二次就直接delete
     //如果存在就删除  
     file.delete();
    }
   
   }
  }


  
  
public class FileIO{
   public static void main(String[] args){
    //在不同环境下的\分隔符是不同的,所以推荐使用File的变量
    File file = new File("f://newFile.txt");
    if(!file.exists()){   
     try {
      file.createNewFile();
      String str = "新年快乐";
      byte[] b = str.getBytes();
      OutputStream  os = new FileOutputStream(file);
      os.write(b, 0, b.length);
      os.close();
     } catch (Exception e) {
      e.printStackTrace();
     } 
    }else{
     //追加内容
     try {
      //第二个参数如果为true则 追加内容
      //OutputStream  os  = new FileOutputStream(file, true);
      //os.write("哈哈哈哈".getBytes());
      InputStream is = new FileInputStream(file);
      byte[] b = new byte[(int)file.lenth()];
      //read 方法是一个字节一个字节地读 当文件读到末尾会返回-1 正常情况不会
      while((is.read(b)!=-1){
      }
      is.close();
      system.out.print(new String(b);
     } catch (Exception e) {
      e.printStackTrace();
     }   
    }
    
   }
  }
  


 
 public class FileWR{
   public static void main(String[] args) throws Exception{
    File file = new File("f:\\1.txt");
    if(!file.exists()){
     file.createNewFile();
    }
    //先读出来 然后再写入另一个文件
    Reader reader = new FileReader(file);
    char[] ch=new char[(int) file.length()];
    int len = reader.read(ch);
    System.out.println(new String(ch,0,len));
    File file1 = new File("f:\\2.txt");
    if(!file.exists()){
     file.createNewFile();
    }
    Writer writer = new FileWriter(file1);
    writer.write(new String(ch,0,len));
    reader.close();
    writer.close();
   }
  }


  注意:在我学的时候经常混淆的东西,字符流和字节流的read方法:
   is.read():  返回的是否到达末尾,是return -1,在没有return -1的情况下,它是一个字节;
   reader.read(): 如上,在没有return -1的情况下,它是一个字符;
   is.read(byte): 返回的是读取到的总字节数;
   reader.read(char): 返回的是读取到的总字符数;
  OutputStreramWriter 和InputStreamReader类
   在网络操作中,我们经常从服务器获取的是字节流,所以我们在给用户看的时候,必须要将之转换为字符流。
   整个IO类中除了字节流和字符流还包括字节和字符转换流。
   OutputStreramWriter将输出的字符流转化为字节流
   InputStreamReader将输入的字节流转换为字符流
   但是不管如何操作,最后都是以字节的形式保存在文件中的。
    
  
  class hello{
   public static void main(String[] args) throws IOException {
    String fileName= "d:"+File.separator+"hello.txt";
    File file=new File(fileName);
    Writer out=new OutputStreamWriter(new FileOutputStream(file));
    out.write("hello");
    out.close();
   }
  }
  运行结果:
    在d盘目录下,存放的hello.txt中显示hello。



  
 

 class hello{
   public static void main(String[] args) throws IOException {
    String fileName= "d:"+File.separator+"hello.txt";
    File file=new File(fileName);
    Writer out=new OutputStreamWriter(new FileOutputStream(file));  //OutputStreamWriter将字节输入流转换为字符输入流
    char[] b=new char[100];
    int len=read.read(b);            //将读取的字符存放入char中,len返回的是读取字符的总个数
    System.out.println(new String(b,0,len));       //将char数组转换为String显示
    read.close();
   }
  }
  


  class ByteArrayIODemo{
   public static void main(String[] args){
    String str = "hello";
    ByteArrayInputStream is = new ByteArrayInputStream(str.getBytes()); //使用str.getBytes()作为流输入的来源(数据源) 该缓冲区包含从流中读取到的字节
    ByteArrayOutputStream os  = new ByteArrayOutputStream();   //将字节数据当做流输出目的地
    int len =  0 ;
    while ((len = is.read())!=-1){
     os.write(len);
    }
    //调用方法toString() 可以指定转换字符集编码
    system.out.print(os.toString());
   }
  }


  想对应的还有CharArrayReader和CharArrayWriter字符的操作。
  
  
//输出流
  public class Out {
   PipedOutputStream outputStream = null;
   public Out(){
    this.outputStream = new PipedOutputStream();
   }
   public PipedOutputStream getOut(){
    return this.outputStream;
   }
   class myRun implements Runnable{
    @Override
    public void run() {
     String str = "你应该可以收到的";
     try {
      outputStream.write(str.getBytes());
      outputStream.close();
     } catch (IOException e) {
      e.printStackTrace();
     }
    }
    
   }
  }
  //输入流
  public class Inp {
   PipedInputStream InputStream = null;
   public Inp(){
    this.InputStream = new PipedInputStream();
   }
   public PipedInputStream getInput(){
    return this.InputStream;
   }
   class myRun implements Runnable{
    @Override
    public void run() {
     try {
      byte[] b  = new byte[1024];
      int len = 0 ;
      len = InputStream.read(b);
      System.out.println(new String(b,0,len));
     } catch (IOException e) {
      e.printStackTrace();
     }
    }
    
   }
  }
  //测试类
  public class FileIo {
   public static void main(String[] args) throws Exception{
    Out out = new Out();
    //得到管道输出流对象
    PipedOutputStream os = out.getOut();
    Inp in = new Inp();
    //得到管道流输入流对象
    PipedInputStream is  = in.getInput();
    //管道连接
    os.connect(is);
    //开始发送
    out.new myRun().run();
    //接受
    in.new myRun().run();
   }
  }
  
  public class SytemDemo{
   public static void main(String[] args)throws Exception{
    //输出到控制台
    System.out.print("Hello");
    //设置输出流
    System.setOut(new PrintStream(new  FileOutputStream(new File("f:\\hello.txt"))));
    //输出到了文件当中 控制台只显示上面的输出语句
    System.out.print("hello");
   }
  }
  


  public class SytemDemo{
   public static void main(String[] args){
    //从控制台键盘读取
    int len  = 0 ;
    byte[] b = new byte[1024];
    //从键盘读取
    len = System.in.read(b);
    System.out.print("从键盘读到的"+new String(b,0,len));
    
    //文件字节输入流对象
    InputStream is = new FileInputStream(new File("f:\\hello"));  
    //设置键盘输入流 定向为文件输入流
    System.setIn(is);
    byte[] b = new byte[1024];
    int len = 0 ;
    len =  System.in.read(b);
    //从文件中读取打印到控制台
    System.out.print(new String(b,0,len));
   }
  }
  


 
 public void BufferedReaderDeno{
   public static void  main(String[] args){
    //BufferedReader只接受字符缓字符流缓冲区 所以要将字节流转换为字符流
    BufferedReader  bf = new BufferedReader(new InputStreamReader(new FileInputStream(new File("F:\\BufferedReaderDeno"))));
    //从字符缓冲区里读取一行    它是以'/r'或'\n'为分隔的
    System.out.print(bf.readLine());
   }
  }


  
 
 public void BufferedReaderDeno{
   public static void  main(String[] args){
    BufferedWriter  bf = new BufferedWriter(new OutputStreamReader(new FileOutputStream(new File("F:\\BufferedWriterDeno"))));
    bf.write("i like code");
    //字符其实先写到内存当中  在写入硬盘  
    //如果字符流不close的话 会发现文件中没有内容   可以flush
    bf.close();
   }
  }


  
  public class ScannerDemo{
   public static void main(String[] args){
    //new Scanner(arg0)  arg0: 可以是字节输入流、字符输入流。都可以    
    Scanner scanner = new Scanner(System.in);
    //自动转换  直接获得int控制台输入的int型数值
    System.out.print(scanner.nextInt());
    //文件一般都不需要指定 字符流还是字节流   直接一个File 对象扔进去,Scanner对象的next方法直接返回的是String类型
    Scanner scanner = new Scanner(new File("F:\\Scanner.txt"));
    System.out.print(scanner.next());
   }
  }
  
 
 public class DataStreamDemo{
   public static void main(String[] args){
    int[] a = {1,2,3};
    DataOutputStream dos = new DataOutputStream(new FileInputStream("F:\\ds.txt"));
    foreach(int b : a){
     dos.write(b);
    }
    dos.close();
    DataInputStream dis = new DataInputStream(new FileInputStream("F:\\ds.txt"));
    int temp = 0;
    //直到存放的类型   每次取出来一个  通过方法直接拿 就行了
    
    while((temp=dis.readInt())!=-1){
     System.out.print(temp);
    }
   }
  }


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

    
   InputStream isr1 = new FileInputStream("F:\\1.txt");
   InputStream isr2 = new FileInputStream(new File("F:\\2.txt"));
   //合并两个字节输入流
   SequenceInputStream sq = new SequenceInputStream(isr1, isr2);
   byte[] b =new byte[1024];
   int len= 0;
   FileOutputStream osw = new FileOutputStream("F:\\total.txt");
   while ((len = sq.read(b))!=-1){
    //将两个文件的内容输出在total中
    osw.write(b,0,len);
   }
   isr1.close();
   isr2.close();
   sq.close();
   osw.close();
   }
  }

  

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

    InputStream isr1 = new FileInputStream("F:\\1.txt");
    ZipOutputStream zos = new ZipOutputStream(new FileOutputStream("F:\\2.zip"));
    //开始写入新的 ZIP 文件条目并将流定位到条目数据的开始处     设置第一个条目的名字
    zos.putNextEntry(new ZipEntry("哈哈.txt"));
    //设置zip包的注释 
    zos.setComment("h");
    byte[] b =new byte[1024];
    int len= 0;
    while ((len = isr1.read(b))!=-1){
     zos.write(b,0,len);
    }
    isr1.close();
    zos.close();
    }
   }


  
 

 public class ZipInputDemo{
   public static void main(String[] args){
    InputStream is = null;
    OutputStream os = null;
    Entry e = null;
    String zipName = "javaCode.zip";
    //要结果的zip文件对象
    File file = new File("F:\\"+zipNmae);
    //通过指定Entry条目对象,获得此条目输出流
    ZipFile zip = new ZipFile(file);
    //zip输入流 可以拿到Entry条目对象
    ZipInputStream zis = new ZipInputStream(new FileInputStream(file));
    while((e=zis.getNextEntry())!=null){
     //在JAVA中"\"属于转移符号,split通过正则表达式的方式分割,在正则表达式中"\","."也属于转义符
     //Java先把"\\"转换为了"\",然后正则表达式将"\."转换为了"."
     File outFile = new File("F:\\"+ZipName.split("\\.")[0]+"\\"+e.getNmae());
     //目录是否存在
     if(!outFile.getParentFile().exists()){
      //makdir  只创建一级目录,也就是如果前面目录都存在 才创建最后一个目录
      //makdirs 创建所有目录
      outFile.makdirs();
     }
     //如果文件不存在
     if(!outFile.exists()){
      outFile.reateNewFile();
     }
     is = zip.getInputStream(e);
     os = new FileOutStream(outFile);
     int temp = 0;
     while((len = is.read())!=-1){
      os.write(temp);
     }
     is.close();
     os.close();
    }
    zis.close();
   }
   
  }


  
  public class PushBackInputStreamDemo{
   public static void main(String[] args){
    String str = "hei.ma";
    ByteArrayInputStream bs = new ByteArrayInputStream(str.getBytes());
    PushbackInputStream ps = new PushbackInputStream(bs);
    int len  = 0 ;
    
    while((len = ps.read())!=-1){
     System.out.println("正常读:"+(char)len);
     //将这个字节回退到缓冲区中 
     if(len =='.'){
      ps.unread(len);
      //先读缓冲区中被退回的字节
      int a = ps.read();
      System.out.println((char)a);
     }
    }
   }
  }
  控制台输出:
    正常读:h
    正常读:e
    正常读:i
    正常读:.
    回退: .
    正常读:m
    正常读:a


  
 
 class person implements Serializable{
   //本来是序列化全部属性   关键字tantsient可以说明 不被序列化保存
   private trantsient String sex;
   private String name ;
   private String age;
   public person(String name,String age,String sex){
    this.name = name;
    this.age = age;
    this.sex = sex;
   }
   public String getName() {
    return name;
   }
   public void setName(String name) {
    this.name = name;
   }
   public String getAge() {
    return age;
   }
   public void setAge(String age) {
    this.age = age;
   }
   @Override
   public String toString() {
    return name+","+age;
   }
   public void setSex(String sex){
    this.sex = sex;
   }
   public String getSex(){
    return this.sex;
   }
  }

  public class SerializableDemo{
   public static void main(String[] args){
   person s1 = new person("小明","1岁");
   person s2 = new person("小红","2岁");
   person p =  {s1,s2};
   ObjectOutputStream obo = new ObjectOutputStream(new FileOutputStream(new File("F:\\SerializableDemo.txt")));
   //将两个对象序列化
   obo.write(p);
   ObjectInputStream  obi = new ObjectInputStream(new FileInputStream(new File("F:\\SerializableDemo.txt")));
   Object[] o1 = (Object[])obi.readObject();
   
   //在文件中看到的是 乱码,因为是二进制文件,输出控制台 是可以看到的。
   system.out.print(o1[0].toString()+"\n"+o1[1].toString());
   }
  }
  输出结果:
    小明,1岁
    小红,2岁

  

  class person implements Externalizable{
   private String sex;
   private String name ;
   private String age;
   public person(String name,String age,String sex){
    this.name = name;
    this.age = age;
    this.sex = sex;
   }
   public String getName() {
    return name;
   }
   public void setName(String name) {
    this.name = name;
   }
   public String getAge() {
    return age;
   }
   public void setAge(String age) {
    this.age = age;
   }
   @Override
   public String toString() {
    return name+","+age;
   }
   public void setSex(String sex){
    this.sex = sex;
   }
   public String getSex(){
    return this.sex;
   }
   //序列化时调用(就是说 你要序列化对象的哪些属性)
   @Override
   public void writeExternal(ObjectOutput out) throws IOException {
    out.writeObject(this.name);
    out.writeObject(this.age);
   }
   //反序列化(根据需要读取反序列化内容)
   @Override
   public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
    this.name = (String) in.readObject();
    this.age = (String) in.readObject();
   }
  }


 

 public class ExternalizableDemo{
   public static void main(String[] args){
   person s1 = new person("小明","1岁","男");
   person s2 = new person("小红","2岁","女");
   person p =  {s1,s2};
   ObjectOutputStream obo = new ObjectOutputStream(new FileOutputStream(new File("F:\\SerializableDemo.txt")));
   //将两个对象序列化
   obo.write(p);
   ObjectInputStream  obi = new ObjectInputStream(new FileInputStream(new File("F:\\SerializableDemo.txt")));
   Object[] o1 = (Object[])obi.readObject();   
   system.out.print(o1[0].toString()+"\n"+o1[1].toString());
   }
  }
  输出结果:
    小明,1岁,null
    小红,2岁,null
   


在Android中多线程下载会经常使用到RandomAccessFile随机读取文件,它可以在移动多少字节,写入。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值