第17章,练习3:使用键盘输入流,接收一大段文本数据,并输入一个图片的路径, 然后将这些数据保存在数据表中,数据表由用户自行创建。

/**
 * 使用键盘输入流,接收一大段文本数据,并输入一个图片的路径, 然后将这些数据保存在数据表中,数据表由用户自行创建。
 */
package exercise17;

import java.sql.Blob;
import java.sql.Clob;
import java.sql.Connection;
import java.sql.DriverManager;
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

public class Ex03 {
	public static final String DBDRIVER = "com.mysql.cj.jdbc.Driver";
    public static final String DBURL = "jdbc:mysql://localhost:3306/test";
    public static final String DBUSER = "root";
    public static final String DBPASS = "mysqladmin";
	public static void main(String[] args) throws Exception {
		// TODO Auto-generated method stub
        Connection conn = null;
        Class.forName(DBDRIVER);   // 加载驱动程序
        conn = DriverManager.getConnection(DBURL, DBUSER, DBPASS);
        createTable(conn);        // 创建名为info的数据表
        insertData(conn);        // 向数据库表中插入一行数据
        showPhoto(conn);          // 展示数据表中的数据内容,longtext类型数据打印在控制台,二进制大对象(longblob类型)输出到桌面的文件中
	}
	
	/**
	 * 
	 * @return 用户从键盘输入的字符串
	 * @throws Exception
	 */
	public static String getString() throws Exception {
	    InputStreamReader isr = new InputStreamReader(System.in);  // 创建字符输入流实例,从键盘输入
	    BufferedReader buf = new BufferedReader(isr);   // 创建字符输入流缓冲
	    String temp = null;         // 保存用户输入的字符串
	    temp = buf.readLine();      // 从字符输入流缓冲中读取一行字符
	    return temp;
	}
	
	/**
	 * @param 数据库的连接实例
	 * @throws Exception
	 * @function 向数据库中插入一行数据
	 */
	public static void insertData(Connection conn) throws Exception {
		boolean flag = true;               //  定义一个标识符
		InputStream input = null;          // 定义一个字节输入流
		PreparedStatement pstmt = null;    // 数据库操作
		// 定义向数据库中插入数据的SQL语句
        String sql = "INSERT INTO info(note, photo) VALUES(?, ?)";
        pstmt = conn.prepareStatement(sql); // 获取数据库操作实例
		while (flag) {                     // 反复插入数据,直至标识符为false
			String text = getLargeText("请输入一个大文本数据:");   // 提示用户输入longtext类型的大文本数据
			byte[] b = text.getBytes();    // 将文本数据从字符串转换为byte类型的数组b
		    input = new ByteArrayInputStream(b);  // 创建字节数组输入流,将字节数组b传入输入流
		    pstmt.setAsciiStream(1, input);  // 设置SQL语句中的第一个?的值
		    // 提示用户输入要保存的图片(longblob类型)路径,返回该文件的File实例
		    File f = getPhotoDir("请输入一张图片的保存路径:", "路径错误,请重新输入:");  
	        input = new FileInputStream(f);  // 创建文件的输入流
	        pstmt.setBinaryStream(2, input); // 设置SQL语句中的第二个?的值
	        pstmt.executeUpdate();           //  向数据库中的info表中插入数据
	        System.out.println("是否继续更新数据?结束请输入‘N’:");
	        String str = "";
	        if ((str = getString()).equals("N") || str.equals("n")) {  // 如果用户输入了n(部分大小写),则将标识符改为false结束更新
	        	flag = false;
	        }
		}
	}
	
	/**
	 * 
	 * @param 提示信息
	 * @return 字符串(用户输入的大文本数据内容)
	 * @throws Exception
	 */
	public static String getLargeText(String info) throws Exception {
		System.out.println(info);     // 打印提示信息
        StringBuffer buffer = new StringBuffer(); // 创建字符串缓冲
        String str = "";
     // 用户可多行输入字符串(删除字符串两端的空格被删除),直到输入end为止(建议用户输入图片文件的名称,这样在读取时可以利用note列获得文件名称)
        while (!(str = getString().trim()).equals("end")) { 
        	buffer.append(str).append("\r\n");    // 每输入一行就加入到StringBuffer中
        }
        buffer.delete(buffer.length()-2, buffer.length());  // 当结束输入时,将最后面多余的换行符(\r和\n两个字符)删除
        return buffer.toString();     // 以字符串形式返回
	}
	
