Java的IO流 Li.042
Java 的 IO 流 字节流, 字节流可以操作任何数据, 计算机中存储是字节流 InputStream OutputStream 字符流, 只能操作纯字符数据, 比较方便 Reader Writer 使用IO流要导入包, 使用时要进行异常处理, 使用后要释放资源 FileInputStream 读取一个文件 import java.io.FileInputStream; import java.io.IOException; public class Demo1_FileInputStream { public static void main(String[] args) throws IOException { FileInputStream fps = new FileInputStream("test.txt"); int x; while ((x = fps.read() ) != -1){ System.out.println(x); } fps.close(); } } read() 为什么接收的int类型 因为字节输入流可以操作任意类型的文件,比如图片音频等, 这些文件底层都是以二进制形式的存储的,如果每次读取都返回byte, 有可能在读到中间的时候遇到111111111,那么这11111111是byte类型的-1, 我们的程序是遇到-1就会停止不读了,后面的数据就读不到了,所以在读取的时候用int类型接收, 如果11111111会在其前面补上24个0凑足4个字节,那么byte类型的-1就变成int类型的255了这样可以保证整个数据读完, 而结束标记的-1就是int类型 字节输出流 write() void write(int b) throws IOException 在输出时int 去掉前3个byte字节, 写入第4个byte到文件中, 这个写是覆盖 import java.io.FileOutputStream; import java.io.IOException; public class Deom2_FileOutputStream { public static void main(String[] args) throws IOException { FileOutputStream fps = new FileOutputStream("test.txt"); fps.write(100); fps.write(101); fps.write(102); fps.close(); } } 字节输出流 追加 FileOutputStream(File file, boolean append) throws FileNotFoundException 输出字节流是否选择追加 import java.io.FileOutputStream; import java.io.IOException; public class Demo3_FileOutputStream { public static void main(String[] args) throws IOException { FileOutputStream fps = new FileOutputStream("test.txt", true); fps.write(100); fps.write(101); fps.close(); } } 复制文件 byte字节读取, byte复制 import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; public class Demo4_FileInOutStream { public static void main(String[] args) throws IOException { FileInputStream fis = new FileInputStream("test.txt"); FileOutputStream fos = new FileOutputStream("copy.txt"); int b = 0; while ( (b = fis.read() )!= -1){ fos.write(b); } fis.close(); fos.close(); } } FileInputStream 的 available方法 int available() throws IOException 返回输入流的长度 import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; public class Demo5_FileInOutStream { public static void main(String[] args) throws IOException { FileInputStream fis = new FileInputStream("test.txt"); FileOutputStream fos = new FileOutputStream("copy.txt"); int len = fis.available(); byte[] arr = new byte[fis.available()]; fis.read(arr); fos.write(arr); fis.close(); fos.close(); } } 通过数组 byte[] 读取写入 import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; public class Demo6_FileInOutStream { public static void main(String[] args) throws IOException { FileInputStream fis = new FileInputStream("test.txt"); FileOutputStream fos = new FileOutputStream("copy.txt"); byte[] arr = new byte[1024 * 1024]; int b = 0; while ( (b =fis.read(arr)) != -1 ){ fos.write(arr,0,b); } fis.close(); fos.close(); } private static void errSimple() throws IOException { FileInputStream fis = new FileInputStream("test.txt"); FileOutputStream fos = new FileOutputStream("copy.txt"); byte[] arr = new byte[3]; int b = 0; while ( (b =fis.read(arr)) != -1 ){ fos.write(arr); } fis.close(); fos.close(); } } BufferedInputStream BufferedOutputStream 原码先读取1024*8个字节到内存, 复制给 BufferedOutputStream 1024*8 然后才写入文件 只需要关闭BufferedInputStream BufferedOutputStream 就能关闭所有流 import java.io.*; public class Demo7_BufferInputStream { public static void main(String[] args) throws IOException { FileInputStream fis = new FileInputStream("test.txt"); FileOutputStream fos = new FileOutputStream("copy.txt"); BufferedInputStream bis = new BufferedInputStream(fis); BufferedOutputStream bos = new BufferedOutputStream(fos); int b ; while( ( b = bis.read() ) != -1){ bos.write(b); } // 只需关闭 BufferedInputStream BufferedOutputStream bis.close(); bos.close(); } } flush和close方法的区别 flush 刷新缓冲区, 缓冲区写到文件中, 刷完可以继续写. close 关闭前 就会刷新缓冲区 将缓冲区内容存到文件中 import java.io.*; public class Demo8_FlushClose { public static void main(String[] args) throws IOException { FileInputStream fis = new FileInputStream("test.txt"); FileOutputStream fos = new FileOutputStream("copy.txt"); BufferedInputStream bis = new BufferedInputStream(fis); BufferedOutputStream bos = new BufferedOutputStream(fos); int b ; while ( (b = bis.read()) != -1 ){ bos.write(b); bos.flush(); } bis.close(); bos.close(); } } 字节流读取中文有乱码 UTF-8中英文1个字节, 中文3个字节, 按字节读取都会读出乱码 import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.nio.charset.StandardCharsets; public class Demo9_CharIO { public static void main(String[] args) throws IOException { // Demo1(); FileOutputStream fos = new FileOutputStream("chinese.txt"); fos.write("你好啊, 世界!".getBytes(StandardCharsets.UTF_8)); fos.write("\r".getBytes(StandardCharsets.UTF_8)); fos.close(); } private static void Demo1() throws IOException { FileInputStream fis = new FileInputStream("chinese.txt"); byte[] arr = new byte[3]; String s; int len ; while ( ( len=fis.read(arr) ) != -1){ System.out.println(new String(arr,0,len)); } } } 异常处理 流初始化null try 关闭流 能关闭一个就关闭一个 import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; public class Demo10_IOException { public static void main(String[] args) throws IOException{ FileInputStream fis = null; FileOutputStream fos = null; try { fis = new FileInputStream("test.txt"); fos = new FileOutputStream("copy.txt"); } finally { try{ if(null != fis){ fis.close(); } } finally { if(null != fos){ fos.close(); } } } } } 图片加密解密 加密把输出的字节异或一个数, 解密时再异或这个数 import java.io.*; public class Demo12_Encrypt { public static void main(String[] args) throws IOException { String src = "beauty.png"; String dest = "copy.png"; String dest2 = "copy1.png"; // extracted(src, dest); extracted(dest, dest2); } private static void extracted( String src, String dest) throws IOException { BufferedInputStream fis = new BufferedInputStream(new FileInputStream(src)); BufferedOutputStream fos = new BufferedOutputStream(new FileOutputStream(dest)); int b ; while ( (b = fis.read()) != -1){ fos.write(b ^ 123 ); } fis.close(); fos.close(); } } 输入文件复制到当前路径下 import java.io.*; import java.util.Scanner; public class Demo13_CopyFile { public static void main(String[] args) throws IOException { Scanner sc = new Scanner(System.in); String src = null; if(sc.hasNext()){ src = sc.nextLine(); } BufferedInputStream fis =null; int b ; BufferedOutputStream fos = null; if(src != null){ File file = new File(src); fis = new BufferedInputStream(new FileInputStream(src)); fos = new BufferedOutputStream(new FileOutputStream("./"+file.getName())); if( file.isFile()){ while ( (b = fis.read()) != -1){ fos.write(b); } } else if( file.isDirectory()){ System.out.println("文件夹无法复制"); } } fis.close(); fos.close(); } } 练习, 录入输入字符到文件中 import java.io.BufferedOutputStream; import java.io.FileOutputStream; import java.io.IOException; import java.nio.charset.StandardCharsets; import java.util.Scanner; public class Demo14_InputKey { public static void main(String[] args) throws IOException { Scanner sc = new Scanner(System.in); BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("test.txt", true)); String input = null; while ( sc.hasNext()){ input = sc.nextLine(); if( "quit".equals(input)){ break; } else{ bos.write(input.getBytes(StandardCharsets.UTF_8)); bos.write("\n".getBytes(StandardCharsets.UTF_8)); } } bos.close(); } }