删除个文件夹,vfs2上传文件到ftp就异常553,这么不经事吗
开心一刻
今天逛街碰到街头采访,一上来就问我敏感话题
主持人:小哥哥,你单身吗
我:是啊
主持人:你找女朋友的话,是想找一个小奶猫呢,还是小野猫呢
我沉思了一下,叹气道:如果可以的话,我想找个人,而且是女人

上传文件
基于 commons-vfs2
实现文件到 FTP
服务器的上传,pom.xml 如下
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.qsl</groupId>
<artifactId>ftp-demo</artifactId>
<version>1.0-SNAPSHOT</version>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.7.18</version>
</parent>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-vfs2</artifactId>
<version>2.7.0</version>
</dependency>
<dependency>
<groupId>commons-net</groupId>
<artifactId>commons-net</artifactId>
<version>3.9.0</version>
</dependency>
</dependencies>
</project>
application.yml
server:
port: 8080
app:
ftp:
host: ftp_ip
userName: ftp账号
password: ftp账号的密码
port: 21
protocol: ftp
baseDir: 账号基础目录
FtpConfig.java
/**
* FTP 配置
* @author 青石路
*/
@Configuration
@ConfigurationProperties(prefix = "app.ftp")
public class FtpConfig {
private String host;
private String userName;
private String password;
private Integer port;
private String protocol;
private String baseDir;
@Bean("fptUri")
public URI fptUri() throws URISyntaxException {
return new URI(protocol, userName+":"+password, host,
port, baseDir, null, null);
}
@Bean
public FileSystemOptions fileSystemOptions() {
FileSystemOptions opts = new FileSystemOptions();
FtpFileSystemConfigBuilder builder = FtpFileSystemConfigBuilder.getInstance();
builder.setControlEncoding(opts, "UTF-8");
builder.setConnectTimeout(opts, 5000);
builder.setUserDirIsRoot(opts, true);
builder.setPassiveMode(opts, true);
return opts;
}
public String getHost() {
return host;
}
public void setHost(String host) {
this.host = host;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public Integer getPort() {
return port;
}
public void setPort(Integer port) {
this.port = port;
}
public String getProtocol() {
return protocol;
}
public void setProtocol(String protocol) {
this.protocol = protocol;
}
public String getBaseDir() {
return baseDir;
}
public void setBaseDir(String baseDir) {
this.baseDir = baseDir;
}
}
FileUploadManager.java 完成上传
/**
* 文件上传 manager
* @author 青石路
*/
@Component
public class FileUploadManager {
private static final Logger LOGGER = LoggerFactory.getLogger(FileUploadManager.class);
private static final FileSystemManager systemManager;
@Autowired
@Qualifier("fptUri")
private URI fptUri;
@Autowired
private FileSystemOptions fileSystemOptions;
static {
try {
systemManager = VFS.getManager();
} catch (FileSystemException e) {
throw new RuntimeException(e);
}
}
public boolean uploadFileToSftp(File file, String fileName) {
try {
FileObject srcObject = systemManager.resolveFile(file.getParentFile(), file.getName());
FileObject destObjectDir = systemManager.resolveFile(fptUri.toString(), fileSystemOptions);
FileObject destObject = systemManager.resolveFile(destObjectDir, fileName);
destObject.copyFrom(srcObject, Selectors.SELECT_SELF);
return true;
} catch (FileSystemException e) {
LOGGER.error("文件:{} 上传SFTP失败,异常:", file.getAbsoluteFile(), e);
return false;
}
}
}
FileUploadController.java
/**
* 文件上传 controller
* @author 青石路
*/
@RestController
@RequestMapping("file")
public class FileUploadController {
private static final Logger LOGGER = LoggerFactory.getLogger(FileUploadController.class);
@Autowired
private FileUploadManager fileUploadManager;
@GetMapping("upload")
public boolean upload(@RequestParam("fileName") String fileName) {
long ramdomLong = ThreadLocalRandom.current().nextLong();
File file = new File(System.getProperty("java.io.tmpdir") + File.separator + ramdomLong + ".txt");
LOGGER.info("localFile:{}", file.getAbsoluteFile());
boolean uploadResult = false;
try {
Files.write(file.toPath(), String.valueOf(ramdomLong).getBytes(StandardCharsets.UTF_8));
uploadResult = fileUploadManager.uploadFileToSftp(file, fileName);
} catch (IOException e) {
throw new RuntimeException(e);
} finally {
try {
Files.deleteIfExists(file.toPath());
} catch (IOException e) {
throw new RuntimeException(e);
}
}
return uploadResult;
}
}
完整代码:ftp-demo
FTP 服务器目录最初情况如下

/idg
下没有任何目录和文件;启动后调用接口
即可完成文件的上传;fileName
参数表示上传到 FTP 服务器上的文件名

true
表示上传成功,FTP 服务器上即可看到 hello.txt

file
目录也被自动创建了,一切都是那么的顺利
上传失败:553
一个不小心把 FTP 服务器上 file
目录给删了,但内心一点都不慌,再上传一次呗,正好我也是这么干的;正当我以为会正常上传的时候,意外来了
org.apache.commons.vfs2.FileSystemException: Could not copy "file:///C:/Users/qsl/AppData/Local/Temp/6456333409667879871.txt" to "ftp://test:***@192.168.2.118/idg/file/hello.txt".
at org.apache.commons.vfs2.provider.AbstractFileObject.copyFrom(AbstractFileObject.java:303)
at com.qsl.manager.FileUploadManager.uploadFileToSftp(FileUploadManager.java:47)
at com.qsl.web.FileUploadController.upload(FileUploadController.java:39)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:205)
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:150)
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:117)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:895)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:808)
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1072)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:965)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006)
at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:898)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:529)
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:623)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:209)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:153)
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:51)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:178)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:153)
at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:178)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:153)
at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:178)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:153)
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:178)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:153)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:168)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:90)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:481)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:130)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:93)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:342)
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:390)
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:63)
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:928)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1794)
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:52)
at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1191)
at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Thread.java:745)
Caused by: org.apache.commons.vfs2.FileSystemException: Could not write to "ftp://test:***@192.168.2.118/idg/file/hello.txt".
at org.apache.commons.vfs2.provider.AbstractFileObject.getOutputStream(AbstractFileObject.java:1280)
at org.apache.commons.vfs2.provider.DefaultFileContent.buildOutputStream(DefaultFileContent.java:540)
at org.apache.commons.vfs2.provider.DefaultFileContent.getOutputStream(DefaultFileContent.java:406)
at org.apache.commons.vfs2.provider.DefaultFileContent.getOutputStream(DefaultFileContent.java:394)
at org.apache.commons.vfs2.provider.DefaultFileContent.write(DefaultFileContent.java:815)
at org.apache.commons.vfs2.provider.DefaultFileContent.write(DefaultFileContent.java:830)
at org.apache.commons.vfs2.util.FileObjectUtils.writeContent(FileObjectUtils.java:203)
at org.apache.commons.vfs2.provider.AbstractFileObject.copyFrom(AbstractFileObject.java:298)
... 52 common frames omitted
Caused by: org.apache.commons.vfs2.FileSystemException: Cant open output connection for file "ftp://test:***@192.168.2.118/idg/file/hello.txt". Reason: "553 Can't open that file: No such file or directory
".
at org.apache.commons.vfs2.FileSystemException.requireNonNull(FileSystemException.java:87)
at org.apache.commons.vfs2.provider.ftp.FtpFileObject.doGetOutputStream(FtpFileObject.java:519)
at org.apache.commons.vfs2.provider.AbstractFileObject.getOutputStream(AbstractFileObject.java:1276)
... 59 common frames omitted
553 Can't open that file: No such file or directory 是什么鬼?莫非是 file
目录不存在的原因?试着手动创建 file
目录,再调用接口上传文件,文件正常上传!
我们来分析下,最初的时候 file
目录是不存在的,但自动创建了,文件也正常上传了,然后我们手动删除 file
目录后,上传文件失败,手动补上 file
目录后,上传又正常了,这说明 file
目录被缓存了呀,对不对?最初的时候,缓存是空的,第一次上传的时候,vfs2
会判断 FTP 服务器上是否存在 file
目录,不存在则创建并进行缓存,那么下次上传的时候,在缓存中找到了 file
目录,那么就直接上传文件了,而不用去判断 FTP 服务器上是否有 file
目录(没有则创建);缓存的作用就很明显了,减少了一次目录是否存在的网络请求,进而提高效率;当然这只是我们的猜想,是否真的存在缓存,看源码肯定是最直观的,入口代码
FileObject destObjectDir = systemManager.resolveFile(fptUri.toString(), fileSystemOptions);
就不带你们详细去跟源码了,debug
跟源码,我相信你们也很容易找到 AbstractFileSystem#resolveFile(final FileName name, final boolean useCache)
private synchronized FileObject resolveFile(final FileName name, final boolean useCache)
throws FileSystemException {
if (!rootName.getRootURI().equals(name.getRootURI())) {
throw new FileSystemException("vfs.provider/mismatched-fs-for-name.error", name, rootName,
name.getRootURI());
}
// imario@apache.org ==> use getFileFromCache
FileObject file;
if (useCache) {
file = getFileFromCache(name);
} else {
file = null;
}
if (file == null) {
try {
file = createFile((AbstractFileName) name);
} catch (final Exception e) {
throw new FileSystemException("vfs.provider/resolve-file.error", name, e);
}
file = decorateFileObject(file);
// imario@apache.org ==> use putFileToCache
if (useCache) {
putFileToCache(file);
}
}
/**
* resync the file information if requested
*/
if (getFileSystemManager().getCacheStrategy().equals(CacheStrategy.ON_RESOLVE)) {
file.refresh();
}
return file;
}
如何修复
首先我们讨论下:要不要修?
手动误删目录,这种情况是非常少的,就拿我们的生产来讲,2020 到现在,从未出现过该问题,如果因为这种极小概率的事件去放弃缓存带来的性能提升,得不偿失,所以我是不推荐修改的,而实际上经过讨论后也决定不去修改;不过话说回来,如果上传压力很小,网络又非常稳定、快速,也就说缓存带来的性能提升可以忽略,那这个时候高可用的优先级就更高了,此时就可以考虑修了,那怎么修了,我这里提供两种方案
禁用缓存
既然
vfs2
有缓存(默认是启用的),应该有开关来禁用它,我就不给你们打哑谜了,直接修改FileSystemManager
,换成其子类StandardFileSystemManager
private static final StandardFileSystemManager systemManager; static {
try {
systemManager = new StandardFileSystemManager();
// 禁用缓存
systemManager.setFilesCache(new NullFilesCache());
systemManager.init();
} catch (FileSystemException e) {
throw new RuntimeException(e);
}
}
你们也许会问,我是怎么知道可以这么调整的,你们跟一下
VFS.getManager()
就知道了,最终会看到// managerClassName: org.apache.commons.vfs2.impl.StandardFileSystemManager
private static FileSystemManager createFileSystemManager(final String managerClassName) throws FileSystemException {
try {
// Create instance
final Class<?> mgrClass = Class.forName(managerClassName);
final FileSystemManager mgr = (FileSystemManager) mgrClass.newInstance(); try {
// Initialize
final Method initMethod = mgrClass.getMethod("init", (Class[]) null);
initMethod.invoke(mgr, (Object[]) null);
} catch (final NoSuchMethodException ignored) {
/* Ignore; don't initialize. */
} return mgr;
} catch (final InvocationTargetException e) {
throw new FileSystemException("vfs/create-manager.error", managerClassName, e.getTargetException());
} catch (final Exception e) {
throw new FileSystemException("vfs/create-manager.error", managerClassName, e);
}
}
通过反射调用了
StandardFileSystemManager
的构造方法和init
方法,与我们的systemManager = new StandardFileSystemManager();
systemManager.init();
是不是有异曲同工之妙?(你们猜的没错,我们的实现正是抄自于
vfs2
)异常弥补
不禁用缓存,还是保留默认的开启,只是当异常的时候,捕获它,然后去创建目录,然后再上传一次
public boolean uploadFileToSftp(File file, String fileName, boolean isRetry) {
String destDir = fptUri.toString();
try {
FileObject srcObject = systemManager.resolveFile(file.getParentFile(), file.getName());
FileObject destObjectDir = systemManager.resolveFile(destDir, fileSystemOptions);
FileObject destObject = systemManager.resolveFile(destObjectDir, fileName);
destObject.copyFrom(srcObject, Selectors.SELECT_SELF);
return true;
} catch (FileSystemException e) {
if (isRetry) {
try {
LOGGER.info("创建目录{}开始", destDir);
FileObject destObjectDir = systemManager.resolveFile(destDir, fileSystemOptions);
destObjectDir.createFolder();
LOGGER.info("创建目录{}开始", destDir);
} catch (FileSystemException ex) {
LOGGER.error("创建目录失败,异常:", ex);
}
return uploadFileToSftp(file, fileName, false);
}
LOGGER.error("文件:{} 上传SFTP失败,异常:", file.getAbsoluteFile(), e);
return false;
}
}
既保留了缓存,也解决了目录误删的问题,就问你们服不服?
总结
vfs2
是有缓存的,如果不小心把 FTP 目录删除了,上传会失败并提示
553 Can't open that file: No such file or directory
可以通过手动补目录的方式就行处理,当然也可以通过重启服务来解决,但这两种都不是通过代码来解决的,可用性很低;通过代码的方式来解决,有两种方法
禁用
vfs2
缓存,但会降低性能,可用但不推荐异常弥补,既保留了缓存,也解决了目录误删的问题,可以用也推荐
异常捕获后用来做流程控制,条件控制,不太规范
删除个文件夹,vfs2上传文件到ftp就异常553,这么不经事吗的更多相关文章
- 上传文件夹或上传文件到linux
http://jingyan.baidu.com/article/d169e18658995a436611d8ee.html https://www.cnblogs.com/nbf-156cwl/p/ ...
- JavaScript开发——文件夹的上传和下载
我们平时经常做的是上传文件,上传文件夹与上传文件类似,但也有一些不同之处,这次做了上传文件夹就记录下以备后用. 首先我们需要了解的是上传文件三要素: 1.表单提交方式:post (get方式提交有大小 ...
- JS开发——文件夹的上传和下载
文件夹上传:从前端到后端 文件上传是 Web 开发肯定会碰到的问题,而文件夹上传则更加难缠.网上关于文件夹上传的资料多集中在前端,缺少对于后端的关注,然后讲某个后端框架文件上传的文章又不会涉及文件夹. ...
- Java web开发——文件夹的上传和下载
我们平时经常做的是上传文件,上传文件夹与上传文件类似,但也有一些不同之处,这次做了上传文件夹就记录下以备后用. 这次项目的需求: 支持大文件的上传和续传,要求续传支持所有浏览器,包括ie6,ie7,i ...
- 需求-java web 能够实现整个文件夹的上传下载吗?
我们平时经常做的是上传文件,上传文件夹与上传文件类似,但也有一些不同之处,这次做了上传文件夹就记录下以备后用. 这次项目的需求: 支持大文件的上传和续传,要求续传支持所有浏览器,包括ie6,ie7,i ...
- Java实现FTP文件与文件夹的上传和下载
Java实现FTP文件与文件夹的上传和下载 FTP 是File Transfer Protocol(文件传输协议)的英文简称,而中文简称为"文传协议".用于Internet上的控制 ...
- c# ftp创建文件(非上传文件)
c# ftp创建文件(非上传文件) 一.奇葩的故事: 今天项目中遇到这么个奇葩的问题,ftp文件传输完成后要在ftp目录下另一个文件夹下创建对应的空文件,听说是为了文件的完整性,既然这么说,那么就必 ...
- java web 能够实现整个文件夹的上传下载吗?
在Web应用系统开发中,文件上传和下载功能是非常常用的功能,今天来讲一下JavaWeb中的文件上传和下载功能的实现. 对于文件上传,浏览器在上传的过程中是将文件以流的形式提交到服务器端的,如果直接使用 ...
- apache-commons-net Ftp 进行文件、文件夹的上传下载及日志的输出
用到了apache 的 commons-net-3.0.1.jar 和 log4j-1.2.15.jar 这连个jar包 JAVA 代码如下: package com.bjut.edu.cn.ftp; ...
- 利用Apache commons-net 包进行FTP文件和文件夹的上传与下载
首先声明:这段代码是我在网上胡乱找的,调试后可用. 需要提前导入jar包,我导入的是:commons-net-3.0.1,在网上可以下载到.以下为源码,其中文件夹的下载存在问题:FTPFile[] a ...
随机推荐
- 一行超长日志引发的 “血案” - Containerd 频繁 OOM 背后的真相
案发现场:混沌初现 2024年6月10日,本应是平静的一天.但从上午 9 点开始,Sealos 公有云的运维监控告警就开始不停地响.北京可用区服务器节点突然出现大量 "not ready&q ...
- C# .NET core Avalonia 11.0版本,发布linux和MAC的简单记录
.net core 7.0+centos 7.0 cetnos目前运行在hyper V虚拟机里 虚拟机部署的注意事项 1 需要配置网络环境, 确保在同一局域网下 如果sftp无法连接 ctrl+shi ...
- mysql子查询不支持limit问题解决
如果sql语句中的子查询包含limit 例如: select * from table where id in (select id from table limit 3) 会报错: This ver ...
- python基础-基本语句
1 条件语句 在进行逻辑判断时,我们需要用到条件语句,Python 提供了 if.elif.else 来进行逻辑判断.格式如下所示: 1 if 判断条件1: 2 执行语句1... 3 elif 判断条 ...
- 解决python命令行报错问题
解决Python报错Failed calling sys.__interactivehook__ 报错截图 可以看到主要的报错信息 File "D:\Python\Anaconda3\lib ...
- HBase 在统一内容平台业务的优化实践
作者:来自 vivo 互联网服务器团队-Leng Jianyu.Huang Haitao HBase是一款开源高可靠性.扩展性.高性能和灵活性的分布式非关系型数据库,本文围绕数据库选型以及使用HBas ...
- 深度学习pytorch常用操作以及流程
在微信公众号上看到这篇文章,担心以后想找的时候迷路,所以记录到了自己的博客上,侵扰致歉,随时联系可删除. 1.基本张量操作 1. 1 创建张量 介绍: torch.tensor() 是 PyTorch ...
- 在github开源市场如何高效寻找优秀开源项目
作为程序员,不论是开发还是学习,肯定会用到开源项目,那么怎么快速在开源网站找到这些项目呢? 常用的开源网站有:github 和 gitee github是全球最大的开源社区,今天就以github为例, ...
- RS232转PN协议网关模块连接PLC和霍尼韦尔条码扫描器通信
为了更快地输入信息,许多设备都配备了条码扫描器,但条码扫描器不能直接与CPU通信.最直接和方便的方法是加RS232转PN协议网关模块(BT-PNR20).本文将深入研究如何利用巴图自动化的RS232转 ...
- [oeasy]python0075_删除变量_del_delete_variable
删除变量 回忆上次内容 上次我们研究了字节序 字节序有两种 符号 英文名称 中文名称 < little-endian 小字节序 > big-endian 大字节序 字节序 用来 明确 ...