参考 点击打开链接
一、根据用途的分类
二、Java IO:管道
1、示例
2、你也可以使用两个管道共有的connect()方法使之相关联。PipedInputStream和PipedOutputStream都拥有一个可以互相关联的connect()方法。
3、管道和线程:请记得,当使用两个相关联的管道流时,务必将它们分配给不同的线程。read()方法和write()方法调用时会导致流阻塞,这意味着如果你尝试在一个线程中同时进行读和写,可能会导致线程死锁。
四、Java IO:网络
1、Java网络API用来在不同进程之间建立网络连接,而Java IO则用来在建立了连接之后的进程之间交换数据。
2、具体与文件读写没有什么区别,只需要将FileInputStream变换成InputStream。
五、Java IO:读写数组(以字节数组为例,字符数组类似)
byte[] bytes = new byte[1024];
//把数据写入字节数组...
InputStream input = new ByteArrayInputStream(bytes);
//读取第一个字节
int data = input.read();
OutputStream output = new ByteArrayOutputStream();
output.write("This text is converted to bytes".toBytes("UTF-8"));
byte[] bytes = output.toByteArray();
注:input和output的对象都是内存,因此这里的数组(bytes)是数据源。
六、Java IO:System.in System.out System.err
1、JVM启动的时候通过Java运行时初始化这3个流;
2、System.err是一个PrintStream流。System.err与System.out的运行方式类似,但它更多的是用于打印错误文本;
3、替换系统流:尽管System.in, System.out, System.err这3个流是java.lang.System类中的静态成员(这3个变量均为final static常量),并且已经预先在JVM启动的时候初始化完成,你依然可以更改它们。
OutputStream output = new FileOutputStream("c:\\data\\system.out.txt");
PrintStream printOut = new PrintStream(output);
System.setOut(printOut);
System.setOut(new PrintStream(new FileOutputStream(FileDescriptor.out)));//这样重定向到标准输出流
七、并发问题:在同一时刻不能有多个线程同时从InputStream或者Reader中读取数据,也不能同时往OutputStream或者Writer里写数据
八、Try-with-resources in Java7
private static void printFileJava7() throws IOException { try(FileInputStream input = new FileInputStream("file.txt"); BufferedInputStream bufferedInput = new BufferedInputStream(input)) { int data = bufferedInput.read(); while(data != -1){ System.out.print((char) data); data = bufferedInput.read(); } } }
自定义的类型只需要实现AutoCloseable接口,即可以适用于本规则,AutoCloseable接口中只有一个Close方法。
九、InputStream 和 OutputStream
1、InputStream
try( InputStream inputstream = new FileInputStream("file.txt") ) { int data = inputstream.read();//0~255 while(data != -1){//流末尾 System.out.print((char) data); data = inputstream.read(); } }
这样的读写方式,汉字会出现乱码,因为把每一个字节都转化一个字符。
- int read(byte[])
将数据督导byte数组中,返回读了多少字节,流末尾的时候返回-1;
- int read(byte, int offset, int length)
该方法从数组的offset位置开始,并且最多将length个字节写入到数组中;几乎所有能用到这个方法的地方,都可以用上面的方法代替。
try(InputStream inputstream = new FileInputStream("c:\\data\\input-text.txt")){ byte[] data = new byte[1024]; int bytesRead = inputstream.read(data); while(bytesRead != -1) { doSomethingWithData(data, bytesRead); bytesRead = inputstream.read(data); } }
2、OutputStream
write(byte):把一个字节写进字节流中;write(byte[]):把字节数组写进字节流中;flush();
十、装饰器模式和FilterInputStream
class MyOwnInputStream extends FilterInputStream{
public MyOwnInputStream(InputStream is){
super(is);
}
public int read() throws IOException{
int c = 0;
if((c = super.read())!=-1){
if(Character.isLowerCase((char)c)){
return Character.toUpperCase(c);
}
else if(Character.isUpperCase((char)c)){
return Character.toLowerCase(c);
}
else
return c;
}
else
return -1;
}
}
public static void main(String[] args)
{
// TODO Auto-generated method stub
int c;
try{
InputStream is = new MyOwnInputStream(new BufferedInputStream(new FileInputStream("c:/file.txt")));
while((c = is.read())>=0){
System.out.print((char)c);
is.close();
}
}catch(IOException ex){
}
}
十一、File的一些API
public static void showFiles(){//列出所有的文件(包括文件夹)
File file = new File("C:/file.txt");
if(!file.exists())
{
System.out.println("文件夹不存在");
return;
}
File[] files = file.listFiles();
for(File f : files){
if(f.isDirectory()){
System.out.print("folder:"+f.getName());
}
else{
System.out.print("file:"+f.getName());
}
}
}
1、createNewFile();//目录文件存在则返回false,否则创建,那么可以创建多级目录吗?
如果路径不存在,会报错,如图
2、mkdir()单级创建目录,mkdirs创建多级目录
3、delete()可以删除多级目录吗?不可以;
递归删除目录:注意file不可以调用listFiles ,否则会报错:NullPointerException
public static void deleteDirs(File file){
if(file.isFile()||file.listFiles().length == 0){
file.delete();
}
for(File f : file.listFiles()){
if(f.isDirectory())
deleteDirs(f);
else
f.delete();
}
}