《Java开发实战经典》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 longtext,"                       // 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"处新建一个文件!
 *
 */

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值