Skip to content

Commit 437a993

Browse files
committed
support appender file rename to normal file
1 parent 3fb2d49 commit 437a993

File tree

9 files changed

+306
-66
lines changed

9 files changed

+306
-66
lines changed

HISTORY

+4
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,8 @@
11

2+
Version 1.27 2019-11-11
3+
* StorageClient add function: regenerate_filename for appender file
4+
StorageClient1 add function: regenerate_filename1 for appender file
5+
26
Version 1.26 2017-04-17
37
* IniFileReader use getResourceAsStream first
48
* change charactor encoding to UTF-8

src/main/java/org/csource/fastdfs/FileInfo.java

+56-6
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,12 @@
1818
* @version Version 1.23
1919
*/
2020
public class FileInfo {
21+
public static final short FILE_TYPE_NORMAL = 1;
22+
public static final short FILE_TYPE_APPENDER = 2;
23+
public static final short FILE_TYPE_SLAVE = 4;
24+
25+
protected boolean fetch_from_server;
26+
protected short file_type;
2127
protected String source_ip_addr;
2228
protected long file_size;
2329
protected Date create_timestamp;
@@ -26,18 +32,60 @@ public class FileInfo {
2632
/**
2733
* Constructor
2834
*
29-
* @param file_size the file size
30-
* @param create_timestamp create timestamp in seconds
31-
* @param crc32 the crc32 signature
32-
* @param source_ip_addr the source storage ip address
35+
* @param fetch_from_server if fetch from server flag
36+
* @param file_type the file type
37+
* @param file_size the file size
38+
* @param create_timestamp create timestamp in seconds
39+
* @param crc32 the crc32 signature
40+
* @param source_ip_addr the source storage ip address
3341
*/
34-
public FileInfo(long file_size, int create_timestamp, int crc32, String source_ip_addr) {
42+
public FileInfo(boolean fetch_from_server, short file_type, long file_size,
43+
int create_timestamp, int crc32, String source_ip_addr)
44+
{
45+
this.fetch_from_server = fetch_from_server;
46+
this.file_type = file_type;
3547
this.file_size = file_size;
3648
this.create_timestamp = new Date(create_timestamp * 1000L);
3749
this.crc32 = crc32;
3850
this.source_ip_addr = source_ip_addr;
3951
}
4052

53+
/**
54+
* get the fetch_from_server flag
55+
*
56+
* @return the fetch_from_server flag
57+
*/
58+
public boolean getFetchFromServer() {
59+
return this.fetch_from_server;
60+
}
61+
62+
/**
63+
* set the fetch_from_server flag
64+
*
65+
* @param fetch_from_server the fetch from server flag
66+
*/
67+
public void setFetchFromServer(boolean fetch_from_server) {
68+
this.fetch_from_server = fetch_from_server;
69+
}
70+
71+
/**
72+
* get the file type
73+
*
74+
* @return the file type
75+
*/
76+
public short getFileType() {
77+
return this.file_type;
78+
}
79+
80+
/**
81+
* set the file type
82+
*
83+
* @param file_type the file type
84+
*/
85+
public void setFileType(short file_type) {
86+
this.file_type = file_type;
87+
}
88+
4189
/**
4290
* get the source ip address of the file uploaded to
4391
*
@@ -117,7 +165,9 @@ public void setCrc32(int crc32) {
117165
*/
118166
public String toString() {
119167
SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
120-
return "source_ip_addr = " + this.source_ip_addr + ", " +
168+
return "fetch_from_server = " + this.fetch_from_server + ", " +
169+
"file_type = " + this.file_type + ", " +
170+
"source_ip_addr = " + this.source_ip_addr + ", " +
121171
"file_size = " + this.file_size + ", " +
122172
"create_timestamp = " + df.format(this.create_timestamp) + ", " +
123173
"crc32 = " + this.crc32;

src/main/java/org/csource/fastdfs/ProtoCommon.java

+2
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,8 @@ public class ProtoCommon {
4949
public static final byte STORAGE_PROTO_CMD_APPEND_FILE = 24; //append file
5050
public static final byte STORAGE_PROTO_CMD_MODIFY_FILE = 34; //modify appender file
5151
public static final byte STORAGE_PROTO_CMD_TRUNCATE_FILE = 36; //truncate appender file
52+
public static final byte STORAGE_PROTO_CMD_REGENERATE_APPENDER_FILENAME = 38; //rename appender file to normal file
53+
5254
public static final byte STORAGE_PROTO_CMD_RESP = TRACKER_PROTO_CMD_RESP;
5355
public static final byte FDFS_STORAGE_STATUS_INIT = 0;
5456
public static final byte FDFS_STORAGE_STATUS_WAIT_SYNC = 1;

src/main/java/org/csource/fastdfs/StorageClient.java

+127-12
Original file line numberDiff line numberDiff line change
@@ -19,18 +19,17 @@
1919
/**
2020
* Storage client for 2 fields file id: group name and filename
2121
* Note: the instance of this class is NOT thread safe !!!
22+
* if not necessary, do NOT set storage server instance
2223
*
2324
* @author Happy Fish / YuQing
24-
* @version Version 1.24
25+
* @version Version 1.27
2526
*/
2627
public class StorageClient {
2728
public final static Base64 base64 = new Base64('-', '_', '.', 0);
2829
protected TrackerServer trackerServer;
2930
protected StorageServer storageServer;
3031
protected byte errno;
3132

32-
33-
3433
/**
3534
* constructor using global settings in class ClientGlobal
3635
*/
@@ -39,8 +38,19 @@ public StorageClient() {
3938
this.storageServer = null;
4039
}
4140

41+
/**
42+
* constructor with tracker server
43+
*
44+
* @param trackerServer the tracker server, can be null
45+
*/
46+
public StorageClient(TrackerServer trackerServer) {
47+
this.trackerServer = trackerServer;
48+
this.storageServer = null;
49+
}
50+
4251
/**
4352
* constructor with tracker server and storage server
53+
* NOTE: if not necessary, do NOT set storage server instance
4454
*
4555
* @param trackerServer the tracker server, can be null
4656
* @param storageServer the storage server, can be null
@@ -601,6 +611,94 @@ public int modify_file(String group_name, String appender_filename,
601611
modify_size, callback);
602612
}
603613

614+
/**
615+
* regenerate filename for appender file
616+
*
617+
* @param group_name the group name of appender file
618+
* @param appender_filename the appender filename
619+
* @return 2 elements string array if success:<br>
620+
* <ul><li> results[0]: the group name to store the file</li></ul>
621+
* <ul><li> results[1]: the new created filename</li></ul>
622+
* return null if fail
623+
*/
624+
public String[] regenerate_appender_filename(String group_name, String appender_filename) throws IOException, MyException {
625+
byte[] header;
626+
boolean bNewConnection;
627+
Socket storageSocket;
628+
byte[] hexLenBytes;
629+
byte[] appenderFilenameBytes;
630+
int offset;
631+
long body_len;
632+
633+
if ((group_name == null || group_name.length() == 0) ||
634+
(appender_filename == null || appender_filename.length() == 0)) {
635+
this.errno = ProtoCommon.ERR_NO_EINVAL;
636+
return null;
637+
}
638+
639+
bNewConnection = this.newUpdatableStorageConnection(group_name, appender_filename);
640+
641+
try {
642+
storageSocket = this.storageServer.getSocket();
643+
644+
appenderFilenameBytes = appender_filename.getBytes(ClientGlobal.g_charset);
645+
body_len = appenderFilenameBytes.length;
646+
647+
header = ProtoCommon.packHeader(ProtoCommon.STORAGE_PROTO_CMD_REGENERATE_APPENDER_FILENAME, body_len, (byte) 0);
648+
byte[] wholePkg = new byte[(int) (header.length + body_len)];
649+
System.arraycopy(header, 0, wholePkg, 0, header.length);
650+
offset = header.length;
651+
652+
System.arraycopy(appenderFilenameBytes, 0, wholePkg, offset, appenderFilenameBytes.length);
653+
offset += appenderFilenameBytes.length;
654+
655+
OutputStream out = storageSocket.getOutputStream();
656+
out.write(wholePkg);
657+
658+
ProtoCommon.RecvPackageInfo pkgInfo = ProtoCommon.recvPackage(storageSocket.getInputStream(),
659+
ProtoCommon.STORAGE_PROTO_CMD_RESP, -1);
660+
this.errno = pkgInfo.errno;
661+
if (pkgInfo.errno != 0) {
662+
return null;
663+
}
664+
665+
if (pkgInfo.body.length <= ProtoCommon.FDFS_GROUP_NAME_MAX_LEN) {
666+
throw new MyException("body length: " + pkgInfo.body.length + " <= " + ProtoCommon.FDFS_GROUP_NAME_MAX_LEN);
667+
}
668+
669+
String new_group_name = new String(pkgInfo.body, 0, ProtoCommon.FDFS_GROUP_NAME_MAX_LEN).trim();
670+
String remote_filename = new String(pkgInfo.body, ProtoCommon.FDFS_GROUP_NAME_MAX_LEN,
671+
pkgInfo.body.length - ProtoCommon.FDFS_GROUP_NAME_MAX_LEN);
672+
String[] results = new String[2];
673+
results[0] = new_group_name;
674+
results[1] = remote_filename;
675+
676+
return results;
677+
} catch (IOException ex) {
678+
if (!bNewConnection) {
679+
try {
680+
this.storageServer.close();
681+
} catch (IOException ex1) {
682+
ex1.printStackTrace();
683+
} finally {
684+
this.storageServer = null;
685+
}
686+
}
687+
688+
throw ex;
689+
} finally {
690+
if (bNewConnection) {
691+
try {
692+
this.storageServer.close();
693+
} catch (IOException ex1) {
694+
ex1.printStackTrace();
695+
} finally {
696+
this.storageServer = null;
697+
}
698+
}
699+
}
700+
}
701+
604702
/**
605703
* upload file to storage server
606704
*
@@ -1514,26 +1612,42 @@ public FileInfo get_file_info(String group_name, String remote_filename) throws
15141612
byte[] buff = base64.decodeAuto(remote_filename.substring(ProtoCommon.FDFS_FILE_PATH_LEN,
15151613
ProtoCommon.FDFS_FILE_PATH_LEN + ProtoCommon.FDFS_FILENAME_BASE64_LENGTH));
15161614

1615+
short file_type;
15171616
long file_size = ProtoCommon.buff2long(buff, 4 * 2);
1518-
if (((remote_filename.length() > ProtoCommon.TRUNK_LOGIC_FILENAME_LENGTH) ||
1519-
((remote_filename.length() > ProtoCommon.NORMAL_LOGIC_FILENAME_LENGTH) && ((file_size & ProtoCommon.TRUNK_FILE_MARK_SIZE) == 0))) ||
1520-
((file_size & ProtoCommon.APPENDER_FILE_SIZE) != 0)) { //slave file or appender file
1617+
if (((file_size & ProtoCommon.APPENDER_FILE_SIZE) != 0))
1618+
{
1619+
file_type = FileInfo.FILE_TYPE_APPENDER;
1620+
}
1621+
else if ((remote_filename.length() > ProtoCommon.TRUNK_LOGIC_FILENAME_LENGTH) ||
1622+
((remote_filename.length() > ProtoCommon.NORMAL_LOGIC_FILENAME_LENGTH) &&
1623+
((file_size & ProtoCommon.TRUNK_FILE_MARK_SIZE) == 0)))
1624+
{
1625+
file_type = FileInfo.FILE_TYPE_SLAVE;
1626+
}
1627+
else {
1628+
file_type = FileInfo.FILE_TYPE_NORMAL;
1629+
}
1630+
1631+
if (file_type == FileInfo.FILE_TYPE_SLAVE ||
1632+
file_type == FileInfo.FILE_TYPE_APPENDER)
1633+
{ //slave file or appender file
15211634
FileInfo fi = this.query_file_info(group_name, remote_filename);
15221635
if (fi == null) {
15231636
return null;
15241637
}
1638+
1639+
fi.setFileType(file_type);
15251640
return fi;
15261641
}
15271642

1528-
FileInfo fileInfo = new FileInfo(file_size, 0, 0, ProtoCommon.getIpAddress(buff, 0));
1529-
fileInfo.setCreateTimestamp(ProtoCommon.buff2int(buff, 4));
1643+
int create_timestamp = ProtoCommon.buff2int(buff, 4);
15301644
if ((file_size >> 63) != 0) {
15311645
file_size &= 0xFFFFFFFFL; //low 32 bits is file size
1532-
fileInfo.setFileSize(file_size);
15331646
}
1534-
fileInfo.setCrc32(ProtoCommon.buff2int(buff, 4 * 4));
1647+
int crc32 = ProtoCommon.buff2int(buff, 4 * 4);
15351648

1536-
return fileInfo;
1649+
return new FileInfo(false, file_type, file_size, create_timestamp,
1650+
crc32, ProtoCommon.getIpAddress(buff, 0));
15371651
}
15381652

15391653
/**
@@ -1590,7 +1704,8 @@ public FileInfo query_file_info(String group_name, String remote_filename) throw
15901704
int create_timestamp = (int) ProtoCommon.buff2long(pkgInfo.body, ProtoCommon.FDFS_PROTO_PKG_LEN_SIZE);
15911705
int crc32 = (int) ProtoCommon.buff2long(pkgInfo.body, 2 * ProtoCommon.FDFS_PROTO_PKG_LEN_SIZE);
15921706
String source_ip_addr = (new String(pkgInfo.body, 3 * ProtoCommon.FDFS_PROTO_PKG_LEN_SIZE, ProtoCommon.FDFS_IPADDR_SIZE)).trim();
1593-
return new FileInfo(file_size, create_timestamp, crc32, source_ip_addr);
1707+
return new FileInfo(true, FileInfo.FILE_TYPE_NORMAL, file_size,
1708+
create_timestamp, crc32, source_ip_addr);
15941709
} catch (IOException ex) {
15951710
if (!bNewConnection) {
15961711
try {

src/main/java/org/csource/fastdfs/StorageClient1.java

+35-2
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,11 @@
1515

1616
/**
1717
* Storage client for 1 field file id: combined group name and filename
18+
* Note: the instance of this class is NOT thread safe !!!
19+
* if not necessary, do NOT set storage server instance
1820
*
1921
* @author Happy Fish / YuQing
20-
* @version Version 1.21
22+
* @version Version 1.27
2123
*/
2224
public class StorageClient1 extends StorageClient {
2325
public static final String SPLIT_GROUP_NAME_AND_FILENAME_SEPERATOR = "/";
@@ -30,7 +32,17 @@ public StorageClient1() {
3032
}
3133

3234
/**
33-
* constructor
35+
* constructor with trackerServer
36+
*
37+
* @param trackerServer the tracker server, can be null
38+
*/
39+
public StorageClient1(TrackerServer trackerServer) {
40+
super(trackerServer);
41+
}
42+
43+
/**
44+
* constructor with trackerServer and storageServer
45+
* NOTE: if not necessary, do NOT set storage server instance
3446
*
3547
* @param trackerServer the tracker server, can be null
3648
* @param storageServer the storage server, can be null
@@ -514,6 +526,27 @@ public int modify_file1(String appender_file_id,
514526
return this.modify_file(parts[0], parts[1], file_offset, modify_size, callback);
515527
}
516528

529+
/**
530+
* regenerate filename for appender file
531+
*
532+
* @param appender_file_id the appender file id
533+
* @return the regenerated file id, return null if fail
534+
*/
535+
public String regenerate_appender_filename1(String appender_file_id) throws IOException, MyException {
536+
String[] parts = new String[2];
537+
this.errno = this.split_file_id(appender_file_id, parts);
538+
if (this.errno != 0) {
539+
return null;
540+
}
541+
542+
String[] new_parts = this.regenerate_appender_filename(parts[0], parts[1]);
543+
if (new_parts != null) {
544+
return new_parts[0] + SPLIT_GROUP_NAME_AND_FILENAME_SEPERATOR + new_parts[1];
545+
} else {
546+
return null;
547+
}
548+
}
549+
517550
/**
518551
* delete file from storage server
519552
*

0 commit comments

Comments
 (0)