Java I/O流(二)——File,Properties,PrintWriter,IO ,RandomAccessFile,ByteBuffer,nio
2017-04-17 20:57
696 查看
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.1ByteArrayInputStream – 把内存中的一个缓冲区作为 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(); } } }
相关文章推荐
- JAVA之旅(三十)——打印流PrintWriter,合并流,切割文件并且合并,对象的序列化Serializable,管道流,RandomAccessFile,IO其他类,字符编码
- Java 用 ByteBuffer和RandomAccessFile 写大文件
- JAVA之旅(三十)——打印流PrintWriter,合并流,切割文件并且合并,对象的序列化Serializable,管道流,RandomAccessFile,IO其他类,字符编码
- 【JAVA IO】_RandomAccessFile笔记
- java.io.RandomAccessFile
- Java--(IO)之RandomAccessFile
- Java_io体系之RandomAccessFile简介、走进源码及示例——20
- IO(打印流、序列流、ObjectStream、管道流、RandomAccessFile、DataStream、ByteArrayStream)
- java io 笔记一:RandomAccessFile(随机访问) 类
- IO流5(IO包中的其他类,ObjectStream,管道流,RandomAccessFile,DataStream,ByteArrayStream)
- Java IO-RandomAccessFile
- Java笔记5 IO<3>File、Properties、PrintWriter、合并流
- java io 笔记一:RandomAccessFile(随机访问) 类
- Java.IO.RandomAccessFile
- JAVA IO - RandomAccessFile
- java io之RandomAccessFile的用法
- Java IO体系之强大的RandomAccessFile
- 黑马程序员--javaIO 之RandomAccessFile
- Java IO _RandomAccessFile 类
- Java基础---Java---IO流-----对象的序列化、管道流、RandomAccessFile、数据类型的流对象DataStream、ByteArrayStream