FILESTREAM data cannot be placed on an empty filegroup 解决办法

如果你也遇到了FILESTREAM data cannot be placed on an empty filegroup 这个错误。

你去google搜索,得到的第一条是应该在这里。答案是:

 

Your script are missing three things:

1) A USE statement for the database.

2) An ALTER DATABASE statement to add a file to the FILESTREAM file group. For instance:

ADD FILE (NAME = filestream_data,

          FILENAME = 'c:\Program Files\Microsoft SQL Server\MSSQL10.SQLEXPRESS\MSSQL\DATA\PreviewIntegration_data')


Beware that the file name should be on a single line.
             

3) A ROWGUIDCOL in the table:

guid uniqueidentifier NOT NULL UNIQUE ROWGUIDCOL,

 

意思是需要

1. Use [你的数据库名]

2. 修改数据库

   完整的应该是这样的(这里只涉及到了修改数据库的file和filegroup部分

复制代码
ExpandedBlockStart.gif 语法
 1  ALTER   DATABASE  database_name 
 2  {
 3       < add_or_modify_files >
 4     |   < add_or_modify_filegroups >
 5  }
 6  [ ; ]
 7 
 8  < add_or_modify_files > :: =
 9  {
10       ADD   FILE   < filespec >   [  ,...n  ]  
11           [  TO FILEGROUP { filegroup_name }  ]
12     |   ADD   LOG   FILE   < filespec >   [  ,...n  ]  
13     |  REMOVE  FILE  logical_file_name 
14     |  MODIFY  FILE   < filespec >
15  }
16 
17  < filespec > :: =  
18  (
19      NAME  =  logical_file_name  
20       [  , NEWNAME = new_logical_name  ]  
21       [  , FILENAME = {'os_file_name' | 'filestream_path' }  ]  
22       [  , SIZE = size [ KB | MB | GB | TB  ]  ] 
23       [  , MAXSIZE = { max_size [ KB | MB | GB | TB  ]   |  UNLIMITED } ] 
24       [  , FILEGROWTH = growth_increment [ KB | MB | GB | TB| %  ]  ] 
25       [  , OFFLINE  ]
26 
27 
28  < add_or_modify_filegroups > :: =
29  {
30       |   ADD  FILEGROUP  filegroup_name  
31           [  CONTAINS FILESTREAM  ]
32       |  REMOVE FILEGROUP  filegroup_name  
33       |  MODIFY FILEGROUP  filegroup_name
34          {  < filegroup_updatability_option >  
35           |   DEFAULT
36           |  NAME  =  new_filegroup_name 
37          }
38  }
39  < filegroup_updatability_option > :: =
40  {
41      { READONLY  |  READWRITE } 
42       |  { READ_ONLY  |  READ_WRITE }
43  }
44 
复制代码

 

 你看了这个语法,再看前面给出来的答案你就会明白那样子的添加文件并没有和库的FileStream有任何的关联。所以应该是这样的:

ALTER   DATABASE   [ 你的数据库 ]

add   FILE (name =  文件逻辑名,
FILENAME 
=  文件全名)  TO  FILEGROUP 你的FileStream名

 

也就是以上的例子需要在后面加上To FileGroup来指明文件添加到哪个FileStream下。

到这里基本的上主要的问题就都解决掉了。

剩下的按照最初的解决方一一对照修正就可以解决了。

欢迎加群互相学习,共同进步。QQ群:iOS: 58099570 | Android: 572064792 | Nodejs:329118122 做人要厚道,转载请注明出处!























本文转自张昺华-sky博客园博客,原文链接:http://www.cnblogs.com/sunshine-anycall/archive/2010/07/10/1774948.html ,如需转载请自行联系原作者

<think>我们正在处理一个关于"IllegalStateException: Cannot read while there is an open stream writer"的错误。根据引用[1]和[2],这个错误通常发生在尝试读取一个文件时,而该文件还有一个打开的流写入器(即写入流没有正确关闭)。引用[2]提供了一个例子:在写入文件后,如果没有关闭流,那么文件内容可能不会被写入(因为缓冲区的数据还没有被刷新到磁盘),并且如果此时尝试读取,就会导致错误。 解决方案的关键是确保在完成写入操作后,正确关闭流(或者至少刷新流),然后再进行读取操作。 步骤: 1. 在写入文件后,调用`close()`方法关闭流。关闭流会自动刷新缓冲区,确保数据写入文件。 2. 或者,在写入后显式调用`flush()`方法,将缓冲区数据强制写入文件,然后再进行读取操作(但之后仍需要关闭流以释放资源)。 引用[2]中的例子问题在于写入后没有关闭流,导致文件内容为空,并且如果此时读取,就会抛出类似引用[1]的异常。 因此,修复代码的步骤是: - 确保在写入操作后关闭流。 - 或者,如果需要在写入后立即读取,那么先关闭写入流,再打开读取流。 下面是一个修正后的示例(以C#为例,因为引用[2]是C#,但原理通用): 原问题代码(有问题的): FileStream fs = new FileStream("test.txt", FileMode.Create); byte[] data = Encoding.UTF8.GetBytes("Hello World"); fs.Write(data, 0, data.Length); // 这里没有关闭流,也没有刷新,所以文件可能还是空的 Console.ReadKey(); 修正后: using (FileStream fs = new FileStream("test.txt", FileMode.Create)) { byte[] data = Encoding.UTF8.GetBytes("Hello World"); fs.Write(data, 0, data.Length); // 使用using语句会自动关闭流(在离开using块时),并刷新缓冲区 } // 现在文件已经写入完成,可以安全读取 在Java中,同样可以使用try-with-resources语句来确保流被关闭。 另外,引用[3][4][5]提到了其他IllegalStateException的情况,但与本问题关联不大,不过它们都强调了在特定状态下不允许某些操作(如RecyclerView布局计算时、Web应用程序停止后、Elasticsearch配置错误等)。因此,处理IllegalStateException的关键是理解当前状态并确保操作符合条件。 对于用户当前的问题,我们主要关注文件读写时的状态:确保在读取之前,写入流已经关闭。 如果用户提供的是Java代码,我们可以给出Java的示例。 假设用户代码类似于: FileWriter writer = new FileWriter("test.txt"); writer.write("Hello World"); // 没有关闭writer // 然后尝试读取 修正后(使用try-with-resources): try (FileWriter writer = new FileWriter("test.txt")) { writer.write("Hello World"); } catch (IOException e) { e.printStackTrace(); } // 现在可以读取了 或者,手动关闭: FileWriter writer = null; try { writer = new FileWriter("test.txt"); writer.write("Hello World"); } catch (IOException e) { e.printStackTrace(); } finally { if (writer != null) { try { writer.close(); } catch (IOException e) { e.printStackTrace(); } } } 使用try-with-resources(Java 7及以上)是更简洁和安全的方式。 因此,总结:遇到“Cannot read while there is an open stream writer”错误,请检查并确保在读取之前已经关闭了写入流。 相关问题: 1. 为什么在写入文件后需要关闭流? 2. 除了关闭流,还有哪些方法可以确保数据被写入文件? 3. 在Java中,如何处理多个流的关闭以避免资源泄漏? 4. 如果写入过程中发生异常,如何保证流被正确关闭? 5. 如何避免在文件读写时出现IllegalStateException?</think>### 问题分析:`IllegalStateException: Cannot read while there is an open stream writer` 此错误发生在尝试**同时进行文件读写操作**时。根本原因是:**写入流(Writer)未正确关闭**,导致文件资源被占用锁定,此时尝试读取会触发异常。以下是详细解析和解决方案: --- ### 错误原因与机制 1. **流未关闭** 写入文件时,数据会先缓存在内存中,直到调用`.close()`或`.flush()`才会真正写入磁盘并释放资源(引用[2])。若未关闭写入流: - 缓冲区数据未刷新到磁盘 → 文件内容为空 - 文件被写入流锁定 → 无法读取(引用[1]) 2. **并发操作冲突** 类似错误也出现在其他场景(引用[3][5]): - RecyclerView 布局计算中禁止调用方法 - Web 应用停止后禁止加载资源 - **本质:资源状态冲突** --- ### 解决方案(Java示例) #### 方法1:显式关闭流(确保资源释放) ```java import java.io.*; public class FixStreamExample { public static void main(String[] args) { FileWriter writer = null; try { // 写入文件 writer = new FileWriter("test.txt"); writer.write("Hello World"); // 关键步骤:关闭写入流并释放资源 writer.close(); // 关闭后文件解锁 // 现在可以安全读取 FileReader reader = new FileReader("test.txt"); // ... 读取操作 } catch (IOException e) { e.printStackTrace(); } finally { // 双重保险:确保流关闭 if (writer != null) { try { writer.close(); } catch (IOException e) { e.printStackTrace(); } } } } } ``` #### 方法2:使用 **try-with-resources**(自动关闭流,推荐) ```java import java.io.*; public class FixStreamExample { public static void main(String[] args) { // try-with-resources 自动关闭流(Java 7+) try (FileWriter writer = new FileWriter("test.txt")) { writer.write("Hello World"); } catch (IOException e) { e.printStackTrace(); } // 此处 writer 自动关闭 // 安全读取 try (FileReader reader = new FileReader("test.txt")) { // ... 读取操作 } catch (IOException e) { e.printStackTrace(); } } } ``` #### 关键修复点 | 错误操作 | 正确操作 | 作用 | |-------------------|-----------------------------|-------------------------| | 写完后直接读取 | 先关闭写入流再读取 | 解除文件锁定 | | 忽略`.close()` | 使用 `try-with-resources` | 自动释放资源(防泄漏) | | 无异常处理 | 添加 `try-catch-finally` | 确保出错时仍关闭流 | --- ### 预防措施 1. **始终关闭流** 使用 `finally` 块或 `try-with-resources` 保证流关闭(引用[5])。 2. **避免读写重叠** 确保读操作开始时,所有关联的写入流已关闭。 3. **检查第三方库** 若使用框架(如 Elasticsearch),验证配置文件(如证书路径)是否正确(引用[4])。 --- ### 相关问题 1. **为什么显式调用 `.flush()` 后仍然无法读取?** `.flush()` 仅强制写入数据,但**不释放文件锁**,必须关闭流才能解锁(引用[2])。 2. **如何调试其他 `IllegalStateException` 场景(如 RecyclerView)?** 检查是否在**布局计算/滚动期间**调用了非法方法(引用[3]),通过 `post()` 延迟操作: ```java recyclerView.post(() -> { /* 安全操作 */ }); ``` 3. **Web 应用中出现类似错误如何解决?** 通常由 **Tomcat 热部署/JAR 冲突**引起(引用[5]): - 清理 `work` 和 `temp` 目录 - 检查依赖冲突(`ClassNotFoundException` 线索) 4. **文件读写最佳实践有哪些?** - 优先使用 `BufferedInputStream/BufferedOutputStream` - 用 `Files` 工具类替代原生流(Java NIO) - 避免在循环中重复打开/关闭流 5. **类似错误在分布式系统(如 Elasticsearch)中如何定位?** 检查: - 证书路径和密码是否正确(引用[4]) - 文件权限(`elastic-certificates.p12` 是否可读) - 集群节点间的 SSL/TLS 配置一致性
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值