Java I/O流(二)——File,Properties,PrintWriter,IO ,RandomAccessFile,ByteBuffer,nio

File概述

文件的操作是非常重要的,我们先来看下他的基本概念

•用于将文件或者文件夹封装成对象
•方便对文件和文件夹的操作
•File对象可以作为参数传递给流的构造函数
我们写个小例子先

import java.io.File;

public class HelloJJAVA {
    public static void main(String[] args) {
        // 创建File对象,不存在也没事
        File file = new File("a.txt");
        //目录 文件名
        File file2 = new File("F:\\isblog\\Demo","a.txt");

        //封装什么就打印什么
        System.out.println(file);
    }
}

其实就是一个类的使用

二.创建删除
是文件肯定有操作方法

•1.创建
•2.删除
•3.判断
•4.获取信息

1.创建

import java.io.File;
import java.io.IOException;

public class HelloJJAVA {
    public static void main(String[] args) {
        // 创建File对象
        File file = new File("a.txt");

        try {
            //创建
            file.createNewFile();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}

在指定的位置创建文件,如果文件已经存在,就不创建,并且返回false,和输出流不一样,输出流对象已建立文件,文件就已经存在,会覆盖

2.删除
删除我就不说了,直接这样

file.delete();

他还有一个方法比较好玩

file.deleteOnExit();

在程序退出之后删除文件

三.判断文件存在

判断文件是否存在


import java.io.File;
import java.io.IOException;

public class HelloJJAVA {
    public static void main(String[] args) {
        // 创建File对象
        File file = new File("a.txt");
        // 判断是否存在,不存在则创建
        if (!file.exists()) {
            try {
                file.createNewFile();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }
}

这样我们就可以去判断文件是否存在且不存在就去创建文件了。

四.创建文件夹
我们继续来看怎么去创建文件夹,其实也很简单


import java.io.File;

public class HelloJJAVA {
    public static void main(String[] args) {
        // 创建File对象
        File file = new File("liuguilin");
        file.mkdir();
    }
}

OK,这样的话,就创建了,这里注意mkdir只能创建一级目录,而mkdirs可以创建多级文件夹目录

五.判断是否为文件/文件夹
有时候还是需要的

import java.io.File;

public class HelloJJAVA {
    public static void main(String[] args) {
        File file = new File("liuguilin");
        //是否为文件
        System.out.println(file.isFile());
        //是否为文件夹
        System.out.println(file.isDirectory());
    }
}

他返回的是boolean值来确定是否存在,但是这里也要记住,就是一定要确定这个文件是否存在,所以我们的流程可以这样写

import java.io.File;
import java.io.IOException;

public class HelloJJAVA {
    public static void main(String[] args) {
        File file = new File("liuguilin");
        // 判断文件是否存在
        if (file.exists()) {
            // 再去判断文件还是文件夹
            if (file.isFile()) {
                System.out.println("文件");
            } else if (file.isDirectory()) {
                System.out.println("文件夹");
            }
        } else {
            try {
                file.createNewFile();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }
}

这样逻辑是比较清晰的

六.获取信息
获取的话,我们是怎么去获取信息的呢?毫无疑问,是get,比如getNmae之类的,我们用代码里的注释来说明是比较好的

import java.io.File;

public class HelloJJAVA {
    public static void main(String[] args) {
        File file = new File("liuguilin.txt");
        File file2 = new File("haha.txt");
        // 项目路径下+文件名
        System.out.println("路径:" + file.getPath());
        // 全路径
        System.out.println("绝对路径:" + file.getAbsolutePath());
        // 最后一次修改时间
        System.out.println("时间:" + file.lastModified());
        // 绝对路径中的文件父目录,如果是相对路径,返回的为空
        System.out.println("父目录:" + file.getParent());
        // 把内容拷贝到另一个文本中并且删除自身
        System.out.println(file.renameTo(file2));
    }
}

七.文件列表
列出可用的系统目录,我们看代码

import java.io.File;

public class HelloJJAVA {
    public static void main(String[] args) {
        File[] listRoots = File.listRoots();
        for (File f : listRoots) {
            // 打印磁盘目录
            System.out.println(f);
        }
    }
}

这样我们就可以得到有效盘符了

我们可以进行改进,我们打印C盘下的所有文件

import java.io.File;

public class HelloJJAVA {
    public static void main(String[] args) {
    //必须封装了一个目录,该目录还必须存在
        File f = new File("c:\\");
        String[] list = f.list();
        for (String fi : list) {
            System.out.println(fi);
        }
    }
}

得到的肯定就是所有文件的列表咯

八.文件过滤
我们做文件夹的时候经常会用到的一个小知识点,就是过滤文件

import java.io.File;
import java.io.FilenameFilter;

public class HelloJJAVA {
    public static void main(String[] args) {
        File f = new File("c:\\");
        String[] list = f.list(new FilenameFilter() {
            // 过滤
            @Override
            public boolean accept(File dir, String name) {
                // 只返回txt后缀的文件
                return name.endsWith(".txt");
            }
        });
        for (String fi : list) {
            // 过滤
            System.out.println(fi);
        }
    }

}

九.文件递归

import java.io.File;

public class HelloJJAVA {
    public static void main(String[] args) {

        File dir = new File("E:\\AndroidDelepoer");

        showDir(dir);
    }

    private static void showDir(File dir) {
        System.out.println("目录:" + dir);
        File[] fils = dir.listFiles();
        for (int i = 0; i < fils.length; i++) {
            if (fils[i].isDirectory()) {
                showDir(fils[i]);
            } else {
                // 列出根目录
                System.out.println("files" + fils);
            }
        }

    }
}

Properties

private static void loadDemo(){
        try {
            FileInputStream fish = new FileInputStream("info.txt");
            Properties properties = new Properties();
            //将流中的数据加载进集合
            properties.load(fish);
            System.out.println(properties);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

打印流PrintWriter

•该流提供了打印方法,可以将各种数据类型原样打印

◦file对象 File
◦字符串路径 String
◦字节打印流
◦字符打印流

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;

public class HelloJJAVA {
    public static void main(String[] args) {

        try {
            BufferedReader bufr = new BufferedReader(new InputStreamReader(
                    System.in));

            PrintWriter oWriter = new PrintWriter(System.out, true);
            String line = null;
            while ((line = bufr.readLine()) != null) {
                if (line.equals("over")) {
                    break;
                }
                oWriter.write(line);
            }
            oWriter.close();
            bufr.close();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}

合并流

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.SequenceInputStream;
import java.util.Enumeration;
import java.util.Vector;

public class HelloJJAVA {
    public static void main(String[] args) {
        try {
            Vector<FileInputStream> v = new Vector<FileInputStream>();
            v.add(new FileInputStream("1.txt"));
            v.add(new FileInputStream("2.txt"));
            Enumeration<FileInputStream> elements = v.elements();
            SequenceInputStream sis = new SequenceInputStream(elements);

            FileOutputStream fos = new FileOutputStream("3.txt");

            byte[] buf = new byte[1024];
            int len = 0;
            while ((len = sis.read(buf)) != -1) {
                fos.write(buf, 0, len);
            }   

            fos.close();
            sis.close();

        } catch (FileNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}

//把1.txt和2.txt乃至add更多的内容合并到3.txt文件中,这就是流的合并

切割文件

// 切割文件
    public static void splitFile() {
        try {
            FileInputStream fis = new FileInputStream("1.jpg");
            FileOutputStream fos = null;
            byte[] buf = new byte[1024 * 1024];

            int len = 0;
            int count = 1;
            while ((len = fis.read(buf)) != -1) {
                fos = new FileOutputStream((count++) + ".patch");
                fos.write(buf, 0, len);
                fos.close();
            }

            fis.close();
        } catch (FileNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

切割完我们可以合并了

// 合并文件
    public static void merge() {
        ArrayList<FileInputStream> al = new ArrayList<>();
        for (int i = 1; i <= 2; i++) {
            try {
                al.add(new FileInputStream(i + ".patch"));
            } catch (FileNotFoundException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
        Iterator<FileInputStream> iterator = al.iterator();
        Enumeration<FileInputStream> en = new Enumeration<FileInputStream>() {

            @Override
            public boolean hasMoreElements() {
                // TODO Auto-generated method stub
                return iterator.hasNext();
            }

            @Override
            public FileInputStream nextElement() {
                // TODO Auto-generated method stub
                return iterator.next();
            }

        };
        try {
            SequenceInputStream seq = new SequenceInputStream(en);
            FileOutputStream fos = new FileOutputStream("2.jpg");

            byte[] buf = new byte[1024];

            int len = 0;

            while ((len = seq.read(buf)) != -1) {
                fos.write(buf, 0, len);
            }

            fos.close();
            seq.close();

        } catch (FileNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

小结:

1.1
ByteArrayInputStream – 把内存中的一个缓冲区作为 InputStream 使用 .
construct—
(A)ByteArrayInputStream(byte[]) 创建一个新字节数组输入流( ByteArrayInputStream ),它从指定字节数组中读取数据( 使用 byte 作为其缓冲区数组)
(B)—ByteArrayInputStream(byte[], int, int) 创建一个新字节数组输入流,它从指定字节数组中读取数据。
—mark:: 该字节数组未被复制。

1.2
StringBufferInputStream – 把一个 String 对象作为 InputStream .
construct—
StringBufferInputStream(String) 据指定串创建一个读取数据的输入流串。
注释:不推荐使用 StringBufferInputStream 方法。 此类不能将字符正确的转换为字节。
同 JDK 1.1 版中的类似,从一个串创建一个流的最佳方法是采用 StringReader 类。

1.3
FileInputStream – 把一个文件作为 InputStream ,实现对文件的读取操作
construct—
(A)FileInputStream(File name) 创建一个输入文件流,从指定的 File 对象读取数据。
(B)FileInputStream(FileDescriptor) 创建一个输入文件流,从指定的文件描述器读取数据。
(C)-FileInputStream(String name) 创建一个输入文件流,从指定名称的文件读取数据。
method —- read() 从当前输入流中读取一字节数据。
read(byte[]) 将当前输入流中 b.length 个字节数据读到一个字节数组中。
read(byte[], int, int) 将输入流中 len 个字节数据读入一个字节数组中。

1.4
PipedInputStream :实现了 pipe 的概念,主要在线程中使用 . 管道输入流是指一个通讯管道的接收端。
一个线程通过管道输出流发送数据,而另一个线程通过管道输入流读取数据,这样可实现两个线程间的通讯。
construct—
PipedInputStream() 创建一个管道输入流,它还未与一个管道输出流连接。
PipedInputStream(PipedOutputStream) 创建一个管道输入流 , 它已连接到一个管道输出流。

1.5
SequenceInputStream :把多个 InputStream 合并为一个 InputStream . “序列输入流”类允许应用程序把几个输入流连续地合并起来,
并且使它们像单个输入流一样出现。每个输入流依次被读取,直到到达该流的末尾。
然后“序列输入流”类关闭这个流并自动地切换到下一个输入流。
construct—
SequenceInputStream(Enumeration) 创建一个新的序列输入流,并用指定的输入流的枚举值初始化它。
SequenceInputStream(InputStream, InputStream) 创建一个新的序列输入流,初始化为首先 读输入流 s1, 然后读输入流 s2 。

Java IO 的一般使用原则 :

一、按数据来源(去向)分类:
1 、是文件: FileInputStream, FileOutputStream, ( 字节流 )FileReader, FileWriter( 字符 )
2 、是 byte[] : ByteArrayInputStream, ByteArrayOutputStream( 字节流 )
3 、是 Char[]: CharArrayReader, CharArrayWriter( 字符流 )
4 、是 String: StringBufferInputStream, StringBufferOuputStream ( 字节流 )StringReader, StringWriter( 字符流 )
5 、网络数据流: InputStream, OutputStream,( 字节流 ) Reader, Writer( 字符流 )

二、按是否格式化输出分:
1 、要格式化输出: PrintStream, PrintWriter

三、按是否要缓冲:
1 、要缓冲: BufferedInputStream, BufferedOutputStream,( 字节流 ) BufferedReader, BufferedWriter( 字符流 )

四、按数据格式分
1 、二进制格式(只要不能确定是纯文本的) : InputStream, OutputStream 及其所有带 Stream 结束的子类
2 、纯文本格式(含纯英文与汉字或其他编码方式); Reader, Writer 及其所有带 Reader, Writer 的子类

五、按输入输出分:
1 、输入: Reader, InputStream 类型的子类
2 、输出: Writer, OutputStream 类型的子类

六、特殊需要
1 、从 Stream 到 Reader,Writer 的转换类: InputStreamReader, OutputStreamWriter
2 、对象输入输出: ObjectInputStream, ObjectOutputStream
3 、进程间通信: PipeInputStream, PipeOutputStream, PipeReader, PipeWriter
4 、合并输入: SequenceInputStream
5 、更特殊的需要: PushbackInputStream, PushbackReader, LineNumberInputStream, LineNumberReader

RandomAccessFile

利用RandomAccessFile实现文件的多线程下载,即多线程下载一个文件时,将文件分成几块,每块用不同的线程进行下载。下面是一个利用多线程在写文件时的例子,其中预先分配文件所需要的空间,然后在所分配的空间中进行分块,然后写入:

    import java.io.FileNotFoundException;  
    import java.io.IOException;  
    import java.io.RandomAccessFile;  

    /** 
     * 测试利用多线程进行文件的写操作 
     */  
    public class Test {  

        public static void main(String[] args) throws Exception {  
            // 预分配文件所占的磁盘空间,磁盘中会创建一个指定大小的文件  
            RandomAccessFile raf = new RandomAccessFile("D://abc.txt", "rw");  
            raf.setLength(1024*1024); // 预分配 1M 的文件空间  
            raf.close();  

            // 所要写入的文件内容  
            String s1 = "第一个字符串";  
            String s2 = "第二个字符串";  
            String s3 = "第三个字符串";  
            String s4 = "第四个字符串";  
            String s5 = "第五个字符串";  

            // 利用多线程同时写入一个文件  
            new FileWriteThread(1024*1,s1.getBytes()).start(); // 从文件的1024字节之后开始写入数据  
            new FileWriteThread(1024*2,s2.getBytes()).start(); // 从文件的2048字节之后开始写入数据  
            new FileWriteThread(1024*3,s3.getBytes()).start(); // 从文件的3072字节之后开始写入数据  
            new FileWriteThread(1024*4,s4.getBytes()).start(); // 从文件的4096字节之后开始写入数据  
            new FileWriteThread(1024*5,s5.getBytes()).start(); // 从文件的5120字节之后开始写入数据  
        }  

        // 利用线程在文件的指定位置写入指定数据  
        static class FileWriteThread extends Thread{  
            private int skip;  
            private byte[] content;  

            public FileWriteThread(int skip,byte[] content){  
                this.skip = skip;  
                this.content = content;  
            }  

            public void run(){  
                RandomAccessFile raf = null;  
                try {  
                    raf = new RandomAccessFile("D://abc.txt", "rw");  
                    raf.seek(skip);  
                    raf.write(content);  
                } catch (FileNotFoundException e) {  
                    e.printStackTrace();  
                } catch (IOException e) {  
                    // TODO Auto-generated catch block  
                    e.printStackTrace();  
                } finally {  
                    try {  
                        raf.close();  
                    } catch (Exception e) {  
                    }  
                }  
            }  
        }  

    }  

Java IO的RandomAccessFile的使用 :http://blog.csdn.net/czplplp_900725/article/details/37809579

nio

nio 是non-blocking的简称,在jdk1.4 里提供的新api 。Sun 官方标榜的特性如下: 为所有的原始类型提供(Buffer)缓存支持。字符集编码解码解决方案。 Channel :一个新的原始I/O 抽象。 支持锁和内存映射文件的文件访问接口。 提供多路(non-bloking) 非阻塞式的高伸缩性网络I/O 。
Java NIO流 – 缓冲区(Buffer,ByteBuffer):http://www.cnblogs.com/youngKen/p/4923635.html

ByteBuffer

每个Buffer都有以下的属性:
byte[] buff

buff即内部用于缓存的数组。
position

当前读取的位置。
mark

为某一读过的位置做标记,便于某些时候回退到该位置。
capacity

初始化时候的容量。
limit

读写的上限,limit<=capacity。

eg:

public static void main(String [] args)
       throws IOException
    {
       // 创建一个capacity为256的ByteBuffer
       ByteBuffer buf = ByteBuffer.allocate(256);
       while (true) {
           // 从标准输入流读入一个字符
           int c = System.in.read();
           // 当读到输入流结束时,退出循环
           if (c == -1)
              break;
           // 把读入的字符写入ByteBuffer中
           buf.put((byte) c);
           // 当读完一行时,输出收集的字符
           if (c == '\n') {
              // 调用flip()使limit变为当前的position的值,position变为0,
              // 为接下来从ByteBuffer读取做准备
              buf.flip();
              // 构建一个byte数组
              byte [] content = new byte[buf.limit()];
              // 从ByteBuffer中读取数据到byte数组中
              buf.get(content);
               // 把byte数组的内容写到标准输出
              System.out.print(new String(content));
              // 调用clear()使position变为0,limit变为capacity的值,
              // 为接下来写入数据到ByteBuffer中做准备
              buf.clear();
           }
      }
    }
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,下面是一个基于GUI编程技术、I/O技术、多线程技术、网络编程技术的示例代码,它可以实现一个简单的聊天程序: ``` import java.awt.BorderLayout; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.PrintWriter; import java.net.Socket; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.JTextArea; import javax.swing.JTextField; public class ChatClient extends JFrame implements ActionListener, Runnable { private static final long serialVersionUID = 1L; private JTextArea chatArea; private JTextField chatInput; private JButton sendBtn; private PrintWriter out; private BufferedReader in; public ChatClient() { super("Chat Client"); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); setSize(400, 300); setLayout(new BorderLayout()); chatArea = new JTextArea(); chatArea.setEditable(false); add(chatArea, BorderLayout.CENTER); JPanel bottomPanel = new JPanel(); bottomPanel.setLayout(new BorderLayout()); chatInput = new JTextField(); bottomPanel.add(chatInput, BorderLayout.CENTER); sendBtn = new JButton("Send"); sendBtn.addActionListener(this); bottomPanel.add(sendBtn, BorderLayout.EAST); add(bottomPanel, BorderLayout.SOUTH); setVisible(true); try { Socket socket = new Socket("localhost", 8888); out = new PrintWriter(socket.getOutputStream(), true); in = new BufferedReader(new InputStreamReader(socket.getInputStream())); new Thread(this).start(); } catch (IOException e) { e.printStackTrace(); } } public static void main(String[] args) { new ChatClient(); } @Override public void actionPerformed(ActionEvent e) { if (e.getSource() == sendBtn) { String input = chatInput.getText(); out.println(input); chatInput.setText(""); } } @Override public void run() { try { while (true) { String msg = in.readLine(); chatArea.append(msg + "\n"); } } catch (IOException e) { e.printStackTrace(); } } } ``` 这个程序实现了一个简单的聊天客户端,它使用了Java Swing库进行GUI设计,使用了Socket进行网络通信,使用了多线程技术实现了异步消息接收,使用了I/O技术进行数据的读写。在程序运行时,它会连接到一个本地的服务器端,然后可以通过输入框向服务器端发送消息,服务器端会收到这些消息并原样返回,客户端会将这些消息显示在聊天窗口中。 希望这个示例代码对您有所帮助!

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值