发表于: 2021-02-04 23:44:16

1 1103


今天完成的事情:

I\O流学习

字节流的输入,输出

字符流的输入,输出

缓冲流和转换流

标准的输入输出流

打印流

数据流

了解基本概念


明天计划的事情:

写留言的回复,根据ip自动分配姓名



遇到的问题:

在IDEA中Spring MVC实现图片上传并显示

======

写一个工具类

package com.kbk.util;


import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.util.*;

public class ImageUtil {

// 上传图片,尝试后发现视频也可以上传
   public static String upload(MultipartFile pictureFile) throws IOException {
// 装配图片地址
       String imgPath = null;
       // 判断pictureFile不为空,则上传图片
       if (pictureFile != null) {
// 设置图片上传路径,我是将图片存在本地的文件夹中
           String path = "D:\\repository\\SpringMVCLayer\\kbk_parent\\kbk_controller\\src\\main\\webapp\\images123";
           // 获取上传的文件名全称
           String fileName=pictureFile.getOriginalFilename();
           // 获取上传文件的后缀名
           String suffix=fileName.substring(fileName.lastIndexOf("."));

           // 使用 UUID 给图片重命名,并去掉四个“-”
           String newFileName = UUID.randomUUID().toString().replaceAll("-", "")+suffix;

           // 检验文件夹是否存在,不存在则创建一个文件夹,即路径必须正确
           isFolderExists(path);

           // 将重名命后的图片上传到图片上传路径
           pictureFile.transferTo(new File(path, newFileName));
           // 装配后的图片地址,包含图片名称、后缀,若使用nginx代理,则不加虚拟路径
           imgPath = newFileName;
       }
return imgPath;
   }

// 验证文件夹是否存在,不存在则创建一个文件夹,即路径必须正确
   public static boolean isFolderExists(String path) {
File file = new File(path);
       boolean mkdir = file.mkdir();
       if(mkdir){
System.out.println("创建成功");
       }else {
System.out.println("创建失败");
       }
return true;
   }
}

==========

/**
* post
* 添加banner列表
*
* @return banner
*/
// 添加banner接口,因为multipartFile需要用form-data格式表单处理数据,这里banner就不需要用@RequestBody注解
@RequestMapping(value = "/api/banner/add",method = RequestMethod.POST)
@ResponseBody
public Map<String,Object> insertBanner(@RequestParam("uploadFile")MultipartFile multipartFile,Banner banner) throws IOException {
// 调用 ImageUtil 类的图片上传方法,返回图片的上传路径
   String coverName = ImageUtil.upload(multipartFile);

   banner.setCover(coverName);

//   banner.setUrl(banner.getUrl());
//   banner.setUpdateBy(banner.getUpdateBy());

   banner.setStatus(false);
   banner.setCreatedTime(System.currentTimeMillis());
   banner.setUpdateTime(System.currentTimeMillis());

   Boolean flag = bannerService.insertSelective(banner);

   if(flag == true){
return Restful.set(200, "查询banner成功", banner);
   }else {
return Restful.set(404, "查询banner失败");
   }
}

postman测试:

IDEA结果:




收获:

File类的写出,创建文件目录

    //read()操作升级:使用read的重载方法
   @Test
   public void testFileReader1() {
FileReader fr = null;
       try {
//1.File类的实例化
           File file = new File("hello.txt");

           //2.FileReader流的实例化
           fr = new FileReader(file);

           //3.读入的操作
           //read(char[] cbuf):返回每次读入cbuf数组中的字符的个数。如果达到文件末尾,返回-1
           char[] cbuf = new char[5];
           int len;
           while((len = fr.read(cbuf)) != -1){
//方式一:
               //错误的写法
//                for(int i = 0;i < cbuf.length;i++){
//                    System.out.print(cbuf[i]);
//                }
               //正确的写法
//                for(int i = 0;i < len;i++){
//                    System.out.print(cbuf[i]);
//                }
               //方式二:
               //错误的写法,对应着方式一的错误的写法
//                String str = new String(cbuf);
//                System.out.print(str);
               //正确的写法
               String str = new String(cbuf,0,len);
               System.out.print(str);
           }
} catch (IOException e) {
e.printStackTrace();
       } finally {
if(fr != null){
//4.资源的关闭
               try {
fr.close();
               } catch (IOException e) {
e.printStackTrace();
               }

}
}

}
/*
   从内存中写出数据到硬盘的文件里。

   说明:
   1. 输出操作,对应的File可以不存在的。并不会报异常
   2.
        File对应的硬盘中的文件如果不存在,在输出的过程中,会自动创建此文件。
        File对应的硬盘中的文件如果存在:
               如果流使用的构造器是:FileWriter(file,false) / FileWriter(file):对原有文件的覆盖
               如果流使用的构造器是:FileWriter(file,true):不会对原有文件覆盖,而是在原有文件基础上追加内容

    */
   @Test
   public void testFileWriter() {
FileWriter fw = null;
       try {
//1.提供File类的对象,指明写出到的文件
           File file = new File("hello1.txt");

           //2.提供FileWriter的对象,用于数据的写出
           fw = new FileWriter(file,false);

           //3.写出的操作
           fw.write("I have a dream!\n");
           fw.write("you need to have a dream!");
       } catch (IOException e) {
e.printStackTrace();
       } finally {
//4.流资源的关闭
           if(fw != null){

try {
fw.close();
               } catch (IOException e) {
e.printStackTrace();
               }
}
}


}

