File 类的用法和 InputStream, OutputStream 的用法

前言        (红字部分要重点理解)   

    在上一篇文章中,  我们已经介绍过File类的一些用法了,这篇具体总结下。

 

 Java代码对文件内容操作:标准库中提供了很多类,是一组类,而学习一个类,先从构造方法开始,如下图:

       也就是说在构造File实例时,可以传的参数就是上图中的参数,可以是相对路径,也可以是绝对路径,如下代码:

package IO;

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

public class IODemo1 {
    public static void main(String[] args) throws IOException {
        //File file = new File("./美食.jpg"); //相对路径
        File file = new File("d:/我的相册/美食.jpg");//绝对路径
        System.out.println(file.getParent());
        System.out.println(file.getName());
        System.out.println(file.getPath());
        System.out.println(file.getCanonicalPath());
    }
}

运行结果:    

    Java代码在系统中创建一个文件: 如下代码,mkdir是创建目录(但是只能是创建一级目录),mkdirs是创建多级目录。

package IO;

import java.io.File;

public class IODemo3 {
    public static void main(String[] args) {
        File file = new File("text-dir/aaa/bbb");
        file.mkdir();
        //file.mkdir只能创建一级目录
        //创建多级目录
        file.mkdirs();
    }
}

     运行结果:

 在创建好文件之后,还可以用list方法看一下当前目录中都有哪些文件,有两种显示方式,显示的效果是一样的,只是返回的参数不同,如下代码:

public static void main1(String[] args) {
        //还可以显示文件里的内容  有两种显示方式
        File file = new File("text-dir");
        //list是以字符串数组的方式来显示
        String[] results = file.list();
        System.out.println(Arrays.toString(results));
        //listFiles是以文件数组的方式显示的
        File[] results2 = file.listFiles();
        System.out.println(Arrays.toString(results2));
    }

   运行结果:

   接下来就是Java操作文件内容了,标准库种提供了两种类,在介绍这两组类之前,要分清啥是输入和输出,认清楚方向:   下图解释了输入输出

 

   Java标准库中对操作文件内容提供了两组类:(上文已经说过普通文件的两种类型)

   1.针对文本文件,提供了一组类,统称为“字符流”  (典型代表:Reader,Writer)。

     说到流(stream)这个字可能很抽象,我们可以想想一下水流,水流的特点就是源源不断,一直流完为止,可以类比到从水龙头中放水,接100ml水可以有很多种接法,可以是一次性接100ml,也可以一次接50ml,分两次来接,也可以一次接1ml,分100次来接,但是总是要有一个单位的,比如说水龙头一次最少流一滴水,接水时再也不能少过这个基本单位了。

    字符流,基本单位就是每次最少读一个字符(这里的字符不仅仅是char类型,也可以是其他字符集的字符),也可以读多个字符(根据方法中的参数来决定),如下图,不带参数的方法默认就是读一个字符,

   注:创建File实例的时候,分割每个目录最好用 “ / ” 来表示,如果是反斜杠表示,就需要写成“\\”,因为需要转义。

package IO;

import java.io.*;

