Abl*_*lia 2 java arrays sqlite blob file
我正在将一个文件从客户端发送到服务器并像这样接收它:
//Receive File:
FileOutputStream fis = new FileOutputStream("receivedTest");
DataInputStream dis = new DataInputStream(clientSocket.getInputStream());
int count;
byte[] buffer = new byte[4096];
while ((count = dis.read(buffer)) > 0)
{
fis.write(buffer, 0, count);
}
fis.close();
Run Code Online (Sandbox Code Playgroud)
就像它在这个主题中解释的那样.它运作良好.但事实是,我真的不想收到文件本身; 我想要一个BLOB.我已经读过BLOB就像一个byte [].
在我的数据库类(我使用SQLite)中,我有下表:
String sqlFile = "CREATE TABLE IF NOT EXISTS files (\n"
+ " id integer PRIMARY KEY,\n"
+ " shorthash byte[],\n"
+ " filename text NOT NULL,\n"
+ " file blob,\n"
+ " owner text\n"
+ ");";
Run Code Online (Sandbox Code Playgroud)
和以下函数插入一个新的"文件":
public void insertFile(byte[] shorthash, String filename, byte[] file, String owner) {
String sql = "INSERT INTO files(shorthash,filename, file, owner) VALUES(?,?,?,?)";
try (Connection conn = DriverManager.getConnection(url);
PreparedStatement pstmt = conn.prepareStatement(sql)) {
pstmt.setBytes(1, shorthash);
pstmt.setString(2, filename);
pstmt.setBytes(3, file);
pstmt.setString(4, owner);
pstmt.executeUpdate();
} catch (SQLException e) {
System.out.println(e.getMessage());
}
}
Run Code Online (Sandbox Code Playgroud)
如您所见,有4列,文件本身位于第3列.在表中,它被声明为BLOB,但是当我插入它时,我只是在做一个setBytes.我不确定这是不对的,这正是我在互联网上发现的.
所以,我在我的服务器上收到这个文件,我想将它存储在我的数据库中.如果可能的话,我想避免在服务器端创建文件(行FileOutputStream fis = new FileOutputStream("receivedTest");在我的第一个代码中).我想将它直接存储在数据库中,因为我将其作为字节数组接收,我认为这样会更容易.
但我不知道该怎么做.可能是因为我并不真正理解Blob和byte []之间的联系.我的意思是,一个字节数组可能太小而无法容纳整个文件; 但是blob还可以.但是,要在数据库中插入文件,我插入一个字节数组.这让我不知所措.
编辑:
所以,我尝试了两件事:首先,在数据库中添加文件就像在这里完成的那样(几乎在我看来的任何地方,它总是以这种方式完成):
//Receive encrypted File:
FileOutputStream fos = new FileOutputStream("receivedTest");
DataInputStream dis = new DataInputStream(clientSocket.getInputStream());
int count;
byte[] buffer = new byte[4096];
while ((count = dis.read(buffer)) > 0)
{
fos.write(buffer, 0, count);
}
fos.close();
DB.insertFile(shorthash, "test", "receivedTest", user);
//Insert file in DB:
public void insertFile(byte[] shorthash, String filename, String filepath, String owner) throws FileNotFoundException {
String sql = "INSERT INTO files(shorthash, filename, file, owner) VALUES(?, ?, ?, ?)";
try (Connection conn = DriverManager.getConnection(url);
PreparedStatement pstmt = conn.prepareStatement(sql)) {
pstmt.setBytes(1, shorthash);
pstmt.setString(2, filename);
File file = new File(filepath);
FileInputStream fis = new FileInputStream(file);
pstmt.setBinaryStream(3, fis, (int) file.length());
pstmt.execute();
pstmt.setString(4, owner);
pstmt.executeUpdate();
fis.close()
} catch (SQLException e) {
System.out.println(e.getMessage());
}
}
Run Code Online (Sandbox Code Playgroud)
其次,将文件作为字节数组插入(但不适用于大文件),如SQLite教程中所述:
//Insert file in DB:
public void insertFile(byte[] shorthash, String filename, String filepath, String owner) throws FileNotFoundException {
String sql = "INSERT INTO files(shorthash, filename, file, owner) VALUES(?, ?, ?, ?)";
try (Connection conn = DriverManager.getConnection(url);
PreparedStatement pstmt = conn.prepareStatement(sql)) {
pstmt.setBytes(1, shorthash);
pstmt.setString(2, filename);
File file = new File(filepath);
FileInputStream fis = new FileInputStream(file);
byte[] buffer = new byte[1024];
ByteArrayOutputStream bos = new ByteArrayOutputStream();
for (int len; (len = fis.read(buffer)) != -1;)
bos.write(buffer, 0, len);
fis.close()
pstmt.setBytes(3, bos.toByteArray());
pstmt.execute();
pstmt.setString(4, owner);
pstmt.executeUpdate();
} catch (SQLException e) {
System.out.println(e.getMessage());
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
Run Code Online (Sandbox Code Playgroud)
然后,当我打印我的数据库时,其中没有文件.如果我尝试使用数据库浏览器打开数据库,则相同.控制台只说:
Connection to SQLite has been established.
ouverture du server
Clients:
1 admin admin
Files:
Run Code Online (Sandbox Code Playgroud)
A byte[]
和BLOB只是讨论任意二进制数据集的两种不同方式.在Java中,a byte[]
是二进制数据的集合.在数据库中,BLOB代表二进制大对象,并且是相同的.只是二进制数据的集合.
因此,根据参考框架,它们具有不同的名称是相同的.因此,当您将其存储byte[]
在blob列中时,您只是将这些字节从Java推送到数据库中.然后当你读回它们时,如果你愿意,可以将它们变回一个对象,因为数据库没有改变它们.它只是直接存储二进制信息.
您会发现,如果您从其他地方编写了一个blob,除非您知道存储的二进制数据的编码和字节顺序,否则您可能无法将其转换为对象.
如果您的文件太大而无法存储在单个文件中,byte[]
或者您希望优化使用内存进行存储的方式,则可以使用a Stream
将数据发送到数据库,而无需同时将其全部保存在内存中.
最后,如果你需要将你FileInputStream
变成字节,你可以像这样使用Apache Commons IO:
byte[] bytes = IOUtils.toByteArray(fis);
然后存储您的文件.
归档时间: |
|
查看次数: |
6269 次 |
最近记录: |