@Test
   public void testFileReaderFileWriter() {
FileReader fr = null;
       FileWriter fw = null;
       try {
//1.创建File类的对象,指明读入和写出的文件
           File srcFile = new File("hello.txt");
           File destFile = new File("hello2.txt");

           //不能使用字符流来处理图片等字节数据
//            File srcFile = new File("爱情与友情.jpg");
//            File destFile = new File("爱情与友情1.jpg");


           //2.创建输入流和输出流的对象
           fr = new FileReader(srcFile);
           fw = new FileWriter(destFile);


           //3.数据的读入和写出操作
           char[] cbuf = new char[5];
           int len;//记录每次读入到cbuf数组中的字符的个数
           while((len = fr.read(cbuf)) != -1){
//每次写出len个字符
               fw.write(cbuf,0,len);

           }
} catch (IOException e) {
e.printStackTrace();
       } finally {
//4.关闭流资源
           //方式一:
//            try {
//                if(fw != null)
//                    fw.close();
//            } catch (IOException e) {
//                e.printStackTrace();
//            }finally{
//                try {
//                    if(fr != null)
//                        fr.close();
//                } catch (IOException e) {
//                    e.printStackTrace();
//                }
//            }
           //方式二:
           try {
if(fw != null)
fw.close();
           } catch (IOException e) {
e.printStackTrace();
           }

try {
if(fr != null)
fr.close();
           } catch (IOException e) {
e.printStackTrace();
           }

}

}

复制硬盘上的图片:

@Test
public void testFileImageInputStream() {
FileInputStream fs = null;
   FileOutputStream fs1 = null;


   try {
//1.创建File类的对象,指明读入和写出的文件
       File image = new File("sd.png");
       File image1 = new File("sd1.png");

       //2.创建输入输出流对象,图片
       fs = new FileInputStream(image);
       fs1 = new FileOutputStream(image1);

       //3.数据的读入和写出操作
       byte[] bytes = new byte[100];
       int len;//记录每次读入到bytes数组中的字符的个数
       while((len = fs.read(bytes)) != -1){
       //每次写出len个字符
           fs1.write(bytes,0,len);

       }
} catch (IOException e) {
e.printStackTrace();
   } finally {
try {
if(fs1 != null)
fs1.close();
       } catch (IOException e) {
e.printStackTrace();
       }

try {
if(fs != null)
fs.close();
       } catch (IOException e) {
e.printStackTrace();
       }
}



}

缓冲流了解:

import org.junit.Test;

import java.io.*;

