1 FileOutputStream
字节输出流,数据写入本地文件
步骤
1.创建字节流输出对象
2.写数据
3.释放资源
1.1 写文字到本地文件 不包括中文
FileOutputStream fileOutputStream = new FileOutputStream("OutPutStreamTest\\a.txt");
fileOutputStream.write(111);
fileOutputStream.close();
1.2 FileOutputStream注意事项
一.创建字节输出流对象
1:参数是字符串表示的路径或者是File对象都是可以的
2:如果文件不存在会创建一个新的文件,但是要保证父级路径是存在的。
3:如果文件已经存在,则会清空文件
二.写数据 细节:write方法的参数是整数,但是实际上写到本地文件中的是整数在ASCII上对应的字符
三. 释放资源 每次使用完流之后都要释放资源
1.3 write
void write ( int b ) 一次写一个字节数据
void write ( byte [ ] b ) 一次写一个字节数组数据
void write(byte[] b, int off, int len) 一次写一个字节数组的部分数据 参数一: 数组 参数二: 起始索引 参数三: 个数
1.4 换行和续写
换行: 只需要再写如换行符 \r\n
续写: 需要打开FileOutPutStream的第二个参数append为true
2 FileInputStream
字节输入流,本地文件读取
步骤
1.创建字节输入流对象
2.读数据
3.释放资源
读取单个字节
FileInputStream fileInputStream = new FileInputStream("OutPutStreamTest\\a.txt");
int read = fileInputStream.read();
System.out.println(read);
fileInputStream.close();
循环读取文件
FileInputStream fileInputStream = new FileInputStream("OutPutStreamTest\\a.txt");
int read;
while ((read = fileInputStream.read())!=-1){
System.out.println(read);
}
fileInputStream.close();
2.1 输入流注意点
1.创建字节输入流对象
1:如果文件不存在,就直接报错。
2.写数据
1:一次读一个字节,读出来的是数据在ASCII上对应的数字
2:读到文件末尾了,read方法返回-1。
3. 释放资源
每次使用完流之后都要释放资源
练习1 读取小文件
把D:\fly\java\javabasic\OutPutStreamTest\a.txt 拷贝到D:\fly\java\javabasic\testIo\copy.txt里面
FileInputStream fileInputStream = new FileInputStream("D:\\fly\\java\\javabasic\\OutPutStreamTest\\a.txt");
FileOutputStream fileOutputStream = new FileOutputStream("D:\\fly\\java\\javabasic\\testIo\\copy.txt");
int read;
while ((read = fileInputStream.read()) != -1) {
fileOutputStream.write(read);
}
fileInputStream.close();
fileOutputStream.close();
读取多个字节
FileInputStream fileInputStream = new FileInputStream("D:\\fly\\java\\javabasic\\OutPutStreamTest\\a.txt");
byte[] bytes = new byte[3];
int len = fileInputStream.read(bytes);
System.out.println(new String(bytes, 0, len));
方法改进,增加每次读写的字节,原本的read每次只会读取一个字节
long start = System.currentTimeMillis();
// 文件拷贝,一次5字节
FileInputStream fileInputStream = new FileInputStream("D:\\fly\\java\\javabasic\\OutPutStreamTest\\a.txt");
FileOutputStream fileOutputStream = new FileOutputStream("D:\\fly\\java\\javabasic\\testIo\\copy.txt");
byte[] bytes = new byte[5 * 1024 * 1024];
int len;
while ((len = fileInputStream.read(bytes)) != -1) {
fileOutputStream.write(bytes, 0, len);
}
fileInputStream.close();
fileOutputStream.close();
long end = System.currentTimeMillis();
System.out.println(end - start);
如何避免产生乱码
- 不要用字节流读取文本文件
- 编码解码时使用同一个码表,同一个编码方式
Unicode: 汉字占三个字节,gbk: 汉字占两个字节,在读取过程中使用不同的字符集容易导致乱码
java编码两种方式
String str= "哈喽";
byte[] bytes = str.getBytes();
System.out.println(Arrays.toString(bytes));
// 指定编码格式
byte[] gbks = str.getBytes("GBK");
System.out.println(Arrays.toString(gbks));
java解码方式
String str2 = new String(bytes);
System.out.println(str2);
// 指定解码方式
String str3 = new String(bytes,"GBK");
System.out.println(str3);
3 FileReader 字符输入流
这里直接读取ch是读取的
FileReader fileReader = new FileReader("D:\\fly\\java\\javabasic\\OutPutStreamTest\\a.txt");
int ch;
while ((ch = fileReader.read()) != -1) {
System.out.print((char) ch);
}
fileReader.close();
// 有参的read: 读取数据 解码 强转 然后再把字符放到数组里面去
FileReader fileReader = new FileReader("D:\\fly\\java\\javabasic\\OutPutStreamTest\\a.txt");
int len;
char[] chars = new char[2];
while ((len = fileReader.read(chars)) != -1) {
System.out.print(new String(chars, 0, len));
}
fileReader.close();
4 FileWriter 字符输出流
FileWriter fileWriter = new FileWriter("D:\\fly\\java\\javabasic\\OutPutStreamTest\\a.txt",true);
fileWriter.write("你哈速度阿斯顿");
fileWriter.close();
5 综合练习
字节流: 拷贝任意文件
字符流: 读取任意文本,往纯文本文件写入数据
5.1 拷贝一个子文件夹,考虑子文件夹
private static void copyFolder(File file, File copyFile) throws Exception {
// 如果不存在copyfile就先创建
copyFile.mkdirs();
// 读取
File[] files = file.listFiles();
// 避免有些文件是无权限访问的
if (files != null) {
// 遍历
for (File childFile : files) {
if (childFile.isFile()) {
// 判断拷贝 文件开始 ------ 文件结束
FileInputStream fileInputStream = new FileInputStream(childFile);
// 由于复制文件需要复制到相应文件夹里面,而不是复习指导文件夹,需要获取文件名字
FileOutputStream fileOutputStream = new FileOutputStream(new File(copyFile, childFile.getName()));
byte[] bytes = new byte[1024];
int len;
while ((len = fileInputStream.read(bytes)) != -1) {
fileOutputStream.write(bytes, 0, len);
}
fileInputStream.close();
fileOutputStream.close();
} else {
copyFolder(childFile, new File(copyFile, childFile.getName()));
}
}
}
}
5.2 文件加密
加密原理: 对原始文件每一个字节进行修改,存储到新的文件夹里面
揭秘原理:读取加密之后的文件,按照加密规则反向加密,变成原始文件
采用的异或,异或两次就是原本的文件
private static void Encryption(File file) throws Exception {
// 创建对象关联文件
FileInputStream fileInputStream = new FileInputStream(file);
// 创建输出文件
FileOutputStream fileOutputStream = new FileOutputStream("D:\\fly\\java\\javabasic\\OutPutStreamTest\\encry\\encry.txt");
int len;
while ((len = fileInputStream.read()) != -1) {
fileOutputStream.write(len ^ 10);
}
fileInputStream.close();
fileOutputStream.close();
}
解密只需要将input的文件改为原本output的文件位置,输出到新的文件即可
5.3 修改文件数据 2-1-9-4-7-8 变成1-2-4-7-8-9
private static void sortNum(File file) throws Exception {
// 获取数据
FileReader fileReader = new FileReader(file);
FileWriter fileWriter = new FileWriter("D:\\fly\\java\\javabasic\\OutPutStreamTest\\encry\\numsort.txt");
StringBuilder sb = new StringBuilder();
int ch;
while ((ch = fileReader.read()) != -1) {
sb.append((char) ch);
}
fileReader.close();
System.out.println(sb);
// 排序
String str = sb.toString();
String[] split = str.split("-");
ArrayList<Integer> list = new ArrayList<>();
for (String s : split) {
list.add(Integer.parseInt(s));
}
Collections.sort(list);
// 输出数据
for (int i = 0; i < list.size(); i++) {
if (i == list.size() - 1) {
fileWriter.write(list.get(i) + "");
} else {
fileWriter.write(list.get(i) + "-");
}
}
fileWriter.close();
}
方法二
private static void sortNum2(File file) throws Exception {
// 获取数据
FileReader fileReader = new FileReader(file);
FileWriter fileWriter = new FileWriter("D:\\fly\\java\\javabasic\\OutPutStreamTest\\encry\\numsort.txt");
StringBuilder sb = new StringBuilder();
int ch;
while ((ch = fileReader.read()) != -1) {
sb.append((char) ch);
}
fileReader.close();
System.out.println(sb);
// 排序, 先将原本的通过-切割变成数组,再将数组转换为Integer元素,进行排序,转成数组
Integer[] array = Arrays.stream(sb.toString()
.split("-"))
.map(Integer::parseInt)
.sorted()
.toArray(Integer[]::new);
// 此时格式为[1,2,4,7,8,9],需要将,变成-,然后截取里面的数据部分写入
// 写入
String s = Arrays.toString(array)
.replaceAll(",", "-");
String result = s.substring(1, s.length() - 1);
fileWriter.write(result);
fileWriter.close();
}