黑马程序员技术交流社区

标题: IO的小问题,大虾们看看 [打印本页]

作者: 汪璨    时间: 2012-6-17 18:24
标题: IO的小问题,大虾们看看

import java.io.FileInputStream;

import java.io.FileOutputStream;
import java.io.IOException;

public class CopyPic {

        /**
         * @param args
         * @throws IOException
         * @throws IOException
         */
        public static void main(String[] args) throws IOException  {
                copyPic_1();
                copyPic_2();
        }

        public static void copyPic_1() throws IOException {
                FileInputStream fis = new FileInputStream("e:\\test\\01.jpg");
                FileOutputStream fos = new FileOutputStream("e:\\test\\llh.jpg");
                byte[] by = new byte[fis.available()];
                fis.read(by);
                //??这里为什么我不读进数组也可以呢?
                fos.write(by);
                fis.close();
                fos.close();
        }
        public static void copyPic_2() throws IOException
        {
                FileInputStream fis = new FileInputStream("e:\\test\\01.jpg");
                FileOutputStream fos = new FileOutputStream("e:\\test\\lla.jpg");
                byte[] by = new byte[1024];
                int len;//还有这里不赋值也是可以的吧,怎么看视频都要赋值的呢?
                while((len = fis.read(by)) != -1)
                {
                        fos.write(by,0,len);
                }
                fis.close();
                fos.close();
        }

}

作者: 车风波    时间: 2012-6-17 18:29
fis.read(by);这样写把整个文件都读进去了。 fis.read();是读一个字节。

不赋值应该也行吧
作者: 朝哥    时间: 2012-6-17 19:05
让我来点化点化楼主吧。
fis.read(by)是把输入流读进一个字节数组里,记住,只读一遍。
注意:如果你要读取的字节的个数小于字节数组的长度,也就是说一次性读就搞定了,是不需要要循环的。
如果楼主要读取的字节个数超过你设置的1024,因为你只读了一遍,那你再就会丢失1024后面的字节了。

明白了?
总之:不管怎样,最好用循环来读写。
作者: 朝哥    时间: 2012-6-17 19:06
这样的话能够全部读到!
作者: 黑马_张佳超    时间: 2012-6-17 19:12
fis通过read(byte[] by)将图片通过读取流存入缓冲数组中,如没有数组作为参数,fos输出流write(byte[] by)虽然能生成目的图片,不是完成的拷贝,是新创建的空的jpg文件。
int len;定义int类型的局部变量,默认赋值为0
作者: 申振华    时间: 2012-6-17 23:10
本帖最后由 申振华 于 2012-6-17 23:26 编辑

public static void copyPic_2() throws IOException
  {
                ....               
                int len;//还有这里不赋值也是可以的吧,怎么看视频都要赋值的呢?
                ...        
    }
这个len变量定义在方法内部属于局部变量。局部变量在声明时必须显示的指定初始值。
因为局部变量的生命周期很短,都存放在方法栈内存空间里,随着方法的调用结束而销毁。
作者: 邓杰    时间: 2012-6-18 03:34
1:首先可以楼主可以查阅FileInputStream的read()方法,重载的形式有两个;
a: read() 从此输入流中读取一个数据字节。 返回的是下一个数据字节;读到末尾返回-1;因此此处是可以不往里面传数组的;因此有代码也可以这样写int len=0;while((len=fis.read())!=-1){fos.write(len)} 这样也可以完成复制;相当于fis读一个字节fos写一个字节;效率比较低;为了提高效率才有了下面的重载形式
b :int read(byte[] b) 从此输入流中将最多 b.length 个字节的数据读入一个 byte 数组中。 读入缓冲区的字节总数,如果因为已经到达文件末尾而没有更多的数据,则返回 -1。这个方法的优点在于,fis先把一定数量的数据从硬盘上读取并存储在内存一个缓冲区中;然后再一次性写到硬盘上去;从而提高了效率;
举个例子给你吧。第一种方法即不定义缓冲区的方法就好比你从一个房间里往另一个房间里拿土豆;你一次从这个房间拿一个再放到另一个房间;再回来拿第二个放到房间;这时的你就是那个读取硬盘数据上的磁头;在不停的来回跑;因此效率很低;
第二种方法;就好比现在你有了一个筐;你先把土豆存到筐里装满后再一次运到另一个房间;从而提高了效率;这是的筐就是缓冲区;
第2个问题:int len;int是一局部变量。并且是基本数据类型;而基本数据类型的默认初始化值为 "0“ 因此在len 的初始化值为“0”时;写不写len=0是一样的;
写了是方便阅读;是一种良好的书写习惯;
希望我说的够详细了;可以帮到你;




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2