/**
* 处理流之一:缓冲流的使用
*
* 1.缓冲流:
* BufferedInputStream
* BufferedOutputStream
* BufferedReader
* BufferedWriter
*
* 2.作用:提供流的读取、写入的速度
*   提高读写速度的原因:内部提供了一个缓冲区
*
* 3. 处理流,就是套接在已有的流的基础上。
*
*/
public class BufferedTest {

/*
   实现非文本文件的复制
    */
   @Test
   public void BufferedStreamTest() throws FileNotFoundException {
BufferedInputStream bis = null;
       BufferedOutputStream bos = null;

       try {
//1.造文件
           File srcFile = new File("爱情与友情.jpg");
           File destFile = new File("爱情与友情3.jpg");
           //2.造流
           //2.1 造节点流
           FileInputStream fis = new FileInputStream((srcFile));
           FileOutputStream fos = new FileOutputStream(destFile);
           //2.2 造缓冲流
           bis = new BufferedInputStream(fis);
           bos = new BufferedOutputStream(fos);

           //3.复制的细节:读取、写入
           byte[] buffer = new byte[10];
           int len;
           while((len = bis.read(buffer)) != -1){
bos.write(buffer,0,len);

//                bos.flush();//刷新缓冲区

           }
} catch (IOException e) {
e.printStackTrace();
       } finally {
//4.资源关闭
           //要求:先关闭外层的流,再关闭内层的流
           if(bos != null){
try {
bos.close();
               } catch (IOException e) {
e.printStackTrace();
               }

}
if(bis != null){
try {
bis.close();
               } catch (IOException e) {
e.printStackTrace();
               }

}
//说明:关闭外层流的同时,内层流也会自动的进行关闭。关于内层流的关闭,我们可以省略.
//        fos.close();
//        fis.close();
       }



}

//实现文件复制的方法
   public void copyFileWithBuffered(String srcPath,String destPath){
BufferedInputStream bis = null;
       BufferedOutputStream bos = null;

       try {
//1.造文件
           File srcFile = new File(srcPath);
           File destFile = new File(destPath);
           //2.造流
           //2.1 造节点流
           FileInputStream fis = new FileInputStream((srcFile));
           FileOutputStream fos = new FileOutputStream(destFile);
           //2.2 造缓冲流
           bis = new BufferedInputStream(fis);
           bos = new BufferedOutputStream(fos);

           //3.复制的细节:读取、写入
           byte[] buffer = new byte[1024];
           int len;
           while((len = bis.read(buffer)) != -1){
bos.write(buffer,0,len);
           }
} catch (IOException e) {
e.printStackTrace();
       } finally {
//4.资源关闭
           //要求:先关闭外层的流,再关闭内层的流
           if(bos != null){
try {
bos.close();
               } catch (IOException e) {
e.printStackTrace();
               }

}
if(bis != null){
try {
bis.close();
               } catch (IOException e) {
e.printStackTrace();
               }

}
//说明:关闭外层流的同时,内层流也会自动的进行关闭。关于内层流的关闭,我们可以省略.
//        fos.close();
//        fis.close();
       }
}

转换流和字符集的了解:

import org.junit.Test;

import java.io.*;

/**
* 处理流之二:转换流的使用
* 1.转换流:属于字符流
*   InputStreamReader:将一个字节的输入流转换为字符的输入流
*   OutputStreamWriter:将一个字符的输出流转换为字节的输出流
*
* 2.作用:提供字节流与字符流之间的转换
*
* 3. 解码:字节、字节数组  --->字符数组、字符串
*    编码:字符数组、字符串 ---> 字节、字节数组
*
*
* 4.字符集
*ASCII:美国标准信息交换码。
用一个字节的7位可以表示。
ISO8859-1:拉丁码表。欧洲码表
用一个字节的8位表示。
GB2312:中国的中文编码表。最多两个字节编码所有字符
GBK:中国的中文编码表升级,融合了更多的中文文字符号。最多两个字节编码
Unicode:国际标准码,融合了目前人类使用的所有字符。为每个字符分配唯一的字符码。所有的文字都用两个字节来表示。
UTF-8:变长的编码方式,可用1-4个字节来表示一个字符。

*
*/
public class InputStreamReaderTest {

/*
   此时处理异常的话,仍然应该使用try-catch-finally
   InputStreamReader的使用,实现字节的输入流到字符的输入流的转换
    */
   @Test
   public void test1() throws IOException {

FileInputStream fis = new FileInputStream("dbcp.txt");
//        InputStreamReader isr = new InputStreamReader(fis);//使用系统默认的字符集
       //参数2指明了字符集,具体使用哪个字符集,取决于文件dbcp.txt保存时使用的字符集
       InputStreamReader isr = new InputStreamReader(fis,"UTF-8");//使用系统默认的字符集

       char[] cbuf = new char[20];
       int len;
       while((len = isr.read(cbuf)) != -1){
String str = new String(cbuf,0,len);
           System.out.print(str);
       }

isr.close();

   }

/*
   此时处理异常的话,仍然应该使用try-catch-finally

   综合使用InputStreamReaderOutputStreamWriter
    */
   @Test
   public void test2() throws Exception {
//1.造文件、造流
       File file1 = new File("dbcp.txt");
       File file2 = new File("dbcp_gbk.txt");

       FileInputStream fis = new FileInputStream(file1);
       FileOutputStream fos = new FileOutputStream(file2);

       InputStreamReader isr = new InputStreamReader(fis,"utf-8");
       OutputStreamWriter osw = new OutputStreamWriter(fos,"gbk");

       //2.读写过程
       char[] cbuf = new char[20];
       int len;
       while((len = isr.read(cbuf)) != -1){
osw.write(cbuf,0,len);
       }

//3.关闭资源
       isr.close();
       osw.close();


   }


}


标准的输入输出流

打印流

数据流


import org.junit.Test;

import java.io.*;

/**
* 其他流的使用
* 1.标准的输入、输出流
* 2.打印流
* 3.数据流
*/
public class OtherStreamTest {

/*
   1.标准的输入、输出流
   1.1
   System.in:标准的输入流,默认从键盘输入
   System.out:标准的输出流,默认从控制台输出
   1.2
   System类的setIn(InputStream is) / setOut(PrintStream ps)方式重新指定输入和输出的流。

   1.3练习:
   从键盘输入字符串,要求将读取到的整行字符串转成大写输出。然后继续进行输入操作,
   直至当输入“e”或者“exit”时,退出程序。

   方法一:使用Scanner实现,调用next()返回一个字符串
   方法二:使用System.in实现。System.in  --->  转换流 ---> BufferedReaderreadLine()

    */
   public static void main(String[] args) {
BufferedReader br = null;
       try {
InputStreamReader isr = new InputStreamReader(System.in);
           br = new BufferedReader(isr);

           while (true) {
System.out.println("请输入字符串:");
               String data = br.readLine();
               if ("e".equalsIgnoreCase(data) || "exit".equalsIgnoreCase(data)) {
System.out.println("程序结束");
                   break;
               }

String upperCase = data.toUpperCase();
               System.out.println(upperCase);

           }
} catch (IOException e) {
e.printStackTrace();
       } finally {
if (br != null) {
try {
br.close();
               } catch (IOException e) {
e.printStackTrace();
               }

}
}
}

/*
   2. 打印流:PrintStream PrintWriter

   2.1 提供了一系列重载的print() println()
   2.2 练习:



    */

