1200字范文,内容丰富有趣,写作的好帮手!
1200字范文 > Java集合 IO 多线程的一些知识

Java集合 IO 多线程的一些知识

时间:2018-08-30 16:44:42

相关推荐

Java集合 IO 多线程的一些知识

Java集合

集合总图概览

Collection

Collection 分为List<E>接口和Set<E>接口。

共有的常见方法

添加:

boolean add(Object obj) //添加一个元素boolean addAll(Collection all) //添加一个集合的元素

删除

boolean remove(Object obj) //删除一个元素boolean removeAll(Collection all) //删除这个集合中有的元素在本集合中的元素

判断是否存在

boolean contains(Object obj) //判断该元素是否存在boolean containsAll(Collection obj) //判断是否存在这个集合中所有的元素boolean isEmpty() //判断是否为空

取交集

boolean retainAll(Collection coll) //取交集,保留和指定的集合相同的元素,而删除不同的元素。

其它

int size() //获取集合大小Iterator iterator() //获取迭代器的首位置

迭代器使用

// it.next()代表it获取下一个元素,然后it再往前自增一位for(Iterator it = coll.iterator(); it.hasNext(); ){System.out.println(it.next());}

List<E>

List<E>接口一共有ArrayListLinkedListVector三个实现类。

ArrayList是数组,LinkedList是双向链表,Vector是同步的数组。

其共有的方法

添加

void add(int index, E element);boolean addAll(int index, Collection<? extends E> c);

删除

E remove(int index);

修改

E set(int index, E element);

获取

E get(int index); //通过元素位置获取int indexOf(Object o); //获取第一个该元素在集合中所在位置int lastIndexOf(Object o); //获取最后一个该元素所在集合中位置List<E> subList(int fromIndex, int toIndex); //获取[)区间的子List

Object[] toArray(); // 转换成数组

ListIterator<E>

ListIterator<E> listIterator(); //获取开头元素的iteratorListIterator<E> listIterator(int index); //获取指定位置的iterator

ListIterator<E>使用

