Logo

郎哥编程

处理二进制数据

2020-01-16 232

二进制数据不能使用文本编辑器查看内容,需要专门读取二进制数据的应用程序查看。例如读取图片文件时,读取图片的程序需要了解该文件的结构,并解释读取的数据,如果不了解该图片文件的结构,读取图片文件就会失败,也就无法把图片显示出来了。

在MySQL中,提供了LONGBLOB类型的字段用来存储二进制数据,可以存储4G以内的二进制数据。除此之外,还提供了BLOB、MediumBlob、TinyBlob字段来存储二进制数据,BLOB用于存储65K以内的二进制数据,MediumBlob用于存储16M以内的二进制数据,TinyBlob用来存储255字节以内的二进制数据。

JDBC提供了Blob接口来封装对MySQL二进制字段类型的存取封装操作,Blob接口包含了getBinaryStream()方法,用于获取InputStream输入流。

课程案例shop数据库的user(用户表)的photo字段就是LONGBLOB字段,可以存储4G以内的图文文件。写入二进制数据时,需要通过I/O流的方式从图片文件中读取数据。

案例1:在user表中插入一条记录,user表的photo是LONGBLOB类型字段,该字段的值需要从图片文件读入。

在demo包下新建SqlDemoTest9类。代码如下:

package demo;
 
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;
 
/** 
* @ClassName: SqlDemoTest9 
* @Description: 数据库编程(处理二进制数据)案例1
* @author 编程训练营 
* @date 
* 
*/
 
public class SqlDemoTest9 {
 
    // 定义JDBC加载路径
    static String jdbc = "com.mysql.cj.jdbc.Driver";
    // 定义MySQL数据库的连接地址
    static String mysqlurl = "jdbc:mysql://localhost:3306/shop?serverTimezone=GMT%2B8";
    // 定义MySQL数据库的用户名
    static String username = "root";
    // 定义MySQL数据库的用户名登录密码
    static String password = "~123456q";
   
    /**
     * @throws FileNotFoundException  
    * @Title: main 
    * @Description: Java程序入口main方法 
    * @param @param args    参数 
   
    * @return void    返回类型 
    * @throws 
    */
 
    public static void main(String[] args) throws FileNotFoundException {
      
       Connection conn = null;
       PreparedStatement prepartStatement = null;
       try {
           // 加载JDBC驱动
           Class.forName(jdbc);
           // 连接数据库
           conn = DriverManager.getConnection(mysqlurl, username, password);
           if (null != conn) {
              System.out.println(conn);
              // 向user表中插入一条记录
              String sql = "insert into user(id,name,loginName,psw,email,createDate,userType,photo)"
                         + "values(?,?,?,?,?,?,?,?)";
              // 实例化PreparedStatement对象
              prepartStatement = conn.prepareStatement(sql);
              // 设置id字段的值
              prepartStatement.setString(1,"0002");
              // 设置name字段的值
              prepartStatement.setString(2,"张三");
              // 设置loginName字段的值
              prepartStatement.setString(3,"zhansan");
              // 设置psw字段的值
              prepartStatement.setString(4,"123456");
              // 设置email字段的值
              prepartStatement.setString(5,"zhangsan@163.com");
              // 设置createDate字段的值
              java.util.Date date = new java.util.Date();
              java.sql.Date sqldate = new java.sql.Date(date.getTime());
              prepartStatement.setDate(6,sqldate);
              // 设置userType字段的值
              prepartStatement.setInt(7,0);
              // 定义一个File对象,准备从图片文件中读取数据
              File  file = new File("d:" + File.separator + "head.png");
              InputStream input = new FileInputStream(file);
              prepartStatement.setBinaryStream(8, input, file.length());
              // 执行SQL语句
              int row  = prepartStatement.executeUpdate();
              if( row == 1 )
              {
                  System.out.println("user表添加记录成功");
              }
              else
              {
                  System.out.println("user表添加记录失败");
              }
              prepartStatement.close();
              conn.close();
           } else {
              System.out.println("数据库连接失败");
           }
       } catch (ClassNotFoundException e) {
           // TODO Auto-generated catch block
           e.printStackTrace();
       } catch (SQLException e) {
           // TODO Auto-generated catch block
           e.printStackTrace();
       }
 
    }
 
}