	/**
	 * 
	 * @param info:输入提示
	 * @param err:错误提示
	 * @return 用户输入的文件路径的File实例
	 * @throws Exception
	 */
	public static File getPhotoDir(String info, String err) throws Exception {
		System.out.println(info);    // 打印输入提示
		String path = getString();   // 获得文件路径的一个字符串
		File f = null;
		f = new File(path);          // 获得文件的File实例
		while (!f.exists() || !path.matches(".+\\.(jpg|png|jpeg|gif)")) {  // 判断文件是否存在,或文件格式(图片)是否正确
			System.err.println(err); // 如果判断结果为否,则打印错误提示
			path = getString();      //  重新输入
			f = new File(path);      // 重新创建File实例
		}
		return f;                    // 返回正确的文件File实例
	}
	
	/**
	 * 
	 * @param conn:数据库连接实例
	 * @throws SQLException
	 * @function 在数据库中创建数据表info(如果这个类型的表已经存在就不用重复创建了)
	 */
    public static void createTable(Connection conn) throws SQLException {
    	Statement stmt = null;    // 数据库操作
    	stmt = conn.createStatement(); // 通过数据库连接得到数据库操作实例
    	// 定义SQL语句,该语句的内容就是:创建数据表info(如果表不存在)。
    	String sql = "create table if not exists info("
    			+ "id int auto_increment primary key,"   // id列,自动增长、主键
    			+ "note varchar(30) CHARACTER SET gbk DEFAULT NULL,"                       // note列,大文本数据对象
    			+ "photo longblob"                       // photo列,二进制大数据对象(图片)
    			+ ");";
    	stmt.execute(sql);        // 执行SQL语句,创建info表
    }
    
    /**
     * @function 展示数据表中的全部数据内容,longtext类型数据打印在控制台,二进制大对象(longblob类型)输出到桌面的文件中
     * @param conn: 数据库连接实例
     * @throws Exception
     */
    public static void showPhoto(Connection conn) throws Exception {
    	PreparedStatement pstmt = null;
    	ResultSet rs = null;
    	String sql = "SELECT id, note, photo FROM info;";
    	pstmt = conn.prepareStatement(sql);  // 获得数据库操作实例
    	rs = pstmt.executeQuery();    // 实行SQL语句,得到查询的结果集
    	while (rs.next()) {           // 展示结果集中的全部内容
    		int id = rs.getInt("id"); // 获得id的值
    		Clob clob = rs.getClob("note");  // 从结果集中获得大文本数据
    		String note = clob.getSubString(1, (int)clob.length()); // 转换成字符串
    		System.out.println("id:  " + id + "; note:  " + note);  // 输出id和note内容
    		File f = new File("C:" + File.separator + "Users" + File.separator + "yeqin" + 
    	        File.separator + "Desktop" + File.separator + note + ".gif"); // 得到输出文件的路径(在桌面)
    		if (!f.exists()) {        // 如果输出的文件不存在,则新建一个
    			System.out.println("在" + f.toString() + "处新建一个文件!");
    			f.createNewFile();    // 新建一个文件
    		}
    		OutputStream output = new FileOutputStream(f);   // 得到文件的写入流
    		Blob blob = rs.getBlob("photo");    // 从结果集中获得Blob实例
    		byte[] b = blob.getBytes(1, (int)blob.length());  // 将Blob实例中的数据保存在byte类型数组中,注意Blob实例的起始位置为1,而不是0
    		output.write(b);              // 将数组内容写入文件中
    		output.close();
    	}
    	pstmt.close();
    }
}


/**
 * 程序运行结果:
	 请输入一个大文本数据:
	 red flower
	end
	请输入一张图片的保存路径:
	d:\photo\red flower.gif
	是否继续更新数据?结束请输入‘N’:
	y
	请输入一个大文本数据:
	HeloIcon_solid
	end
	请输入一张图片的保存路径:
	y
	路径错误,请重新输入:
	d:\photo\HelpIcon_solid.gif
	是否继续更新数据?结束请输入‘N’:
	y
	请输入一个大文本数据:
	image1
	end
	请输入一张图片的保存路径:
	d:\photo\image1.gif
	是否继续更新数据?结束请输入‘N’:
	n
	id:  1; note:  red flower
	在"C:\Users\yeqin\Desktop\red flower.gif"处新建一个文件!
	id:  2; note:  HeloIcon_solid
	在"C:\Users\yeqin\Desktop\HeloIcon_solid.gif"处新建一个文件!
	id:  3; note:  image1
	在"C:\Users\yeqin\Desktop\image1.gif"处新建一个文件!
 *
 */

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值