   @Test
   public void test2() {
PrintStream ps = null;
       try {
FileOutputStream fos = new FileOutputStream(new File("D:\\IO\\text.txt"));
           // 创建打印输出流,设置为自动刷新模式(写入换行符或字节 '\n' 时都会刷新输出缓冲区)
           ps = new PrintStream(fos, true);
           if (ps != null) {// 把标准输出流(控制台输出)改成文件
               System.setOut(ps);
           }


for (int i = 0; i <= 255; i++) { // 输出ASCII字符
               System.out.print((char) i);
               if (i % 50 == 0) { // 50个数据一行
                   System.out.println(); // 换行
               }
}


} catch (FileNotFoundException e) {
e.printStackTrace();
       } finally {
if (ps != null) {
ps.close();
           }
}

}

/*
   3. 数据流
   3.1 DataInputStream DataOutputStream
   3.2 作用:用于读取或写出基本数据类型的变量或字符串

   练习:将内存中的字符串、基本数据类型的变量写出到文件中。

   注意:处理异常的话,仍然应该使用try-catch-finally.
    */
   @Test
   public void test3() throws IOException {
//1.
       DataOutputStream dos = new DataOutputStream(new FileOutputStream("data.txt"));
       //2.
       dos.writeUTF("刘建辰");
       dos.flush();//刷新操作,将内存中的数据写入文件
       dos.writeInt(23);
       dos.flush();
       dos.writeBoolean(true);
       dos.flush();
       //3.
       dos.close();


   }
/*
   将文件中存储的基本数据类型变量和字符串读取到内存中,保存在变量中。

   注意点:读取不同类型的数据的顺序要与当初写入文件时,保存的数据的顺序一致!

    */
   @Test
   public void test4() throws IOException {
//1.
       DataInputStream dis = new DataInputStream(new FileInputStream("data.txt"));
       //2.
       String name = dis.readUTF();
       int age = dis.readInt();
       boolean isMale = dis.readBoolean();

       System.out.println("name = " + name);
       System.out.println("age = " + age);
       System.out.println("isMale = " + isMale);

       //3.
       dis.close();

   }

}





返回列表 返回列表
评论

    分享到