Java中的IOStream
前言
Java中的IOStream也就是所说的IO流,但是每当我听到流这个词的时候,就不由自主的想到河水。。它和河水有什么关系呢,IOStream更直观的理解就是数据输入输出时传输的通道,这里的流也就是只数据吧,而且在传输中它不是简单的静态传输(不懂什么是静什么是动),才用了流这个字吧。
关于数据的输入和输出,在这里是相对于Java程序而言。比如我现在通过敲键盘输入的字符如果传到了Java程序中,就是Java程序的输入啦。而输出则更常见,比如最开始时我们使用的System.out.println()就是把Java程序运行的结果输出到了控制台。然而,其实我们更常见的数据输入输出的形式应该是文件(File),不管是.txt,.jpg,.doc,都是文件。在Java里甚至把文件夹也归到了File类里。所以这里先要学习File这个类了,毕竟后面的数据的IO大部分是通过文件来实现的。也不要有压力啊,秉持着万物皆对象的真理,不过是对各种方法的作用熟悉而已。
Java中的File类
主要学习File类的构造函数和类中的方法,其中File构造函数有四种,这里只讨论其中的三种,另一种涉及到URL,也还有好多方法没有列出,详细信息可参考jdk文档。
File(String pathname)
如下程序,就是将路径为pathname的文件夹或文件夹变成Java可以操作的对象。如果文件或文件夹不存在也没有关系,因为后面可以通过file中其他方法来创建它。后面的代码段省略import和package以简化。
package learn;
import java.io.File;
public class StreamLearnDemo {
public static void main(String[] arg) {
File file = new File("G:\\eclipse\\workspace\\Javalearn1\\src\\JavaCreatDir");
}
}
File(File parent, String child)
就是parent是文件夹,然后可以把这个文件夹里的文件给变成java可以操作的对象
public class StreamLearnDemo {
public static void main(String[] arg) {
File file = new File("G:\\eclipse\\workspace\\Javalearn1\\src\\JavaCreatDir");
File file2 = new File(file,"a.txt")
}
}
File(String parent, String child)
大同小异,无非前面的parent是父文件夹,后面的child是里面的子文件夹或文件。这个就不贴代码啦。
mkdir()
创建一个新的文件夹。如下程序,运行程序后会在G:\eclipse\workspace\Javalearn1\src"路径下新建一个名为JavaCreatDir的文件夹。
public class StreamLearnDemo {
public static void main(String[] arg) {
File file = new File("G:\\eclipse\\workspace\\Javalearn1\\src\\JavaCreatDir");
file.mkdir();
}
}
mkdirs()
创建一个新的多级文件夹,如下程序,运行程序后会在G:\eclipse\workspace\Javalearn1\src"路径下新建一个名为JavaCreatDir的文件夹。并在JavaCreatDir文件夹下有子文件夹1,子文件夹下还有子文件夹2。
public class StreamLearnDemo {
public static void main(String[] arg) {
File file = new File("G:\\eclipse\\workspace\\Javalearn1\\src\\JavaCreatDir\\1\\2");
file.mkdirs();
}
}
你如果直接通过mkdir()创建多级文件夹是不会成功的,只有mkdirs()可以。
creatNewFile()
创建新文件嘛。
public class StreamLearnDemo {
public static void main(String[] arg) throws IOException {
File file = new File("G:\\eclipse\\workspace\\Javalearn1\\src\\JavaCreatDir\\1\\2\\1.txt");
file.createNewFile();
}
delete()
删除文件嘛。
public class StreamLearnDemo {
public static void main(String[] arg) throws IOException {
File file = new File("G:\\eclipse\\workspace\\Javalearn1\\src\\JavaCreatDir\\1\\2\\1.txt");
file.delete();
}
renameTo(File dest)
重命名文件,这时dest必须是完整的文件路径加新的文件名。如果设置了新的文件路径,就会把当前的文件移动到新的文件夹中。有些方法需要异常。
public class StreamLearnDemo {
public static void main(String[] arg) throws IOException {
File file = new File("G:\\eclipse\\workspace\\Javalearn1\\src\\JavaCreatDir\\1\\2\\1.txt");
File rename = new File("G:\\eclipse\\workspace\\Javalearn1\\src\\JavaCreatDir\\1\\2\\rename1.txt");
file.renameTo(rename);
}
}
判断功能的方法
File类里有一些具有判断功能的方法,但有些并不常用。下面随便列出了几个。
isHidden():是否是隐藏文件
exists():是否存在
canRead():是否可读
canExecute():是否可执行
canWrite():是否可写
IO流
对于IO流,我们也可以把它说成是IO管道。它就相当于在程序和文件(或者其他要输入输出的地方)之间的一条管道,而数据因为有了这条管道的存在而可以进行传输,也就是输入输出。在Java中,有InputStream、OutputStream、Reader、Writer这四个原始的控制IO流的类。分别对字节输入、字节输出、字符输入、字符输出流。然而它们都是抽象类,不可以实例化。事实上,实际的IO流又分了很多类,比如文件流、缓存流等等,这些流则是可以实例化的。下面通过文件流进行举例
文件流
在说到Java里File类时,不知你有么有好奇为什么没有写向文件里写数据的方法,反正我是在jdk文档里找了一遍没找到。这就是因为我们缺少连接Java程序和文件里数据的通道,也就是文件流。与前面类比,Java定义了FileInputStream、FileOutputStream、FileReader、FileWriter这四个类以方便我们创建这个通道。
FileOutputStream
下面利用FileOutputStream对文件进行写入数据,但首先要明白,它代表的是字节流,如果你想要将字符写入文件,需要将字符转成字节形式。其实也不用担心,String类给我们提供字符转字节方法getBytes()。
public class StreamLearnDemo {
public static void main(String[] arg) throws IOException {
File file = new File("G:\\eclipse\\workspace\\Javalearn1\\src\\JavaCreatDir\\1.txt");//建文件
String strData = "Hellow world,crush it";
FileOutputStream outStream = new FileOutputStream(file);//创建流对象
byte[] byteData = strData.getBytes();//字符转字节
outStream.write(byteData);//写数据
outStream.close();//关闭流
}
}

可以稍微分析一下程序,首先建立一个txt文件。然后创建了流对象。这个时候可以发现创建是需要输入参数file,可以理解这就是为了将流管道的一端怼到文件,而管道的另一端是在java程序,所以这时可以通过流对象来传输数据了。用流中的write方法就可以将依据转换好的字节流写入txt文件了。最后记得要关闭流,在这里程序结束流是会自动关闭,但是如果有的程序是要一直循环运行的,这时你不关闭它,就会出现大问题。所以养成习惯,用完就关了。
下面可以详细讨论一下FileOutputStream类中的write方法。writer方法可以有三种不同的输入参数。
- write(byte[] b);这种前面已经用过,代表写字节数据
- write(byte[] b, int off, int len);代表从byte[off]开始写入len个字节的数据,
- write(int b);写一个字节的数据,这个数据为b。
第一种就不看了,第三种自己可以试验一下挺简单,比如把b设成65,文件里就会被写入字符A,因为A的ASCII码是65。这里详细看一下第二种吧,如下程序:
public class StreamLearnDemo {
public static void main(String[] arg) throws IOException {
File file = new File("G:\\eclipse\\workspace\\Javalearn1\\src\\JavaCreatDir\\1.txt");
String strData = "Hellow world,crush it";
FileOutputStream outStream = new FileOutputStream(file);
byte[] byteData = strData.getBytes();
outStream.write(byteData,2,2);
outStream.close();
}
}

看完运行的结果不知道你有没有一丝疑问,反正我有一点。我用了outStream.write(byteData,1,2);,这应该代表取byteData里面的第3、4两个字节,然而Java的字符类型不是应该占2个字节的吗,按道理输出应该是一个e这一个字符的啊。网上查了一下,大概结果是,使用getBytes()时默认返回的就是UTF-8时的字符编码。可以参考这里。而当我将getBytes()改成getBytes(UTF-16)时,结果确实是有相应变化的。
FileInputStream
从File中以字节的方式读数据的方法,如下程序,最开始我在1.txt中输入了ABC三个字母,可以知道读入的是这三个字母的ASCII码值。
public class StreamLearnDemo {
public static void main(String[] arg) throws IOException {
File file = new File("G:\\eclipse\\workspace\\Javalearn1\\src\\JavaCreatDir\\1.txt");
FileInputStream inputStream = new FileInputStream(file);
byte[] byteData = new byte[1024];
inputStream.read(byteData);
inputStream.close();
for(int i=0; i<3; i++)
System.out.println(byteData[i]);
}
}

当然,这里的.read方法也可以根据不同的输入参数重载,与.write方法应该差不多吧。读入一个字节的read(),读入byte.length个字节的read(byte[] b),还有这个read(byte[] b, int off, int len),看前面的write方法应该就知道它的意思了吧。
这个流就先告一段落吧,主要是为了编一个TCP聊天的程序。后面什么缓存流用到时在写。~~~~~
582

被折叠的 条评论
为什么被折叠?



