3 Commits
9 changed files with 158 additions and 31 deletions
+12
View File
@@ -1,4 +1,16 @@
Version 1.37 2025-11-06
* query file info support two combined flags:
ProtoCommon.FDFS_QUERY_FINFO_FLAGS_NOT_CALC_CRC32
ProtoCommon.FDFS_QUERY_FINFO_FLAGS_KEEP_SILENCE
you must upgrade your FastDFS server V6.15.1 and higher version
Version 1.36 2025-10-26
* monitor protocol compatible with IPv4/IPv6 address automatically
* FastDFS server version requirements:
# group and storage statistics / monitor APIs: FastDFS server >= V6.13.1
# other APIs: FastDFS server >= V6.06
Version 1.35 2025-09-04
* group and storage statistics / monitor API output reserved
and available space
+1 -1
View File
@@ -4,7 +4,7 @@
<groupId>org.csource</groupId>
<artifactId>fastdfs-client-java</artifactId>
<version>1.35-SNAPSHOT</version>
<version>1.37-SNAPSHOT</version>
<name>fastdfs-client-java</name>
<description>fastdfs client for java</description>
<packaging>jar</packaging>
@@ -113,6 +113,9 @@ public class ProtoCommon {
public static final byte FDFS_RW_MODE_WRITEONLY = 2;
public static final byte FDFS_RW_MODE_BOTH = FDFS_RW_MODE_READONLY + FDFS_RW_MODE_WRITEONLY;
public static final byte FDFS_QUERY_FINFO_FLAGS_NOT_CALC_CRC32 = 1;
public static final byte FDFS_QUERY_FINFO_FLAGS_KEEP_SILENCE = 2;
private ProtoCommon() {
}
@@ -1540,9 +1540,14 @@ public class StorageClient {
*
* @param group_name the group name of storage server
* @param remote_filename filename on storage server
* @param flags combined flags as following:
* ProtoCommon.FDFS_QUERY_FINFO_FLAGS_NOT_CALC_CRC32 : do NOT calculate CRC32
* for appender file or slave file
* ProtoCommon.FDFS_QUERY_FINFO_FLAGS_KEEP_SILENCE : keep silence,
* when this file not exist, do not log error on storage server
* @return FileInfo object for success, return null for fail
*/
public FileInfo query_file_info(String group_name, String remote_filename) throws IOException, MyException {
public FileInfo query_file_info(String group_name, String remote_filename, byte flags) throws IOException, MyException {
boolean bNewStorageServer = this.newUpdatableStorageConnection(group_name, remote_filename);
Connection connection = this.storageServer.getConnection();
try {
@@ -1566,7 +1571,7 @@ public class StorageClient {
System.arraycopy(bs, 0, groupBytes, 0, groupLen);
header = ProtoCommon.packHeader(ProtoCommon.STORAGE_PROTO_CMD_QUERY_FILE_INFO,
+groupBytes.length + filenameBytes.length, (byte) 0);
groupBytes.length + filenameBytes.length, flags);
OutputStream out = connection.getOutputStream();
byte[] wholePkg = new byte[header.length + groupBytes.length + filenameBytes.length];
System.arraycopy(header, 0, wholePkg, 0, header.length);
@@ -1613,6 +1618,11 @@ public class StorageClient {
}
}
public FileInfo query_file_info(String group_name, String remote_filename) throws IOException, MyException {
final byte flags = 0;
return this.query_file_info(group_name, remote_filename, flags);
}
/**
* check storage socket, if null create a new connection
*
@@ -735,16 +735,26 @@ public class StorageClient1 extends StorageClient {
* get file info from storage server
*
* @param file_id the file id(including group name and filename)
* @param flags combined flags as following:
* ProtoCommon.FDFS_QUERY_FINFO_FLAGS_NOT_CALC_CRC32 : do NOT calculate CRC32
* for appender file or slave file
* ProtoCommon.FDFS_QUERY_FINFO_FLAGS_KEEP_SILENCE : keep silence,
* when this file not exist, do not log error on storage server
* @return FileInfo object for success, return null for fail
*/
public FileInfo query_file_info1(String file_id) throws IOException, MyException {
String[] parts = new String[2];
this.errno = this.split_file_id(file_id, parts);
if (this.errno != 0) {
return null;
}
public FileInfo query_file_info1(String file_id, byte flags) throws IOException, MyException {
String[] parts = new String[2];
this.errno = this.split_file_id(file_id, parts);
if (this.errno != 0) {
return null;
}
return this.query_file_info(parts[0], parts[1]);
return this.query_file_info(parts[0], parts[1], flags);
}
public FileInfo query_file_info1(String file_id) throws IOException, MyException {
final byte flags = 0;
return this.query_file_info1(file_id, flags);
}
/**
@@ -0,0 +1,46 @@
/**
* Copyright (C) 2025 Happy Fish / YuQing
* <p>
* FastDFS Java Client may be copied only under the terms of the GNU Lesser
* General Public License (LGPL).
* Please visit the FastDFS Home Page https://github.com/happyfish100/fastdfs for more detail.
*/
package org.csource.fastdfs;
import java.util.Date;
/**
* C struct body decoder
*
* @author Happy Fish / YuQing
* @version Version 1.36
*/
public class StructIPv4StorageStat extends StructStorageStat {
protected static int fieldsTotalSize;
protected static StructBase.FieldInfo[] fieldsArray =
new StructBase.FieldInfo[StructStorageStat.FIELD_COUNT];
static {
fieldsTotalSize = StructStorageStat.initFieldsArray(
fieldsArray, ProtoCommon.FDFS_IPV4_SIZE);
}
/**
* get fields total size
*
* @return fields total size
*/
public static int getFieldsTotalSize() {
return fieldsTotalSize;
}
/**
*
* @param bs byte array
* @param offset start offset
*/
public void setFields(byte[] bs, int offset) {
super.setFields(fieldsArray, bs, offset);
}
}
@@ -0,0 +1,46 @@
/**
* Copyright (C) 2025 Happy Fish / YuQing
* <p>
* FastDFS Java Client may be copied only under the terms of the GNU Lesser
* General Public License (LGPL).
* Please visit the FastDFS Home Page https://github.com/happyfish100/fastdfs for more detail.
*/
package org.csource.fastdfs;
import java.util.Date;
/**
* C struct body decoder
*
* @author Happy Fish / YuQing
* @version Version 1.36
*/
public class StructIPv6StorageStat extends StructStorageStat {
protected static int fieldsTotalSize;
protected static StructBase.FieldInfo[] fieldsArray =
new StructBase.FieldInfo[StructStorageStat.FIELD_COUNT];
static {
fieldsTotalSize = StructStorageStat.initFieldsArray(
fieldsArray, ProtoCommon.FDFS_IPV6_SIZE);
}
/**
* get fields total size
*
* @return fields total size
*/
public static int getFieldsTotalSize() {
return fieldsTotalSize;
}
/**
*
* @param bs byte array
* @param offset start offset
*/
public void setFields(byte[] bs, int offset) {
super.setFields(fieldsArray, bs, offset);
}
}
@@ -85,10 +85,7 @@ public class StructStorageStat extends StructBase {
protected static final int FIELD_COUNT = 62;
protected static int fieldsTotalSize;
protected static StructBase.FieldInfo[] fieldsArray = new StructBase.FieldInfo[FIELD_COUNT];
static {
protected static int initFieldsArray(StructBase.FieldInfo[] fieldsArray, int ipaddr_size) {
int offset = 0;
fieldsArray[FIELD_INDEX_STATUS] = new StructBase.FieldInfo(
@@ -104,8 +101,8 @@ public class StructStorageStat extends StructBase {
offset += ProtoCommon.FDFS_STORAGE_ID_MAX_SIZE;
fieldsArray[FIELD_INDEX_IP_ADDR] = new StructBase.FieldInfo(
"ipAddr", offset, ProtoCommon.FDFS_IPV6_SIZE);
offset += ProtoCommon.FDFS_IPV6_SIZE;
"ipAddr", offset, ipaddr_size);
offset += ipaddr_size;
fieldsArray[FIELD_INDEX_SRC_ID] = new StructBase.FieldInfo(
"srcId", offset, ProtoCommon.FDFS_STORAGE_ID_MAX_SIZE);
@@ -339,16 +336,7 @@ public class StructStorageStat extends StructBase {
"ifTrunkServer", offset, 1);
offset += 1;
fieldsTotalSize = offset;
}
/**
* get fields total size
*
* @return fields total size
*/
public static int getFieldsTotalSize() {
return fieldsTotalSize;
return offset;
}
protected byte status;
@@ -978,7 +966,7 @@ public class StructStorageStat extends StructBase {
* @param bs byte array
* @param offset start offset
*/
public void setFields(byte[] bs, int offset) {
protected void setFields(StructBase.FieldInfo[] fieldsArray, byte[] bs, int offset) {
this.status = byteValue(bs, offset, fieldsArray[FIELD_INDEX_STATUS]);
this.readWriteMode = byteValue(bs, offset, fieldsArray[FIELD_INDEX_RW_MODE]);
this.id = stringValue(bs, offset, fieldsArray[FIELD_INDEX_ID]);
@@ -1044,4 +1032,7 @@ public class StructStorageStat extends StructBase {
this.lastHeartBeatTime = dateValue(bs, offset, fieldsArray[FIELD_INDEX_LAST_HEART_BEAT_TIME]);
this.ifTrunkServer = booleanValue(bs, offset, fieldsArray[FIELD_INDEX_IF_TRUNK_FILE]);
}
public void setFields(byte[] bs, int offset) {
}
}
@@ -657,7 +657,8 @@ public class TrackerClient {
ipAddrLen = 0;
}
header = ProtoCommon.packHeader(ProtoCommon.TRACKER_PROTO_CMD_SERVER_LIST_STORAGE, ProtoCommon.FDFS_GROUP_NAME_MAX_LEN + ipAddrLen, (byte) 0);
header = ProtoCommon.packHeader(ProtoCommon.TRACKER_PROTO_CMD_SERVER_LIST_STORAGE,
ProtoCommon.FDFS_GROUP_NAME_MAX_LEN + ipAddrLen, (byte) 0);
byte[] wholePkg = new byte[header.length + bGroupName.length + ipAddrLen];
System.arraycopy(header, 0, wholePkg, 0, header.length);
System.arraycopy(bGroupName, 0, wholePkg, header.length, bGroupName.length);
@@ -673,9 +674,17 @@ public class TrackerClient {
return null;
}
ProtoStructDecoder<StructStorageStat> decoder = new ProtoStructDecoder<StructStorageStat>();
return decoder.decode(pkgInfo.body, StructStorageStat.class,
StructStorageStat.getFieldsTotalSize());
if (pkgInfo.body.length % StructIPv6StorageStat.getFieldsTotalSize() == 0) {
ProtoStructDecoder<StructIPv6StorageStat> decoder =
new ProtoStructDecoder<StructIPv6StorageStat>();
return decoder.decode(pkgInfo.body, StructIPv6StorageStat.class,
StructIPv6StorageStat.getFieldsTotalSize());
} else {
ProtoStructDecoder<StructIPv4StorageStat> decoder =
new ProtoStructDecoder<StructIPv4StorageStat>();
return decoder.decode(pkgInfo.body, StructIPv4StorageStat.class,
StructIPv4StorageStat.getFieldsTotalSize());
}
} catch (IOException ex) {
try {
connection.close();