public class IODemo5 {
    public static void main(String[] args) {
        try(OutputStream outputStream = new FileOutputStream("d:/text.txt")) {
            outputStream.write(97);
            outputStream.write(98);
            outputStream.write(99);
            //此时也是一次写一个byte   read和write也可以一次读写多个字节
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    public static void main1(String[] args) throws IOException {
        //InputStream是一个抽象类,所以不能直接new对象,相当于IO操作不只是可以读写硬盘,也可以读写网卡
        //所以FileInputStream继承于InputStream,就说明此时是读系统文件
        /*InputStream inputStream = new FileInputStream("d:/text.txt");
        inputStream.close();//最后操作完文件内容一定要关闭资源,一定要记得!!很重要*/

        //此处就不用手动关闭资源了,InputStream实现了closed接口,这种写法会自动的调用关闭资源的方法
        try(InputStream inputStream =new FileInputStream("d:/text.txt")) {
            //读文件
            //read 一次返回的是一个字节
            //但是不是用byte来接收,看源码有解释,用一个-1来表示已经读完文件了
            //此处的返回值类型是int
            while (true) {
                int b = inputStream.read();
                if (b == -1) {
                    break;
                }
                System.out.println(b);
                //因为此时操作是字节流,所以输出的是对应的ASCII码值
            }

        }
    }
}

  看完上述代码,需要注意的点: (3)文件资源泄露是重点一定要重视!!

    (1)OutputStream outputStream = new FileOutputStream("d:/text.txt")  这一行代码可以看到,在new一个对象时,并没有直接new OutputStream,原因就是它是一个抽象类(可以看下源码),所以需要new 继承OutputStream类的子类。为啥它是一个抽象类呢?OutputStream就是IO,所以不只是可以读写硬盘上的文件,还可以读写网卡等等,其中FileOutputStream(文件中读写)这个子类就明确的说明了IO是要从文件中进行读写。

    (2)new一个对象在一个内存中,那咋样才能去读写硬盘中的文件呢,InputStream inputStream =new FileInputStream("d:/text.txt")这一行代码的意思就是打开文件,打开文件的意思就是让inputStream这个对象和硬盘中的("d:/text.txt")这个文件关联起来(就相当于有了一个遥控器(上一篇文章已经介绍过可以看下)),操作这个内存中的对象就相当于间接的操作硬盘中的文件了。

     (3)有打开文件就得有关闭文件,这个还真需要咱们Java程序员注意!(当然我还不是程序猿),Java不像C++一样需要手动释放资源(像内存啥的都是手动释放的),一般GC会帮我们释放资源(垃圾回收器)但是在文件操作这里,是需要我们手动进行释放的,释放的这个资源就是文件描述符,文件描述符这个概念是在进程,进程是使用PCB这样的结构来进行描述的,这里面就包含各种信息:1.pid(进程id)2.内存指针(表示当前这个进程是在、哪一部分内存中) 3.文件描述符表     (这个文件描述符表中就是一个个的文件描述符,文件描述符就是标识了当前进程都打开了哪些文件,一个文件描述符就相当于这个表中的位置,位置记载了这个文件的信息,当打开一个文件时,就会在这里边申请一个位置,文件描述符表可以当成一个数组,数组下标就是一个文件描述符,下标对应的元素就是文件在内核中的结构体的表示。)   可是这个数组的大小终究是有限的,不能无限的放这样的一个一个的文件描述符,所以就不能无限制的打开一个个文件但是又不释放资源(就是数组的那个下标),一旦数组存的元素满了,再继续打开文件,就会打开失败 -->  这个操作就交文件资源泄露。一旦文件资源泄露之后,会有很严重的后果(甚至比C++的内存泄露还要严重!!)

      但是又不用写很挫的代码,就是手动关闭文件,可以看上边代码:try(InputStream inputStream =new FileInputStream("d:/text.txt")) 用了这样的 写法,此时就不用手动关闭资源了,这个写法是try with resources(带资源的try操作) 它会在try中的代码执行完毕后自动帮助我们去关闭文件,为啥呢,我们可以看下图中的源码:OutputStream(InputStream也一样)实现了特定的Closeable接口,这个接口就是帮我们关闭文件的,也就相当于当try代码块结束后,就会自动帮助我们调用这个接口,进行文件的关闭,如果我们自己的代码实现了这个Closeable接口,也是可以用try with resources这样的语法来完成。

 

 2.针对二进制文件,提供了一组类,统称为“字节流” (典型代表:InputStream,OutputStream)

     而回到字节流中,就是从文件中读100个字节的数据,可以一次性读100个字节,也可以一次读50个字节,分两次来读,也可以一次读一个字节,分100次来读取。而字节流这个类中最小单位就是一个字节(就像是上文中的一滴水一样)。

package IO;

import java.io.*;

public class IODemo5 {
    public static void main(String[] args) {
        try(OutputStream outputStream = new FileOutputStream("d:/text.txt")) {
            outputStream.write(97);
            outputStream.write(98);
            outputStream.write(99);
            //此时也是一次写一个byte   read和write也可以一次读写多个字节
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    public static void main1(String[] args) throws IOException {
        //InputStream是一个抽象类,所以不能直接new对象,相当于IO操作不只是可以读写硬盘,也可以读写网卡
        //所以FileInputStream继承于InputStream,就说明此时是读系统文件
        /*InputStream inputStream = new FileInputStream("d:/text.txt");
        inputStream.close();//最后操作完文件内容一定要关闭资源,一定要记得!!很重要*/

        //此处就不用手动关闭资源了,InputStream实现了closed接口,这种写法会自动的调用关闭资源的方法
        try(InputStream inputStream =new FileInputStream("d:/text.txt")) {
            //读文件
            //read 一次返回的是一个字节
            //但是不是用byte来接收,看源码有解释,用一个-1来表示已经读完文件了
            //此处的返回值类型是int
            while (true) {
                int b = inputStream.read();
                if (b == -1) {
                    break;
                }
                System.out.println(b);
                //因为此时操作是字节流,所以输出的是对应的ASCII码值
            }

        }
    }
}

   此处需要注意的点:

       可能看完上述代码会有疑问:int b = inputStream.read()   无参数的read()不是一次读一个字节吗,为啥用int类型的变量来接收呢,我们可以看下源码:

 这段英文就给了我们答案:

     (1)一个字节(byte)可以表示整数的范围就是 -128 ~ +127,如果是无符号就是0 ~ 255,此时表示的范围是 0 ~ 255 ,但是后边又说了,如果读到这个文件的最后一个字节(就是读完文件时),要用 -1 来返回,也就是说要用一个byte之外的数字来返回,代表读完了这个文件,所以此时byte就超范围了,所以此时用int来接收这个read的字节。

     (2)此时我们来看运行结果:  如下图,我这read的是一个abc,为啥运行read的是二进制了呢,别忘了,我们现在介绍的是字节流,不是字符流,read的是一个个的字节,所以运行出来的这串数字就是对应文件里一个个字符的ASCII码值。

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
Java 基础核心总结》 Java 概述 什么是 Java2 Java 的特点Java 开发环境 JDK JRE Java 开发环境配置 Java 基本语法 数据型基础语法运算符 Java 执行控制流程条件语句 if 条件语句 if...else 条件语句if...else if 多分支语句switch 多分支语句 循环语句 while 循环语句do...while 循环for 循环语句 跳转语句 break 语句 continue 语句面向对象 也是-种对象对象的创建 属性和方法 构造方法 方法重载 方法的重写 初始化 的初始化 成员初始化 构造器初始化初始化顺序 数组初始化 对象的销毁 对象作用域 this 和 super 访问控制权限继承 多态组合代理 向上转型static final 接口和抽象接口 抽象异常 认 识 Exception 什么是 Throwable 常见的 Exception 与 Exception 有关的 Java 关键字 throws 和 throw try 、finally 、catch 什么是 Error 内部 创建内部集合 Iterable 接口顶层接口 ArrayList Vector LinkedList Stack HashSet TreeSet LinkedHashSet PriorityQueue HashMap TreeMap LinkedHashMap Hashtable IdentityHashMap WeakHashMap Collections 集合实现特征图 泛形 泛型的使用 用泛型表示 用泛型表示接口泛型方法 泛型通配符 反射 Class Field Method ClassLoader 枚举 枚举特性 枚举和普通-样枚举神秘之处 枚举 I/O File 基础 IO 和相关方法InputStream OutputStream Reader Writer InputStream 及其子 OutputStream 及其子Reader 及其子Writer 及其子 注解 关于 null 的几种处理方式大小写敏感 null 是任何引用型的初始值 null 只是-种特殊的值使用 Null-Safe 方法null 判断 关于思维导图 Java.IO Java.lang Java.math Java.net Java 基础核心总结 V2.0 IO 传统的 BIO BIO NIO 和 AIO 的区别什么是流 流的分 节点流和处理流 Java IO 的核心 File Java IO 流对象 字节流对象InputStream OutputStream 字符流对象Reader Writer 字节流与字符流的转换新潮的 NIO 缓冲区(Buffer)通道(Channel) 示例:文件拷贝案例 BIO 和 NIO 拷贝文件的区别操作系统的零拷贝 选择器(Selectors) 选择键(SelectionKey) 示例:简易的客户端服务器通信 集合 集合框架总览 -、Iterator Iterable ListIterator 二、Map 和 Collection 接口Map 集合体系详解 HashMap LinkedHashMap TreeMap WeakHashMap Hashtable Collection 集合体系详解 Set 接口 AbstractSet 抽象SortedSet 接口HashSet LinkedHashSet TreeSet List 接口 AbstractList 和 AbstractSequentialList Vector Stack ArrayList LinkedList Queue接口Deque 接口 AbstractQueue 抽象LinkedList ArrayDeque PriorityQueue 反射的思想及作用 反射的基本使用 获取的 Class 对象构造的实例化对象获取-个的所有信息 获取中的变量(Field) 获取中的方法(Method) 获取的构造器(Constructor) 获取注解 通过反射调用方法反射的应用场景 Spring 的 IOC 容器反射 + 抽象工厂模式 JDBC 加载数据库驱动反射的优势及缺陷 增加程序的灵活性破坏的封装性 性能损耗 代理模式 静态代理与动态代理常见的动态代理实现JDK Proxy CGLIB JDK Proxy 和 CGLIB 的对比动态代理的实际应用 Spring AOP 变量 变量汇总实例变量 实例变量的特点全局变量 静态变量 静态变量的特点变量 局部变量
android Bitmap用法总结 Bitmap用法总结 1、Drawable → Bitmap public static Bitmap drawableToBitmap(Drawable drawable) { Bitmap bitmap = Bitmap .createBitmap( drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight(), drawable.getOpacity() != PixelFormat.OPAQUE ? Bitmap.Config.ARGB_8888 : Bitmap.Config.RGB_565); Canvas canvas = new Canvas(bitmap); // canvas.setBitmap(bitmap); drawable.setBounds(0, 0, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight()); drawable.draw(canvas); return bitmap; } 2、从资源中获取Bitmap Resources res=getResources(); Bitmap bmp=BitmapFactory.decodeResource(res, R.drawable.pic); 3、Bitmap → byte[] private byte[] Bitmap2Bytes(Bitmap bm){ ByteArrayOutputStream baos = new ByteArrayOutputStream(); bm.compress(Bitmap.CompressFormat.PNG, 100, baos); return baos.toByteArray(); } 4、byte[] → Bitmap private Bitmap Bytes2Bimap(byte[] b){ if(b.length!=0){ return BitmapFactory.decodeByteArray(b, 0, b.length); } else { return null; } } 5、保存bitmap static boolean saveBitmap2file(Bitmap bmp,String filename){ CompressFormat format= Bitmap.CompressFormat.JPEG; int quality = 100; OutputStream stream = null; try { stream = new FileOutputStream("/sdcard/" + filename); } catch (FileNotFoundException e) { // TODO Auto-generated catch block Generated by Foxit PDF Creator © Foxit Software http://www.foxitsoftware.com For evaluation only. e.printStackTrace(); } return bmp.compress(format, quality, stream); } 6、将图片按自己的要求缩放 // 图片源 Bitmap bm = BitmapFactory.decodeStream(getResources() .openRawResource(R.drawable.dog)); // 获得图片的宽高 int width = bm.getWidth(); int height = bm.getHeight(); // 设置想要的大小 int newWidth = 320; int newHeight = 480; // 计算缩放比例 float scaleWidth = ((float) newWidth) / width; float scaleHeight = ((float) newHeight) / height; // 取得想要缩放的matrix参数 Matrix matrix = new Matrix(); matrix.postScale(scaleWidth, scaleHeight); // 得到新的图片 Bitmap newbm = Bitmap.createBitmap(bm, 0, 0, width, height, matrix, true); // 放在画布上 canvas.drawBitmap(newbm, 0, 0, paint); 相关知识链接:http://www.eoeandroid.com/thread-3162-1-1.html 7、bitmap的用法小结 BitmapFactory.Options option = new BitmapFactory.Options(); option.inSampleSize = 2; //将图片设为原来宽高的1/2,防止内存溢出 Bitmap bm = BitmapFactory.decodeFile("",option);//文件流 URL url = new URL(""); InputStream is = url.openStream(); Bitmap bm = BitmapFactory.decodeStream(is); android:scaleType: android:scaleType是控制图片如何resized/moved来匹对ImageView的size。ImageView.ScaleType / android:scaleType值的意义区别: CENTER /center 按图片的原来size居中显示,当图片长/宽超过View的长/宽,则截取图片的居中部分 显示 CENTER_CROP / centerCrop 按比例扩大图片的size居中显示,使得图片长(宽)等于或大于View的长 (宽) CENTER_INSIDE / centerInside 将图片的内容完整居中显示,通过按比例缩小或原来的size使得图片 长/宽等于或小于View的长/宽 Generated by Foxit PDF Creator © Foxit Software http://www.foxitsoftware.com For evaluation only. FIT_CENTER / fitCenter 把图片按比例扩大/缩小到View的宽度,居中显示 FIT_END / fitEnd 把图片按比例扩大/缩小到View的宽度,显示在View的下部分位置 FIT_START / fitStart 把图片按比例扩大/缩小到View的宽度,显示在View的上部分位置 FIT_XY / fitXY 把图片 不按比例 扩大/缩小到View的大小显示 MATRIX / matrix 用矩阵来绘制,动态缩小放大图片来显示。 //放大缩小图片 public static Bitmap zoomBitmap(Bitmap bitmap,int w,int h){ int width = bitmap.getWidth(); int height = bitmap.getHeight(); Matrix matrix = new Matrix(); float scaleWidht = ((float)w / width); float scaleHeight = ((float)h / height); matrix.postScale(scaleWidht, scaleHeight); Bitmap newbmp = Bitmap.createBitmap(bitmap, 0, 0, width, height, matrix, true); return newbmp; } //将Drawable转化为Bitmap public static Bitmap drawableToBitmap(Drawable drawable){ int width = drawable.getIntrinsicWidth(); int height = drawable.getIntrinsicHeight(); Bitmap bitmap = Bitmap.createBitmap(width, height, drawable.getOpacity() != PixelFormat.OPAQUE ? Bitmap.Config.ARGB_8888 : Bitmap.Config.RGB_565); Canvas canvas = new Canvas(bitmap); drawable.setBounds(0,0,width,height); drawable.draw(canvas); return bitmap; Generated by Foxit PDF Creator © Foxit Software http://www.foxitsoftware.com For evaluation only. } //获得圆角图片的方法 public static Bitmap getRoundedCornerBitmap(Bitmap bitmap,float roundPx){ Bitmap output = Bitmap.createBitmap(bitmap.getWidth(), bitmap .getHeight(), Config.ARGB_8888); Canvas canvas = new Canvas(output); final int color = 0xff424242; final Paint paint = new Paint(); final Rect rect = new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight()); final RectF rectF = new RectF(rect); paint.setAntiAlias(true); canvas.drawARGB(0, 0, 0, 0); paint.setColor(color); canvas.drawRoundRect(rectF, roundPx, roundPx, paint); paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN)); canvas.drawBitmap(bitmap, rect, rect, paint); return output; } //获得带倒影的图片方法 public static Bitmap createReflectionImageWithOrigin(Bitmap bitmap){ final int reflectionGap = 4; int width = bitmap.getWidth(); int height = bitmap.getHeight(); Matrix matrix = new Matrix(); matrix.preScale(1, -1); Bitmap reflectionImage = Bitmap.createBitmap(bitmap, 0, height/2, width, height/2, matrix, false); Bitmap bitmapWithReflection = Bitmap.createBitmap(width, (height + height/2), Config.ARGB_8888); Canvas canvas = new Canvas(bitmapWithReflection); canvas.drawBitmap(bitmap, 0, 0, null); Paint deafalutPaint = new Paint(); Generated by Foxit PDF Creator © Foxit Software http://www.foxitsoftware.com For evaluation only. canvas.drawRect(0, height,width,height + reflectionGap, deafalutPaint); canvas.drawBitmap(reflectionImage, 0, height + reflectionGap, null); Paint paint = new Paint(); LinearGradient shader = new LinearGradient(0, bitmap.getHeight(), 0, bitmapWithReflection.getHeight() + reflectionGap, 0x70ffffff, 0x00ffffff, TileMode.CLAMP); paint.setShader(shader); // Set the Transfer mode to be porter duff and destination in paint.setXfermode(new PorterDuffXfermode(Mode.DST_IN)); // Draw a rectangle using the paint with our linear gradient canvas.drawRect(0, height, width, bitmapWithReflection.getHeight() + reflectionGap, paint); return bitmapWithReflection; } }

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

良月初十♧

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值