SqlDemoTest9程序代码和SqlDemoTest7程序代码基本相同,SqlDemoTest9使用FileInputStream将图片文件读取进来,然后通过PreparedStatement接口的setBinaryStream ()方法将图片文件内容写入到对应的二进制字段中。

程序执行结果如下图所示:

image.png 

二进制文件写入完成后,在读取数据库记录时,可以使用ResultSet接口的读取二进制数据的方法将二进制内容读取出来。

案例2:查询案例1写入的记录,并将记录内容输出到控制台。

在demo包下新建SqlDemoTest10类。代码如下:

package demo;
 
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
 
/**
 * @ClassName: SqlDemoTest10
 * @Description: 数据库编程(处理二进制数据)案例2
 * @author 编程训练营
 * @date
 *
 */
 
public class SqlDemoTest10 {
 
    // 定义JDBC加载路径
    static String jdbc = "com.mysql.cj.jdbc.Driver";
    // 定义MySQL数据库的连接地址
    static String mysqlurl = "jdbc:mysql://localhost:3306/shop?serverTimezone=GMT%2B8";
    // 定义MySQL数据库的用户名
    static String username = "root";
    // 定义MySQL数据库的用户名登录密码
    static String password = "~123456q";
 
    /**
     * @Title: main
     * @Description: Java程序入口main方法
     * @param @param args 参数
     *
     * @return void 返回类型 @throws
     */
 
    public static void main(String[] args) {
 
       Connection conn = null;
       Statement statement = null;
       try {
           // 加载JDBC驱动
           Class.forName(jdbc);
           // 连接数据库
           conn = DriverManager.getConnection(mysqlurl, username, password);
           if (null != conn) {
              System.out.println(conn);
              // 获取表记录数的SQL语句
              String sql = "select * from user where id='0002'";
              // 实例化Statement对象
              statement = conn.createStatement();
              // 执行SQL查询语句
              ResultSet resultset = statement.executeQuery(sql);
              if (null != resultset) {
                  while (resultset.next()) {
                     // 获取id字段内容
                     String id = resultset.getString("id");
                     // 获取name字段内容
                     String name = resultset.getString("name");
                     // 获取loginName字段内容
                     String loginName = resultset.getString("loginName");
                     // 获取psw字段内容
                     String psw = resultset.getString("psw");
                     // 获取email字段内容
                     String email = resultset.getString("email");
                     // 获取createDate字段内容
                     String createDate = resultset.getString("createDate");
                     // 获取userType字段内容
                     int userType = resultset.getInt("userType");
                     // 读取二进制数据
                     InputStream input = resultset.getBinaryStream("photo");
                     // 将读取的二进制数据写入到temphead.png文件中
                     String photoPath = "d:" + File.separator + "temphead.png";
                     File file = new File(photoPath);
                     try {
                         FileOutputStream outstream = new FileOutputStream(file);
                         int nTemp = 0;
                         while( (nTemp = input.read()) != -1 )
                         {
                            outstream.write(nTemp);
                         }
                         input.close();
                         outstream.close();
                     } catch (IOException e) {
                         // TODO Auto-generated catch block
                         e.printStackTrace();
                     }
                     System.out.printf("-----输出第%d条记录-----\n", resultset.getRow());
                     System.out.println("id:" + id + ";");
                     System.out.println("name:" + name + ";");
                     System.out.println("loginName:" + loginName + ";");
                     System.out.println("psw:" + psw + ";");
                     System.out.println("email:" + email + ";");
                     System.out.println("createDate:" + createDate.toString() + ";");
                     System.out.printf("photo:%s;\n",photoPath);
                     System.out.println("-------------------------------");
                  }
 
                  resultset.close();
              } else {
                  System.out.println("SQL语句执行失败");
              }
              statement.close();
              conn.close();
           } else {
              System.out.println("数据库连接失败");
           }
       } catch (ClassNotFoundException e) {
           // TODO Auto-generated catch block
           e.printStackTrace();
       } catch (SQLException e) {
           // TODO Auto-generated catch block
           e.printStackTrace();
       }
 
    }
 
}

SqlDemoTest10将程序读取的图片数据保存到磁盘文件中。程序执行结果如下图所示:

image.png

代码在线纠错(通义千问 qwen-max)

支持粘贴多个代码文件,提交后由阿里云通义千问自动分析代码漏洞、语法错误、逻辑问题并给出修改建议。
您已解锁 AI 代码纠错功能,可正常使用!

评论区

登录 后发表评论
暂无评论