ListIterator it = list.listIterator();while(it.hasNext()){Object obj = it.next();// xxx 此处写你的业务代码}// 逆序while(it.hasPrevious()){Object obj = it.previous();// xxx 此处写你的业务代码}

补充LinkedList一些独有的常用方法

LinkedList独有的方法

public void addFirst(E e) //插入元素在链表首位置public void addLast(E e) //插入元素在链表尾部位置public E removeFirst() //移除链表头部元素public E removeLast() //移除链表尾部元素public E getFirst() //获取队列中头部元素public E getLast() //获取队列中尾部元素

补充,上述三种操作add、remove、get方法有对应的offer、poll、peek方法。其溢出、空、获取不到值等情况时返回null值而不抛出异常。

public void offerFirst(E e) //插入元素在链表首位置public void offerLast(E e) //插入元素在链表尾部位置public E pollFirst() //移除链表头部元素public E pollLast() //移除链表尾部元素public E peekFirst() //获取队列中头部元素public E peekLast() //获取队列中尾部元素

Set<E>

Set用法与Collection一致。其中,HashSet底层是hash table。而TreeSet则是红黑树。

元素唯一性:通过对象的HashCodeequals方法实现的。

如果对象的hashCode值不同,那么不用判断equals方法,就直接存储到哈希表中。

如果对象的hashCode值相同,那么要再次判断对象的equals方法是否为true。

如果为true,视为相同元素,不存。如果为false,那么视为不同元素,就进行存储。

因此,我们如果要存自定义对象,则需要重写hashCode方法和equals方法

@Overridepublic int hashCode();@Overridepublic boolean equals(Object obj)

对于TreeSet,如果是自定义的类需要存储,则是需要实现Comparable接口,实现其中的Compareto方法。

//return -1; //-1表示放在红黑树的左边,即逆序输出//return 1; //1表示放在红黑树的右边,即顺序输出//return 0; //表示元素相同,仅存放第一个元素@Overridepublic int compareTo(Student s)

Map<K, V>

Map<K, V>是Java开发的一个接口。其有两个实现类,一个是HashMap,一个是TreeMap。其中,HashMap底层为哈希表。通过key计算hash值,然后去对应位置找键值对。

TreeMap底层对于key来说,是用红黑树存储的。通过红黑树去查找key,比传统的遍历搜索快得多。但是又要慢于Hash方法。

常用方法:

增加

V put(K key, V value)

删除

V remove(Object key)void clear() //清除所有键值对

查询

V get(Object key)

判断存在与否

boolean containsKey(Object key) //存在这个key与否boolean containsValue(Object value) //存在这个value与否boolean isEmpty() //map是否为空

遍历键值对需要准备

Set<Map.Entry<K, V>> entrySet() //遍历出所有的键值对,然后将他们存储到Set里面Set<K> keySet() //获取所有键的SetCollection<V> values() //获取所有value的setint size()

遍历的例子

public class Test4 {public static void main(String[] args) {HashMap<Phone,String> map = new HashMap<>();map.put(new Phone("Apple",7000),"美国");map.put(new Phone("Sony",5000),"日本");map.put(new Phone("Huawei",6000),"中国");Set<Phone> phones = map.keySet();Iterator<Phone> iterator = phones.iterator();while (iterator.hasNext()){Phone next = iterator.next();System.out.println(next.getBrand()+"=="+next.getPrice()+"=="+map.get(next));}}}//此处严谨一点,应该实现hashCode方法和equals方法。因为是自定义类做key。class Phone{private String Brand;private int Price;public Phone(String brand, int price) {Brand = brand;Price = price;}public String getBrand() {return Brand;}public void setBrand(String brand) {Brand = brand;}public int getPrice() {return Price;}public void setPrice(int price) {Price = price;}}//第二个遍历的例子public class Test4 {public static void main(String[] args) {HashMap<Phone,String> map = new HashMap<>();map.put(new Phone("Apple",7000),"美国");map.put(new Phone("Sony",5000),"日本");map.put(new Phone("Huawei",6000),"中国");Set<Map.Entry<Phone, String>> entries = map.entrySet();for (Map.Entry<Phone, String> entry : entries) {System.out.println(entry.getKey().getBrand()+"==="+entry.getKey().getPrice()+"==="+entry.getValue());}}}

Java IO

先上一张类图:

根据处理数据的不同分别为:字符流和字节流

根据数据流向不同分为:输入流和输出流

字符流和字节流

输入流:

InputStream是所有的输入字节流的父类,它是一个抽象类。

ByteArrayInputStreamStringBufferInputStreamFileInputStream是三种基本的介质流,它们分别从Byte数组、StringBuffer、和本地文件中读取数据。

PipedInputStream是从与其它线程共用的管道中读取数据,与Piped 相关的知识后续单独介绍。

ObjectInputStream和所有FilterInputStream的子类都是装饰流(装饰器模式的主角)。

输出流:

OutputStream是所有的输出字节流的父类,它是一个抽象类。

ByteArrayOutputStreamFileOutputStream是两种基本的介质流,它们分别向Byte 数组、和本地文件中写入数据。

PipedOutputStream是向与其它线程共用的管道中写入数据。

ObjectOutputStream和所有FilterOutputStream的子类都是装饰流。

节点流

节点流:直接与数据源相连,读入或读出。

直接使用节点流,读写不方便,为了更快的读写文件,才有了处理流。

父类:

InputStreamOutputStreamReaderWriter

文件:

FileInputStreamFileOutputStreamFileReaderFileWriter

数组:

ByteArrayInputStreamByteArrayOutputStreamCharArrayReaderCharArrayWriter

字符串:

StringReaderStringWriter

处理流

缓冲流

BufferedInputStreamBufferedOutputStreamBufferedReaderBufferedWriter

转换流,实现字节流与字符流之间数据的转换

InputStreamReaderOutputStreamReader

其中,转换流需要InputStream或者OutputStream作为参数。实现从字符流到字节流的转换。

这两个类的构造:

public InputStreamReader(InputStream in); //通过构造函数初始化,使用的是本系统默认的编码表GBK。public InputStreamReader(InputStream in,String charSet); //通过该构造函数初始化,可以指定编码表。public OutputStreamWriter(OutputStream out);//通过该构造函数初始化,使用的是本系统默认的编码表GBK。public OutputStreamwriter(OutputStream out,String charSet); //通过该构造函数初始化,可以指定编码表。

数据流,提供将基础数据类型写入到文件中,或者读取出来。

DataInputStreamDataOutputStream

File

File类型是对于文件进行操作的。其有六大构造函数

public File(String pathName); //指定绝对路径public File(URI uri); //指定uri地址public File(String parent, String child) //指定父文件绝对路径,子文件绝对路径public File(File parent, String child) //指定父文件,子文件相对路径

还有两个私有构造函数,因为创建File类时候用不到,因此不在这里赘述了。

第一个构造函数的例子

String filePath1 = "D:/cat.png" ;File file = new File( filePath1 ) ;

第三个构造函数例子

String parentFilePath = "E:/cat" ;String childFilePath = "small_cat.txt" ;File parent = new File(parentFilePath);parent.mkdir();//如果不存在父路径,就会抛出异常File child = new File(parentFilePath, childFilePath);try{child.createNewFile();}catch(Exception e){e.printStackTrace();}

第四个构造函数例子

String parentFilePath = "E:/cat" ;File parent = new File(parentFilePath);parent.mkdir();//文件或者目录不存在就会抛出异常File file = new File(parent, "xxx.txt");try{file.createNewFile();}catch(IOException e){e.printStackTrace();}

接下来是一些常用api:

public boolean mkdir(); //创建单级目录public boolean mkdirs(); //创建多级目录public boolean createNewFile();

public boolean exists() //文件是否存在public boolean isFile() //是否是文件public boolean isDirectory() //是否是目录public boolean isHidden() //是否隐藏(windows上可以设置某个文件是否隐藏)public boolean isAbsolute() //是否为绝对路径public boolean canRead() //是否可读public boolean canWrite() //是否可写public boolean canExecute() //是否可执行

public String getName() //获取文件的名字,只是名字,没有路径public String getParent() //获取父目录的绝对路径,返回值是一个字符串。如果文件有父目录,那么返回父目录的绝对路径,(比如:`E:\cat`) , 如果文件本身就在磁盘的根目录,那么返回磁盘的路径,(比如:`E:\`)。public File getParentFile() //获取父文件,返回值是一个File对象。public long lastModified() ; //返回文件最后一次修改的时间//上述返回值long可以直接用作Date实例的参数//long time = file.lastModified();//Date dt = new Date(time);public boolean renameTo(File file) //文件命名public long length() //返回文件的大小,单位字节public boolean delete() //删除文件public String[] list() //获取该目录下的所有的文件的名字。如果`file`为文件,返回值为`null`,在使用时记得判空;但是如果`file`为目录,那么返回这个目录下所有文件的名字,只是名字,不含路径;如果`file`是一个空目录,返回一个长度为0的数组;从上面的结果可以看出,`list()` 方法,只是对`file`为目录时有效,当`file`为一个文件的时候,该方法毫无意义。public File[] listFiles() //获取该目录下的所有的文件。如果`file`为文件,返回值为`null`,在使用时记得判空;但是如果`file`为目录,那么返回这个目录下所有的文件 ;如果`file`是一个空目录,返回一个长度为0的数组;从上面的结果可以看出,`listFiles()` 方法,只是对`file`为目录时有效,当`file`为一个文件的时候,该方法毫无意义。

最后讲一下关于FileFilterFilenameFilter的问题

FileFilter

其作用是过滤自己所需要的文件。通过任何方式。需要重写里面的accept()方法

例子:只需要该目录下所有文件夹

package com.app;import java.io.File;import java.io.FileFilter;import java.io.IOException;public class A3 {public static void main(String[] args) throws IOException {String filePath = "F:/" ;File file = new File( filePath ) ;getFile(file);}/*** 获取指定目录的所有文件夹* @param file*/private static void getFile( File file ){MyFileFilter myFileFilter = new MyFileFilter() ;File[] files = file.listFiles( myFileFilter ) ;for( File f : files ){if ( f.isHidden() ) continue ;System.out.println( f.getAbsolutePath() );}}static class MyFileFilter implements FileFilter {MyFileFilter(){}//pathname:文件的绝对路径+ 文件名 , 比如:F:\安来宁 - 难得.mp3 , 或者: F:\文件夹1@Overridepublic boolean accept(File pathname) {if( pathname.isDirectory() ){return true ;}return false;}}}

FilenameFilter

一样的,重写accept()方法。这是通过名字过滤。

package com.app;import java.io.File;import java.io.FilenameFilter;import java.io.IOException;public class A3 {public static void main(String[] args) throws IOException {String filePath = "F:/" ;File file = new File( filePath ) ;getFile(file);}/*** 扫描出指定路径的所有图片* @param file*/private static void getFile( File file ){MyFilenameFilter myFileFilter = new MyFilenameFilter( ".png") ;File[] files = file.listFiles( myFileFilter ) ;for( File f : files ){if ( f.isHidden() ) continue ;System.out.println( f.getAbsolutePath() );}}static class MyFilenameFilter implements FilenameFilter {//type为需要过滤的条件,比如如果type=".jpg",则只能返回后缀为jpg的文件private String type; MyFilenameFilter( String type){this.type = type ;}@Overridepublic boolean accept(File dir, String name) {//dir表示文件的当前目录,name表示文件名;return name.endsWith( type ) ;}}}

缓冲流

缓冲流分为InputStreamOutputStream这两种流。其中,这两种流又有其各自的子类,分别为BufferedInputStreamBufferedOutputStream这两种。这两种是用来封装对应的节点流的。因为直接操作节点流会对磁盘IO产生很大的影响。因此,我们需要一个缓冲区来对节点流进行封装,让磁盘IO次数减少。

BufferedInputStream

BufferedInputStream的作用是为另一个输入流添加一些功能,例如,提供“缓冲功能”以及支持mark()标记和reset()重置方法。

BufferedInputStream本质上是通过一个内部缓冲区数组实现的。例如,在新建某输入流对应的BufferedInputStream后,当我们通过read()读取输入流的数据时,BufferedInputStream会将该输入流的数据分批的填入到缓冲区中。每当缓冲区中的数据被读完之后,输入流会再次填充数据缓冲区;如此反复,直到我们读完输入流数据位置。

BufferedInputstream常用Api

类具有的字段:

private static int defaultBufferSize = 8192;//内置缓存字节数组的大小 8KBprotected volatile byte buf[]; //内置缓存字节数组protected int count;//当前buf中的字节总数、注意不是底层字节输入流的源中字节总数protected int pos;//当前buf中下一个被读取的字节下标protected int markpos = -1;//最后一次调用mark(int readLimit)方法记录的buf中下一个被读取的字节的位置protected int marklimit;//调用mark后、在后续调用reset()方法失败之前云寻的从in中读取的最大数据量、用于限制被标记后buffer的最大值

构造函数:

BufferedInputStream(InputStream in) //使用默认buf大小、底层字节输入流构建bis BufferedInputStream(InputStream in, int size) //使用指定buf大小、底层字节输入流构建bis

常用api:

int available(); //返回底层流对应的源中有效可供读取的字节数void close(); //关闭此流、释放与此流有关的所有资源 boolean markSupport(); //查看此流是否支持markvoid mark(int readLimit); //标记当前buf中读取下一个字节的下标 int read(); //读取buf中下一个字节 int read(byte[] b, int off, int len); //读取buf中下一批字节数据 void reset(); //重置最后一次调用mark标记的buf中的位子 long skip(long n); //跳过n个字节、 不仅仅是buf中的有效字节、也包括in的源中的字节

BufferedOutputStream

BufferedOutputStream是用作输出缓冲作用所用的一种流,我们在用完它之后需要关闭这个流对象。所以要注意在使用BufferedOutputStream写完数据后,要调用flush()方法或close()方法,强行将缓冲区中的数据写出。否则可能无法写出数据。

常用api:

protected byte[] buf; //内置缓存字节数组、用于存放程序要写入out的字节 protected int count; //内置缓存字节数组中现有字节总数

构造函数:

BufferedOutputStream(OutputStream out); //使用默认大小、底层字节输出流构造bos。默认缓冲大小是 8192 字节( 8KB )BufferedOutputStream(OutputStream out, int size); //使用指定大小、底层字节输出流构造bos

常用方法及close()方法

//在这里提一句,`BufferedOutputStream`没有自己的`close`方法,当他调用父类`FilterOutputStrem`的方法关闭时,会间接调用自己实现的`flush`方法将buf中残存的字节flush到out中,再`out.flush()`到目的地中,DataOutputStream也是如此。 void flush(); //将写入bos中的数据flush到out指定的目的地中、注意这里不是flush到out中、因为其内部又调用了out.flush() write(byte b);//将一个字节写入到buf中 write(byte[] b, int off, int len);//将b的一部分写入buf中

BufferedOutputStream在调用close()时,会一同调用flush()方法。因此为什么要在try-catch-finally代码块调用close(),就是确保数据不要因为没有输出到文件、内存而被JVM清理了。

调用BufferedOutputStreamclose()方法时,也会关闭OutputStream流。因为在close()方法中,调用了flush()方法。因此就会关闭并且将在缓冲区的数据刷写出输出流。

因此,在关闭处理流时,节点流也一同关闭了。

例子:

public class A3 {public static void main(String[] args) throws IOException {String filePath = "F:/123.png" ;String filePath2 = "F:/abc.png" ;File file = new File( filePath ) ;File file2 = new File( filePath2 ) ;copyFile( file , file2 );}/*** 复制文件* @param oldFile* @param newFile*/public static void copyFile( File oldFile , File newFile){InputStream inputStream = null ;BufferedInputStream bufferedInputStream = null ;OutputStream outputStream = null ;BufferedOutputStream bufferedOutputStream = null ;try {inputStream = new FileInputStream( oldFile ) ;bufferedInputStream = new BufferedInputStream( inputStream ) ;outputStream = new FileOutputStream( newFile ) ;bufferedOutputStream = new BufferedOutputStream( outputStream ) ;byte[] b=new byte[1024]; //代表一次最多读取1KB的内容int length = 0 ; //代表实际读取的字节数while( (length = bufferedInputStream.read( b ) )!= -1 ){//length 代表实际读取的字节数bufferedOutputStream.write(b, 0, length );}//缓冲区的内容写入到文件bufferedOutputStream.flush();} catch (FileNotFoundException e) {e.printStackTrace();}catch (IOException e) {e.printStackTrace();}finally {if( bufferedOutputStream != null ){try {bufferedOutputStream.close();} catch (IOException e) {e.printStackTrace();}}if( bufferedInputStream != null){try {bufferedInputStream.close();} catch (IOException e) {e.printStackTrace();}}if( inputStream != null ){try {inputStream.close();} catch (IOException e) {e.printStackTrace();}}if ( outputStream != null ) {try {outputStream.close();} catch (IOException e) {e.printStackTrace();}}}}}

reader 与 writer类字符流

类的继承关系

Reader

|__ BufferedReader、StringReader、InputStreamReader|__ FileReader

Writer

|__ BufferedWriter、StringWriter、OutputStreamWriter|__ FileWriter

BufferedReader

构造函数

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

方法

int read() //读取单个字符。int read(char[] cbuf, int off, int len) //将字符读入数组的某一部分。String readLine() //读取一个文本行。boolean ready() //判断此流是否已准备好被读取。void reset() //将流重置到最新的标记。long skip(long n) //跳过字符。void close() //关闭该流并释放与之关联的所有资源。void mark(int readAheadLimit) //标记流中的当前位置。boolean markSupported() //判断此流是否支持 mark() 操作(它一定支持)。

BufferedWriter

构造函数

BufferedWriter(Writer out, int sz) //创建一个使用给定大小输出缓冲区的新缓冲字符输出流。BufferedWriter(Writer out) //建一个使用默认大小输出缓冲区的缓冲字符输出流。

方法

void close() // 关闭此流,但要先刷新它。void flush() //刷新该流的缓冲。void newLine() //写入一个行分隔符。void write(char[] cbuf, int off, int len) //写入字符数组的某一部分。void write(int c) //写入单个字符。void write(String s, int off, int len) //写入字符串的某一部分。

总体例子:

public class A4 {public static void main(String[] args) {String filePath = "F:/123.txt" ;String filePath2 = "F:/abc.txt" ;File file = new File( filePath ) ;File file2 = new File( filePath2 ) ;copyFile( file , file2 );}private static void copyFile( File oldFile , File newFile ){Reader reader = null ;BufferedReader bufferedReader = null ;Writer writer = null ;BufferedWriter bufferedWriter = null ;try {reader = new FileReader( oldFile ) ;bufferedReader = new BufferedReader( reader ) ;writer = new FileWriter( newFile ) ;bufferedWriter = new BufferedWriter( writer ) ;String result = null ; //每次读取一行的内容while ( (result = bufferedReader.readLine() ) != null ){bufferedWriter.write( result ); //把内容写入文件bufferedWriter.newLine(); //换行,result 是一行数据,所以没写一行就要换行 }bufferedWriter.flush(); //强制把数组内容写入文件} catch (FileNotFoundException e) {e.printStackTrace();}catch (IOException e) {e.printStackTrace();}finally {try {bufferedWriter.close(); //关闭输出流} catch (IOException e) {e.printStackTrace();}}}}

InputStreamReader 和 OutputStreamReader转换流

这两个流可以从字节向字符的转变。因此,我们可以用其进行包装一些字节流。同时这两个流可以被缓冲流所包装,对其进行缓冲。

类的继承关系

Reader|__ BufferedReader、StringReader、InputStreamReader|__ FileReader

Writer|__ BufferedWriter、StringWriter、OutputStreamWriter|__ FileWriter

InputStreamReader简介

InputStreamReader是字符流Reader的子类,是字节流通向字符流的桥梁。你可以在构造器重指定编码的方式,如果不指定的话将采用底层操作系统的默认编码方式,例如GBK等。要启用从字节到字符的有效转换,可以提前从底层流读取更多的字节,使其超过满足当前读取操作所需的字节。一次只读一个字符。

InputStreamReader构造函数

InputStreamReader(Inputstream in) //创建一个使用默认字符集的 InputStreamReader。InputStreamReader(Inputstream in,Charset cs) //创建使用给定字符集的 InputStreamReader。InputStreamReader(InputStream in, CharsetDecoder dec) //创建使用给定字符集解码器的 InputStreamReader。InputStreamReader(InputStream in, String charsetName) //创建使用指定字符集的 InputStreamReader。

一般方法

void close() // 关闭该流并释放与之关联的所有资源。StringgetEncoding() //返回此流使用的字符编码的名称。int read() //读取单个字符。int read(char[] cbuf, int offset, int length) //将字符读入数组中的某一部分。boolean ready() //判断此流是否已经准备好用于读取。

OutputStreamWriter简介

OutputStreamWriter是字符流Writer的子类,是字符流通向字节流的桥梁。每次调用write()方法都会导致在给定字符(或字符集)上调用编码转换器。在写入底层输出流之前,得到的这些字节将在缓冲区中累积。一次只写一个字符。

OutputStreamWriter构造函数

OutputStreamWriter(OutputStream out) //创建使用默认字符编码的 OutputStreamWriterOutputStreamWriter(OutputStream out, String charsetName) //创建使用指定字符集的 OutputStreamWriter。OutputStreamWriter(OutputStream out, Charset cs) //创建使用给定字符集的 OutputStreamWriter。OutputStreamWriter(OutputStream out, CharsetEncoder enc) //创建使用给定字符集编码器的 OutputStreamWriter。

一般方法

void write(int c) //写入的字符长度void write(char cbuf[]) //写入的字符数组void write(String str) //写入的字符串void write(String str, int off, int len) //应该写入的字符串,开始写入的索引位置,写入的长度void close() //关闭该流并释放与之关联的所有资源。

需要注意的事项

InputStreamReaderOutputStreamWriter实现从字节流到字符流之间的转换,使得流的处理效率得到提升,但是如果我们想要达到最大的效率,我们应该考虑使用缓冲字符流包装转换流的思路来解决问题。比如:

BufferedReader in = new BufferedReader(new InputStreamReader(System.in));

实例:

public class A5 {public static void main(String[] args) {String filePath = "F:/123.txt" ;String filePath2 = "F:/abc.txt" ;File file = new File( filePath ) ;File file2 = new File( filePath2 ) ;copyFile( file , file2 );}private static void copyFile( File oldFile , File newFile ){InputStream inputStream = null ;InputStreamReader inputStreamReader = null ;OutputStream outputStream = null ;OutputStreamWriter outputStreamWriter = null ;try {inputStream = new FileInputStream( oldFile ) ; //创建输入流inputStreamReader = new InputStreamReader( inputStream ) ; //创建转换输入流outputStream = new FileOutputStream( newFile ) ; //创建输出流outputStreamWriter = new OutputStreamWriter( outputStream ) ; //创建转换输出流int result = 0 ;while( (result = inputStreamReader.read()) != -1){//一次只读一个字符outputStreamWriter.write( result ); //一次只写一个字符}outputStreamWriter.flush(); //强制把缓冲写入文件} catch (FileNotFoundException e) {e.printStackTrace();}catch (IOException e) {e.printStackTrace();}finally{if ( outputStreamWriter != null) {try {outputStreamWriter.close();} catch (IOException e) {e.printStackTrace();}}if ( inputStreamReader != null ) {try {inputStreamReader.close();} catch (IOException e) {e.printStackTrace();}}}}}

ByteArrayInputStream、ByteArrayOutputStream

这两个流是用来将字节数组和输入输出流互相转化的。

其中,ByteArrayInputStream是用来将字节数组转化为输入流。ByteArrayOutputStream是用来将内存缓冲区转化为字节数组输出。

ByteArrayInputStream

构造函数:

public ByteArrayInputStream(byte buf[])public ByteArrayInputStream(byte buf[], int offset, int length)

一般方法

void close() // 关闭该流并释放与之关联的所有资源。StringgetEncoding() //返回此流使用的字符编码的名称。int read() //读取单个字符。int read(char[] cbuf, int offset, int length) //将字符读入数组中的某一部分。boolean ready() //判断此流是否已经准备好用于读取。

关于简化文件的一些操作,Apache基金会发布了FileUtils这个工具类。因此,我们可以使用这个工具类,简化我们对文件的crud。

其maven导入:

<dependency><groupId>commons-io</groupId><artifactId>commons-io</artifactId><version>2.8.0</version></dependency>

具体用法参见:

FileUtils的一些用法,链接到别人博客

多线程

由于篇幅过大,多线程移步这一个博客"Java多线程"

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。