如何在文件的下一行写入内容?并在文件中查找字符串并将其替换在同一行
How can I Write contents in the nextline within a File? and Finding a String inside a File and Replacing it at the same exact line
我正在使用 SpringBoot 应用程序,并为显示的狗图片引入了一个 "Like" 按钮,每次点赞时它都会点击下面的 @RequestMapping(value="likedDog")
我正在用分隔符连接必要的信息。
控制器内部的方法如下所示:
@RequestMapping(value = "likedDog")
public String likedDogList(@RequestParam("breedType") String breedType, @RequestParam("id") String id, Model model){
Long likes=0L;
String delimiter="_!_";
Dogs dogObject= dogsService.returnDogById(Long.valueOf(id));
if(dogObject.getLikes()==null){
likes=0L;
}
else{
likes=dogObject.getLikes();
}
likes=likes+1;//1,2
dogObject.setLikes(likes);//set 1,2
dogObject=dogsService.saveDog(dogObject);
model.addAttribute("dogObj",dogObject);
model.addAttribute("dogBreedType",breedType);
String content=id+delimiter+breedType+delimiter+dogObject.getImgURL()+delimiter+dogObject.getLikes();
String contentSub=id+delimiter+breedType+delimiter+dogObject.getImgURL();
try{
File file = new File("src/main/resources/data/DogLikes.txt");
if (!file.exists()) {
file.createNewFile();
}
FileWriter fw = new FileWriter(file.getAbsoluteFile());
BufferedWriter bw = new BufferedWriter(fw);
bw.write(content);
bw.newLine();
bw.flush(); // ORIGINAL
bw.close();
}
catch(Exception e){
System.out.println("Exception occured in likedDogList()");
e.printStackTrace();
}
return "liked";
}
如果喜欢属于不同的狗,我想在各自文件的换行符上写连接字符串"content",代码如下所示,即使我引入bw.newLine
我也不会写在换行符中,它只是替换文件第一行中的旧现有内容。
文件DogLikes.txt中的内容如下所示:
17_!_Pug_!_http://i.imgur.com/E5vBM5Z.png_!_1 //but on every click the contents are being replaced in this first line only
预期输出,每个Like要写入DogLikes.txt的内容如下所示:
17_!_Pug_!_http://i.imgur.com/E5vBM5Z.png_!_1
18_!_Pug_!_http://i.imgur.com/E5vBM5Z.png_!_1 //should be written like this in newline on like of dogId 18
19_!_Pug_!_http://i.imgur.com/E5vBM5Z.png_!_1 //should be written like this in newline on like of dogId 19
第二个问题:
此外,如果我在 DogId 18 上单击 "Like",它应该按如下方式替换第二行,
17_!_Pug_!_http://i.imgur.com/E5vBM5Z.png_!_1
18_!_Pug_!_http://i.imgur.com/E5vBM5Z.png_!_2 //replacement of String in this exact location is expected
19_!_Pug_!_http://i.imgur.com/E5vBM5Z.png_!_1
非常感谢您在此方面的帮助,在此先致谢。
嘿@daniel 备份方法用于将内容逐行写入文件,而我正在使用不同的恢复方法。然而,我想出了一个新想法,将喜欢和不喜欢的内容合并到同一行中,如下所示:
单击 "Like" 和 "Dislike" 时的预期输出
1_!_Labrador_!_http://i.imgur.com/eE29vX4.png_!_like_!_11_!_dislike_!_5
2_!_Labrador_!_http://i.imgur.com/xX2AeDR.png_!_like_!_3_!_dislike_!_5
3_!_Labrador_!_http://i.imgur.com/hBFRUuW.png_!_like_!_1_!_dislike_!_5
16_!_Pug_!_http://i.imgur.com/E5vBM5Z.png_!_like_!_119_!_dislike_!_5
我在 backup() 方法中有点需要你的帮助,因为我尝试了不同的组合来更新同一行中的喜欢和不喜欢,因为你的方法只动态更新喜欢。我也很期待根据喜欢程度从高到低对狗的图像进行排序。
预先感谢您的帮助。
正如您在问题中所述,您的要求是对文件系统中的特定文件使用内存存储和备份机制。我尝试了一个使用 spring mvc 和数据 rest 的简短原型。您可以在这里找到:https://github.com/dbubenheim/Whosebug-40820684
最有趣的部分是数据的备份和恢复过程,我有以下两个服务类:
@Service
public class DogBackupServiceImpl implements DogBackupService {
@Value("${dog.backup.file}")
private String dogLikesFile;
private static final String DELIMITER = "_!_";
@Override
public void backup(final Dog dog) throws IOException {
final Path dogLikesPath = Paths.get(this.dogLikesFile);
if (!Files.exists(dogLikesPath)) {
Files.createDirectories(dogLikesPath.getParent());
Files.createFile(dogLikesPath);
}
final File dogLikesFile = Paths.get(this.dogLikesFile).toFile();
final StringBuilder stringBuilder = new StringBuilder();
String currentLine;
String oldLine = null;
try (final Scanner scanner = new Scanner(dogLikesFile)) {
while (scanner.hasNextLine()) {
currentLine = scanner.nextLine().trim();
stringBuilder.append(currentLine);
if (currentLine != null && !currentLine.isEmpty()) {
stringBuilder.append("\n");
}
if (currentLine != null && currentLine.startsWith(Long.toString(dog.getId()))) {
oldLine = currentLine;
}
}
}
String content = stringBuilder.toString();
final boolean firstLike = (oldLine == null || oldLine.isEmpty());
final String updateLine = dog.getId() + DELIMITER + dog.getBreedType() + DELIMITER + dog.getImgUrl() + DELIMITER + dog.getLikes();
if (!firstLike) {
content = content.replace(oldLine, updateLine);
}
try (final BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter(dogLikesFile))) {
bufferedWriter.write(content);
if (firstLike) {
bufferedWriter.write(updateLine);
}
bufferedWriter.close();
}
}
}
和
@Service
public class DogRestoreServiceImpl extends ContextLoaderListener implements DogRestoreService {
@Value("${dog.backup.file}")
private String dogLikesFile;
private static final int FIELD_ID = 0;
private static final int FIELD_BREED_TYPE = 1;
private static final int FIELD_IMG_URL = 2;
private static final int FIELD_LIKES = 3;
private static final String DELIMITER = "_!_";
private final DogRepository dogRepository;
public DogRestoreServiceImpl(final DogRepository dogRepository) {
this.dogRepository = requireNonNull(dogRepository, "dogRepository must not be null!");
}
@Override
public void restore() throws IOException {
final Path path = Paths.get(this.dogLikesFile);
if (!Files.exists(path)) {
System.out.println("nothing to restore");
return;
}
final File dogLikesFile = path.toFile();
final Set<Dog> dogs = new HashSet<>();
String line;
try (final BufferedReader reader = new BufferedReader(new FileReader(dogLikesFile))) {
while ((line = reader.readLine()) != null) {
final String[] fields = line.split(DELIMITER);
final Dog dog = new Dog.DogBuilder(Long.parseLong(fields[FIELD_ID]))
.breedType(fields[FIELD_BREED_TYPE])
.imgUrl(fields[FIELD_IMG_URL])
.likes(Long.parseLong(fields[FIELD_LIKES]))
.build();
dogs.add(dog);
}
this.dogRepository.save(dogs);
}
}
@Override
public void contextInitialized(final ServletContextEvent event) {
try {
System.out.println("context initialized. restoring data...");
this.restore();
System.out.println("data restoring completed!");
} catch (final IOException ioException) {
ioException.printStackTrace();
}
}
}
想法是:备份过程在spring数据存储库每次保存一个实体时保存,以使备份文件保持最新。
恢复过程基本上是在 spring 上下文成功初始化时(应用程序启动时)触发的。所以你应该能够在内存和备份文件中拥有所有数据。
您可以通过以下基本操作通过 cURL 与服务交互:
# retrieve all dogs
curl -X GET "http://localhost:8080/dogs"
# post dog
curl -X POST -H "Content-Type: application/json" -d '{
"breedType": "Husky",
"imgUrl": "http://i.imgur.com/abc123.png",
"likes": 0
}' "http://localhost:8080/dogs"
# like dog
curl -X POST -H "Content-Type: application/json" -d '' http://localhost:8080/dogs/likeDog/<dogs-id>"
希望对您有所帮助!如果还有任何问题,请告诉我。
我正在使用 SpringBoot 应用程序,并为显示的狗图片引入了一个 "Like" 按钮,每次点赞时它都会点击下面的 @RequestMapping(value="likedDog")
我正在用分隔符连接必要的信息。
控制器内部的方法如下所示:
@RequestMapping(value = "likedDog")
public String likedDogList(@RequestParam("breedType") String breedType, @RequestParam("id") String id, Model model){
Long likes=0L;
String delimiter="_!_";
Dogs dogObject= dogsService.returnDogById(Long.valueOf(id));
if(dogObject.getLikes()==null){
likes=0L;
}
else{
likes=dogObject.getLikes();
}
likes=likes+1;//1,2
dogObject.setLikes(likes);//set 1,2
dogObject=dogsService.saveDog(dogObject);
model.addAttribute("dogObj",dogObject);
model.addAttribute("dogBreedType",breedType);
String content=id+delimiter+breedType+delimiter+dogObject.getImgURL()+delimiter+dogObject.getLikes();
String contentSub=id+delimiter+breedType+delimiter+dogObject.getImgURL();
try{
File file = new File("src/main/resources/data/DogLikes.txt");
if (!file.exists()) {
file.createNewFile();
}
FileWriter fw = new FileWriter(file.getAbsoluteFile());
BufferedWriter bw = new BufferedWriter(fw);
bw.write(content);
bw.newLine();
bw.flush(); // ORIGINAL
bw.close();
}
catch(Exception e){
System.out.println("Exception occured in likedDogList()");
e.printStackTrace();
}
return "liked";
}
如果喜欢属于不同的狗,我想在各自文件的换行符上写连接字符串"content",代码如下所示,即使我引入bw.newLine
我也不会写在换行符中,它只是替换文件第一行中的旧现有内容。
文件DogLikes.txt中的内容如下所示:
17_!_Pug_!_http://i.imgur.com/E5vBM5Z.png_!_1 //but on every click the contents are being replaced in this first line only
预期输出,每个Like要写入DogLikes.txt的内容如下所示:
17_!_Pug_!_http://i.imgur.com/E5vBM5Z.png_!_1
18_!_Pug_!_http://i.imgur.com/E5vBM5Z.png_!_1 //should be written like this in newline on like of dogId 18
19_!_Pug_!_http://i.imgur.com/E5vBM5Z.png_!_1 //should be written like this in newline on like of dogId 19
第二个问题: 此外,如果我在 DogId 18 上单击 "Like",它应该按如下方式替换第二行,
17_!_Pug_!_http://i.imgur.com/E5vBM5Z.png_!_1
18_!_Pug_!_http://i.imgur.com/E5vBM5Z.png_!_2 //replacement of String in this exact location is expected
19_!_Pug_!_http://i.imgur.com/E5vBM5Z.png_!_1
非常感谢您在此方面的帮助,在此先致谢。
嘿@daniel 备份方法用于将内容逐行写入文件,而我正在使用不同的恢复方法。然而,我想出了一个新想法,将喜欢和不喜欢的内容合并到同一行中,如下所示:
单击 "Like" 和 "Dislike" 时的预期输出
1_!_Labrador_!_http://i.imgur.com/eE29vX4.png_!_like_!_11_!_dislike_!_5
2_!_Labrador_!_http://i.imgur.com/xX2AeDR.png_!_like_!_3_!_dislike_!_5
3_!_Labrador_!_http://i.imgur.com/hBFRUuW.png_!_like_!_1_!_dislike_!_5
16_!_Pug_!_http://i.imgur.com/E5vBM5Z.png_!_like_!_119_!_dislike_!_5
我在 backup() 方法中有点需要你的帮助,因为我尝试了不同的组合来更新同一行中的喜欢和不喜欢,因为你的方法只动态更新喜欢。我也很期待根据喜欢程度从高到低对狗的图像进行排序。 预先感谢您的帮助。
正如您在问题中所述,您的要求是对文件系统中的特定文件使用内存存储和备份机制。我尝试了一个使用 spring mvc 和数据 rest 的简短原型。您可以在这里找到:https://github.com/dbubenheim/Whosebug-40820684
最有趣的部分是数据的备份和恢复过程,我有以下两个服务类:
@Service
public class DogBackupServiceImpl implements DogBackupService {
@Value("${dog.backup.file}")
private String dogLikesFile;
private static final String DELIMITER = "_!_";
@Override
public void backup(final Dog dog) throws IOException {
final Path dogLikesPath = Paths.get(this.dogLikesFile);
if (!Files.exists(dogLikesPath)) {
Files.createDirectories(dogLikesPath.getParent());
Files.createFile(dogLikesPath);
}
final File dogLikesFile = Paths.get(this.dogLikesFile).toFile();
final StringBuilder stringBuilder = new StringBuilder();
String currentLine;
String oldLine = null;
try (final Scanner scanner = new Scanner(dogLikesFile)) {
while (scanner.hasNextLine()) {
currentLine = scanner.nextLine().trim();
stringBuilder.append(currentLine);
if (currentLine != null && !currentLine.isEmpty()) {
stringBuilder.append("\n");
}
if (currentLine != null && currentLine.startsWith(Long.toString(dog.getId()))) {
oldLine = currentLine;
}
}
}
String content = stringBuilder.toString();
final boolean firstLike = (oldLine == null || oldLine.isEmpty());
final String updateLine = dog.getId() + DELIMITER + dog.getBreedType() + DELIMITER + dog.getImgUrl() + DELIMITER + dog.getLikes();
if (!firstLike) {
content = content.replace(oldLine, updateLine);
}
try (final BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter(dogLikesFile))) {
bufferedWriter.write(content);
if (firstLike) {
bufferedWriter.write(updateLine);
}
bufferedWriter.close();
}
}
}
和
@Service
public class DogRestoreServiceImpl extends ContextLoaderListener implements DogRestoreService {
@Value("${dog.backup.file}")
private String dogLikesFile;
private static final int FIELD_ID = 0;
private static final int FIELD_BREED_TYPE = 1;
private static final int FIELD_IMG_URL = 2;
private static final int FIELD_LIKES = 3;
private static final String DELIMITER = "_!_";
private final DogRepository dogRepository;
public DogRestoreServiceImpl(final DogRepository dogRepository) {
this.dogRepository = requireNonNull(dogRepository, "dogRepository must not be null!");
}
@Override
public void restore() throws IOException {
final Path path = Paths.get(this.dogLikesFile);
if (!Files.exists(path)) {
System.out.println("nothing to restore");
return;
}
final File dogLikesFile = path.toFile();
final Set<Dog> dogs = new HashSet<>();
String line;
try (final BufferedReader reader = new BufferedReader(new FileReader(dogLikesFile))) {
while ((line = reader.readLine()) != null) {
final String[] fields = line.split(DELIMITER);
final Dog dog = new Dog.DogBuilder(Long.parseLong(fields[FIELD_ID]))
.breedType(fields[FIELD_BREED_TYPE])
.imgUrl(fields[FIELD_IMG_URL])
.likes(Long.parseLong(fields[FIELD_LIKES]))
.build();
dogs.add(dog);
}
this.dogRepository.save(dogs);
}
}
@Override
public void contextInitialized(final ServletContextEvent event) {
try {
System.out.println("context initialized. restoring data...");
this.restore();
System.out.println("data restoring completed!");
} catch (final IOException ioException) {
ioException.printStackTrace();
}
}
}
想法是:备份过程在spring数据存储库每次保存一个实体时保存,以使备份文件保持最新。 恢复过程基本上是在 spring 上下文成功初始化时(应用程序启动时)触发的。所以你应该能够在内存和备份文件中拥有所有数据。
您可以通过以下基本操作通过 cURL 与服务交互:
# retrieve all dogs
curl -X GET "http://localhost:8080/dogs"
# post dog
curl -X POST -H "Content-Type: application/json" -d '{
"breedType": "Husky",
"imgUrl": "http://i.imgur.com/abc123.png",
"likes": 0
}' "http://localhost:8080/dogs"
# like dog
curl -X POST -H "Content-Type: application/json" -d '' http://localhost:8080/dogs/likeDog/<dogs-id>"
希望对您有所帮助!如果还有任何问题,请告诉我。